Описан флэш-диск для компьютера Орион-128 объемом от 16 мегабайт. Диск очень прост, ибо построен на современной элементной базе: микроконтроллере Pic и последовательной (serial) flash памяти. В режиме чтения диск работает как стандартное параллельное ПЗУ, заменяя несколько ROM-дисков с возможностью переключения через графическое меню. Поддерживаются ROM-диски повышенного (>64кб) объема, совместимые с DsDos. Возможно дополнительное высокоскоростное подключение современной SPI периферии: карт памяти SD, RTC, ЦАП, радиомодулей, Ethernet-контроллеров и др). Также Ориону-128 доступен высокоскоростной (921600 бод) com-порт для связи с IBM PC через переходник usb-com.
Принципиальная схема флэш-диска Ориона-128 показана на рисунке ниже.
Микроконтроллер DD1 выполняет функцию интеллектуального преобразователя параллельного интерфейса Ориона в последовательный интерфейс микросхемы памяти DD2. Он принимает от Ориона-128 адрес с шин «B» и «С» порта F5 и выдаёт байт данных на шину «A» порта F5.
Линия С2 порта F4 подключается опционально ради поддержки больших дисков в DsDos. Для поддержки экстремально высоких скоростей чтения и записи можно дополнительно пробросить от Ориона на флэш-диск сигнал CS выбора ППА F5.
Для обнаружения сброса Ориона не требуется пробрасывать соответствующий сигнал от Ориона на флэш-диск. Вместо этого входные линии адреса «B» и «С» флэш-диска подтянуты к плюсу питания. При сбросе Ориона порты ввода-вывода переводятся в третье состояние и на шине адреса ROM-диска появляется код 0xffff, который распознаётся МК.
Взаимодействие МК c флэш-памятью DD2 идет по шине SPI (линии SDI, SDO, SCK). Сигналы CS1, CS2, CS3 используются для выбора абонента шины. CS1=0 при CS2=CS3=1 выбирает основную микросхему флэш-памяти DD2.
Для подключения SD-карты памяти предусмотрены отдельные линии шины SPI (SD_SDI, SD_SDO). Если установка SD-карты не планируется, то соответствующие выводы МК (RC0, RC1) могут использоваться произвольно.
На DA1 собран стабилизатор напряжения +3.3в, от которого питается МК и память; такое питающее напряжение более типично для современной периферии; ППА F5 Ориона-128 также нормально воспринимает такие уровни сигналов.
Для подключения флэш-диска к IBM-PC используется переходник usb-com с уровнями ТТЛ, собранный по типовой схеме на PL2303, CP2102, CH340G и прочее (у китайцев легко купить готовые модули). Обычно такие переходники как раз имеют выходные уровни +3.3в. Переходники с уровнями +5в не желательны; резистор R1 должен ограничить втекающий в МК ток.
Выводы МК MCLR, RB6, RB7 используются для первичного внутрисхемного программирования МК. Необходимо позаботиться о том, чтобы не спалить программатором порты Ориона (напряжение на MCLR достигает +9в). Также можно выбрать МК в корпусе dip40 и установить его на панельке. В дальнейшем обновлять прошивки МК можно по com-интерфейсу при штатном подключении к Ориону.
Микроконтроллер Pic18f47k42 можно заменить на Pic18f46k42 без изменений прошивки, если не требуется ультра-быстрый раздел ROM-диска. Также можно использовать МК Pic18f57k42 с большим число выводов для подключения дополнительной периферии.
В настоящее время в радиолюбительской практике последовательные шины заметно потеснили параллельные. Так, популярные микросхемы флэш-памяти w25q128 имеют значительный по меркам Ориона объём (16 мегабайт) и последовательный интерфейс SPI. Широко распространённые карты флэш памяти SD HC и SD XC также имеют последовательный интерфейс. В этом смысле при проектировании современного накопителя для Ориона-128 следует ориентироваться именно на последовательный интерфейс типа SPI. Именно он позволяет использовать наиболее современную периферию, причем не только память.
В принципе, последовательный интерфейс может быть реализован на Орионе-128 чисто программно. Однако реальная скорость работы при этом оказывается неприемлемо низкой. Практический смысл имеет построение некого преобразователя быстрого и родного для Ориона параллельного интерфейса в высокоскоростной последовательный интерфейс микросхем памяти. В идеале flash - диск должен имитировать хотя бы в режиме чтения стандартное параллельное ПЗУ, чтобы сохранить работоспособность существующего программного обеспечения и чтобы Орион-128 мог загружаться и работать с соответствующим ROM-диском.
Однако задача эмуляции параллельного ПЗУ на последовательной памяти является далеко не тривиальной. Это связано с тем, что истинные микросхемы ПЗУ обеспечивают высокую скорость произвольного доступа. Современная последовательная память обеспечивает высокую скорость лишь при последовательном чтении, при произвольном доступе скорость падает. Так, совершенно не пригодны для эмуляции ROM-диска современные SD HC и SD XC карты памяти, поскольку они имеют посекторную (по 512 байт) адресацию.
Имеются микросхемы памяти с побайтной адресацией, например, w25q128 объёмом 16 мегабайт. При этом для считывания байта по произвольному 24-битному адресу требуется посыл пяти байт через интерфейс SPI, что требует минимум 5*8=40 тактов шины SPI. На частоте SPI в 16 МГц это соответствует задержке в 2.5 мкс. Посмотрим, достаточно ли такого быстродействия для имитации ROM-диска.
Типичный код для Ориона по считыванию данных с ROM-диска состоит из пары инструкций: SHLD F501, LDA F500. Т.е. от выставления данных на шине адреса до считывания информации на шине данных проходит 12-13 тактов Ориона, или 4.8 мкс (на частоте Ориона в 2.5 МГц). Таким образом, даже на частоте SPI в 16МГц последовательная память фактически не успевает: в наихудшем случае случайного момента изменения адреса ей надо 2.5 мкс, чтобы завершить предыдущее чтение и ещё 2.5 мкс на новое чтение (и это без учета возможных накладных расходов).
Впрочем, на самом деле скорость чтения ROM-диска Орионом-128 достаточно низкая. Классический цикл чтения из ROM-диска в память Ориона имеет вид:
LL: | SHLD F501 | ; 16 тактов |
LDA F500 | ; 13 тактов | |
stax D | ; 7 тактов | |
inx H | ; 5 тактов | |
inx D | ; 5 тактов | |
dcr C | ; 5 тактов | |
jnz LL | ; 10 тактов |
Таким образом, между собственно операциями чтения ROM-диска проходит масса свободного времени. Поэтому возможен следующий подход к эмуляции ROM-диска: надо начинать последовательное чтение только после обнаружения факта изменения адреса на шине. Тогда выборка из памяти будет осуществлена за 2.5 мкс, т.е. с практически двукратным запасом по времени. Кроме того, можно заранее выдать в микросхему памяти команду чтения и старшую часть адреса. Тогда выборка может быть осуществлена за 1.5 мс.
Однако на данном пути имеется одна сложность: инструкция shld f501 выдает 16-битный адрес на шину не одномоментно, а раздельно младшую и старшую части. Если начать последовательно чтение памяти не дожидаясь полной выдачи адреса, то можно прочесть совсем не тот адрес. Тут можно предложить два подхода. Во-первых, при последовательном чтении изменение старшей части адреса происходит инкрементально - при переполнении младшей. Поэтому по изменению младшей части адреса с 255 на 0 можно предсказать инкремент старшей части. Такой подход не вносит дополнительных задержек и даже позволяет форсировать процесс чтения, однако при доступе по случайному адресу возможна ошибка.
Второй подход - после обнаружения изменения только младшей части адреса надо выждать минимум 3 такта Ориона. На самом деле это не влечёт увеличение задержки чтения, поскольку изменение младшей части адреса действительно начинается раньше. Однако при этом оказывается ограниченной минимальная тактовая частота Ориона, при которой будет работать ROM-диск. Кроме того, при разгоне Ориона выше 2.5 МГц внесенная задержка будет излишней. Тем не менее, при работе Ориона на частотах 2 - 5 МГц такой подход представляется оптимальным.
Для Ориона, работающего на частотах выше 5 МГц, эмуляция ROM-диска на последовательной памяти становится не целесообразной. На этот случай для эмуляции ROM-диска может быть использована встроенная flash-память микроконтроллера объёмом 64 Кб. Эта область образует первый "ультра-быстрый" ROM-диск, с которого Орион всегда может загрузиться. Для доступа к данным за пределами "ультра-быстрого" ROM-диска следует модифицировать стандартный цикл чтения ROM: необходимо максимально разнести во времени инструкций "SHLD F501" и "LDA F500". Уже перестановка инструкции "inx H", "dcr C" до "LDA F500" позволит Ориону-128 работать на тактовой частоте в 10 МГц (скорость чтения с ROM-диска при этом не уменьшается). Отметим, что код необходимо менять только при тактовой частоте Ориона выше 5 МГц и только при обращении к ROM за пределами первого "ультра-быстрого" 64-кб блока. Как альтернатива, флэш-память может быть прочитана напрямую без ограничений по скорости.
В одну микросхему памяти объемом 16 мбайт можно уместить множество ROM-дисков. Для их переключения необходимо удерживать кнопку сброса Ориона-128 дольше 2 сек. При этом флэш-диск переключается на специальный загрузочный ROM-диск, содержащий графическое меню выбора нужного ROM-диска из всех доступных. Этот выбор запоминается и в дальнейшем используется для загрузок Ориона при более коротких нажатиях на кнопку сброс.
Также управлять ROM-дисками можно из прикладных программ при помощи специальных команд.
В настоящее время ROM-диски объемом более 64 кбайта программно поддерживаются разве что DsDos. Соответственно предлагаемый флэш-диск Ориона эмулирует "ROM5" диск, собранный по этой схеме. В ней для выбора адресуемого 64-килобайтного банка диска используется линия С2 порта F4 Ориона, которая должна быть проброшена от Ориона на флэш-диск. Положительный фронт (0→1) на С2 приводит к запоминанию старшей части адреса в качестве номера текущего 64 килобайтного банка.
Если текущий эмулируемый ROM-диск это обычный (64 кб), то сигнал от линии С2 порта F4 игнорируется.
Флеш-диск Ориона также поддерживает переключение банков по 64 кб без использования линии С2 порта F4. Однако пока существующий софт не использует эту возможность. Более целесообразно использовать функцию чтения данных с флэш-диска по произвольному 24-битному адресу, ибо она оказывается быстрее, чем обычное чтение с ПЗУ.
Запись во флэш-память довольно длительная операция: сперва необходимо выполнить стирание страницы, затем программирование, при этом необходимо выдержать диктуемые микросхемой памяти временные рамки. О произвольном доступе на запись речь вообще не идет. Поэтому флэш-диск Ориона не имитирует параллельного интерфейса RAM диска - это было бы крайне затруднительно сделать на флэш-памяти (можно на SRAM-памяти вроде 23LC1024, но у неё маловат объём). Кроме того, мне не удалось найти софт по работе с RAM-дискам, на который следовало бы ориентироваться.
Поэтому флэш-диск для Ориона-128 просто предоставляет программе на Орионе интерфейс по прямому управлению микросхемами памяти, включая формирования сигналов "выбор кристалла" и высокоскоростную передачу данных между Орион-128 и интерфейсом SPI. Всю логику по записи данных в микросхемы памяти должна реализовывать программа на Орионе. Благо протокол записи в w25q128 совсем не сложен.
В настоящее время для Ориона-128 нет программ, которые бы умели вести запись на рассматриваемый флэш-диск. Возможно для начала такая поддержка будет реализована в специальном загрузочном ROM-диск, который стартует при длительном нажатии на кнопку сброс Ориона, хотя бы на уровне простейших функций по сохранению полного дампа памяти Ориона во флэш-памяти и обратному восстановлению.
Чтобы использовать функционал флэш-диска, отличный от эмуляции ROM-дисков, необходимо перевести его в специальный "командный" режим. Для этого надо неспешно (с минимальными задержками в 10 мкс) прочитать следующие адреса ROM-диска: 0xFFFF (эквивалентно сбросу), 0xFFA4, 0xFF48, 0xFFBC, 0xFF40, 0xFF14, 0xFF78, 0xFFAC. В результате флэш-диск ответит байтом 0x4E, уже не имеющим отношения к содержимому ROM-диску. Далее можно посылать диску команды. Например, команды 0xAC и 0xAD приводит к инкременту ответа флэш-диска, что является признаком наличия флэш-диска и его работе в командном режиме.
В командном режиме осуществляется двухсторонний обмен между флэш-диском и Орионом-128, причем переключение режима работы микросхемы к580вв55 порта ввода-вывода F5 не требуется. Вместо этого младшая часть адреса (F501) используется Орионом в качестве передаваемых во флэш-диск данных, старшая часть адреса (F502) используется для управления передачей, а F500 - для получения Орионом-128 данных от флэш-диска.
В командном режиме управляющий байт определяет, что должен делить флэш-диск. Действие инициируется Орионом путем изменения управляющего байта или его младшего бита. Флэш-диск при обнаружении нового управляющего байта производит действие, при необходимости принимая байт данных с линий F501 и возвращая в Орион байт данных, зависящий от команды. Поддерживаемые флэш-диском команды описаны в таблице, их состав может быть дополнен в будущем.
Код | Описание команды |
---|---|
Идентификация флэш-диска | |
0xAC | Проверка наличия флэш-диска. Текущий ответ флэш-диска инкрементируется. Если доступ к флэш-диску не требуется, то рекомендуется использовать именно этот код команды. |
0xAE | Проверка наличия проброса линии CS ППА порта F5, что позволяется использовать быстрые режимы чтения. Текущий ответ флэш-диска инкрементируется при любом обращении к ППА F5. |
Управление ROM-дисками | |
0xBС | Запрос начального адреса области памяти, в которой расположен текущий ROM-диск. Возвращается старший байт 24-битного адреса. Данная команда полезна для ускорения чтения данных ROM-диска. |
0xBA | Набор функций для управления текущим (активным) ROM-диска. Данная команда предназначена для реализации меню выбора активного загрузочного ROM-диска из нескольких возможных. Выполняемая подоперация зависит от байта данных (F501). Если подоперация = 0, то возвращает номер текущего активного ROM-диска (нумерация от 0, 0 означает специальный диск с меню выбора активного ROM-диска). Если подоперация = 1, то возвращает общее число доступных для выбора ROM-дисков. Если подоперация = 128+N, то в качестве активного выбирается диск N. |
0xB6 | Выбор банка в пределах ROM-диска повышенного объёма. Используется как альтернатива выбора банка через порт f402. Пoсле выполнения команды флэш-диск переходит из командного режима в режим эмуляции ROM-диска. |
0xFF | Выход из командного режима в режим эмуляции ROM-диска. |
0x00 | Нет операции. На случай смены режима ППА порта, которое сбросит управляющий байт в ноль. |
Прямое управление SPI периферией (в том числе для записи данных на флэш-диск) | |
0xD6 | Задание сигналов "выбор кристалла" для периферии флэш-диска. Байт данных используется для формирования сигнала выбора кристалла (0xFF - ничего не выбрано, 0xFE - выбор основной микросхемы flash-памяти W25Q128). Если старший бит сброшен, то SPI будет работать с отдельными линиями для SD-карты. |
0xD8 | Посыл байта через интерфейс SPI с приёмом результата. При обнаружении команды или инверсии её младшего бита происходит отправка данных на SPI. После окончания отправки принятый байт будет выдан в Орион-128. На частоте SPI 16 МГц передача байта происходит очень быстро, поэтому какое-либо ожидание на стороне Ориона не требуется. |
0xD0 | Быстрый посыл байта через интерфейс SPI с использованием проброса линии CS ППА порта F5. |
0xD2 | Быстрый приём байта через интерфейс SPI с использованием проброса линии CS ППА порта F5. |
Быстрый (до 921600 бод) Com-порт | |
0x60 | Включение com-порта для использования его Орионом-128. |
0x62 | Задание скорости com-порта, которая вычисляется как 16000000/(n+1). Также сбрасываются очереди отправки и приёма. |
0x64 | Запрос свободной длины буфера отправки данных com-порта. Возвращается значение - величина свободного места в очереди (0..255 байт) отправки. Длина свободной части буфера может расти по мере того, как данные отправляются com-портом. Для чтения актуального значения необходимо выполнить запрос повторно, инвертировав младший бит управляющего байта. |
0x66 | Отправка байта через com-порт. Байт помещается в очередь отправки ком-порта, если есть свободное место. Возвращается длина свободного места в очереди отправки. |
0x68 | Запрос длины очереди принятых данных от com-порта. Возвращается значение - число уже принятых байт (0..255 байт), которое может прочитать Орион-128. |
0x6a | Получение байта от com-порта. Байт извлекается из очереди приёма, если он там есть, доп. ожидание не требуется. В сочетании с предварительным запросом 0x68 длины очереди Ориону-128 удаётся читать данные на максимальной скорости. |
Доступ к ресурсам МК | |
0x20 | Установка младшего байта адреса чтения из флэш-памяти МК. |
0x21 | Установка второго байта адреса чтения из флэш-памяти МК. |
0x23 | Установка старшего байта адреса чтения из флэш-памяти МК. МК выдаёт в Орион-128 прочитанный байт. |
0x24 | Чтение байта данных по установленному ранее адресу флэш-памяти МК с инкрементом адреса. МК выдаёт в Орион-128 прочитанный байт, адрес чтения инкрементируется. Доступ к флэш-памяти МК может быть использован для отображения меню выбора ROM-дисков: туда программа на IBM-PC записывает параметры ROM-дисков, в том числе объёмы и текстовые названия для отображения в меню. |
Чтение данных с обычных ROM-дисков оказывается достаточно медленным: классический код чтения ПЗУ требует целых 46 тактов на байт (53 кб/с, без учета кода организации цикла).
Прямое управление флэш-диском может быть использовано для последовательного считывания Орионом-128 данных с флэш-памяти w25q128 на более высокой скорости, чем обеспечивает стандартный ROM-диск. Это возможно потому, что Ориону не требуется выдавать адрес чтения командой "SHDL" (16 тактов) и инкрементировать его через "INX H" (5 тактов). Инкремент адреса выполняется микросхемой памяти автоматически.
Для чтения необходимо выбрать кристалл w25q128 сигналом CS1=0 (код 0xfe), послать байт 3 (команда чтения), послать 24-битный адрес (начиная со старшего байта). Далее последовательно читаются данные начиная с установленного адреса с его инкрементом.
Для чтения массива данных в память Ориона может быть использован следующий код:
... | ; выбор кристалла w25q128, посыл команды чтения и адреса | |
lxi H, F502 | ; для быстрого доступа к регистру управления | |
LL2: | mvi M, D8 | ; команда отправить байт по spi и принять результат |
inx D | ; пока есть время, делаем инкремент | |
LDA F500 | ; читаем прочитанный с W25Q128 байт | |
stax D | ; и пишем в память ориона | |
mvi M, D9 | ; повторяем команду, инвертировав младший бит | |
inx D | ; пока есть время, делаем инкремент | |
LDA F500 | ; читаем прочитанный с W25Q128 байт | |
stax D | ; пишем в память ориона | |
dcr C | ||
jnz LL2 |
В данном примере в теле цикла читается два байта данных. Это позволяет использовать фиксированные (константные) значения управляющего слова, которые посылаются с использованием команды "mvi". В итоге чтение требует всего 35 тактов на 1 байт (скорость 70 кб/с).
Для ещё большего повышения скорости загрузки массива данных с флэш-диска в Орион-128 можно использовать параллельный интерфейс порта F5 не для выдачи 16-битного адреса чтения, а для приёма сразу 16-ти бит прочитанных данных. В этом случае после инициирования чтения с w25q128 микросхема ППА F5 переводится в режим ввода данных по линиям A и B (F500 и F501), на которые флэш-диск будет выдавать прочитанные байты парами.
Для пересылки пары байт в память может использоваться следующий вид:
mvi M, cmd_rd16 | ; даём команду чтения пары байт по SPI | |
inx D | ; пока есть время, делаем инкремент | |
LDA F500 | ; читаем первый прочитанный с W25Q128 байт | |
stax D | ; и пишем в память Ориона | |
inx D | ; на след. адрес | |
IN F5 | ; читаем с F501 второй прочитанный с W25Q128 байт | |
stax D | ; и пишем в память Ориона |
Данный код выполняется 57 тактов, или 28.5 тактов на байт (скорость 86 кб/с на 2.5 МГц).
Ещё более высокое быстродействие можно получить путем использования стековых инструкций:
... | ; выбор кристалла w25q128, посыл команды чтения и адреса | |
... | ; переключение ППА F5 на режим 16-битного ввода | |
lxi D, F502 | ; для быстрого доступа к регистру управления | |
mvi A, cmd_rd16 | ; команда чтения 16-бит данных | |
stax D | ; выдаём команду во флэш-диск | |
jmp LL4 | ||
LL4: | rol | ; быстрое переключение кода команды для следующего чтения |
LHLD F500 | ; читаем два байта данных в HL | |
stax D | ; и выдаём команду выдачи следующих | |
push H | ; пишем прочитанное данные в память ориона | |
ror | ; обратное переключение кода команды | |
LHLD F500 | ; читаем два байта данных в HL | |
stax D | ; и выдаём команду выдачи следующих данных | |
push H | ; пишем прочитанное в память ориона | |
dcr C | ||
jnz LL4 |
В данном примере за одну итерацию цикла пересылается сразу 4 байта, причем пересылка одного байта занимает всего 19 тактов (128 кб/с). Недостатком использования инструкции push является то, что запись в память Ориона идет в обратном порядке.
В принципе, можно было бы ориентировать флэш-диск на такое "обратное чтение", изначально записывая данные в микросхему памяти w25q128 в обратном порядке. Тогда в режиме ROM-диска микроконтроллеру следовало бы выполнять дополнительную инверсию входного адреса. В побайтном режиме быстрого чтения также следовало бы писать полученные данные в память Ориона в обратном порядке (с конца массива к началу, используя инструкцию "dcx D" вместо "inx D", что не снижает быстродействия). Впрочем, узаконивать такое усложение мы пока не рекомендуем из-за возможных проблем с программной совместимостью. Разве что некоторые данные, заведомо предназначенные для максимально скоростного чтения, могут быть записаны в инверсном порядке ради максимально быстрой загрузки.
Заметим, что достигнутые скорости чтения флэш-диска сравнимы со скоростью копирования данных память-память Ориона (24 такта на байт при обычном подходе и 17 тактов/байт при использовании стековых инструкций). Т.е. даже диск, подключаемый непосредственно к системной шине процессора Ориона, работал бы быстрее лишь на самую малость. Впрочем, оказывается нет смысла в создании диска как полноценного абонента системной шины.
Для дальнейшего увеличения быстродействия флэш-диска достаточно пробросить во флэш-диск сигнал CS выбора кристалла ППА порта F5. В этом случае отпадает необходимость посыла управляющего байта с Ориона во флэш-диск ради чтения/записи следующего байта. Вместо этого, обнаружив обращение Ориона к ППА F5, флэш-диск автоматически запрашивает следующий байт по SPI или начинает выдачу нового байта (в зависимости от управляющего байта). Заметим, что указанное действие происходит после окончания выборки ППА по переходу сигнала CS 0→1, так как в этом случае у флэш-диска есть запас времени минимум в 7 тактов Ориона на его выполнение.
Тело цикла чтения приобретает следующий вид:
mov a,m | ; читаем байт данных с флэш-диска (заранее HL:=F500) | |
stax D | ; и пишем в память Orion | |
inx D | ; на следующий байт |
Время выполнения тут составляет всего 19 тактов на байт (скорость 128 кб/с), что превышает скорость обычного копирования память-память.
Максимально быстрым оказывается режим чтения с использованием стековых инструкций:
mov D,m | ; читаем байт данных с флэш-диска (заранее HL:=F500) | |
mov E,m | ; читаем следующий байт | |
push D | ; и пишем в память Ориона пару байт |
Этот код требует всего 12.5 тактов на байт (скорость 200 кб/с), но к сожалению данные оказываются записанными в ОЗУ Ориона-128 в обратном порядке (хотя эта проблема вообщем решаема).
Заметим, что при пробросе линии CS режим 16-битного чтения, требующий смены режима ППА, оказывается менее выгодным.
В таблице ниже дана сводка всех режимов чтения с указанием максимально достижимой скорости чтения массива последовательно расположенных байт в память Ориона. Заметим, что ограничения на скорость чтения обусловлены не флэш-диском, а скоростью работы программы на Орионе-128. Данные скорости достигаются не только при чтении флэш-памяти w25q128, но также для любого SPI-абонента (SD-карты памяти, Ethernet-контроллера).
Режим чтения | Тактов на байт | Скорость чтения (на Орионе 2.5 МГц) |
---|---|---|
Обычное подключение флэш-диска к порту F5 (линия A - данные, линии B,C - адрес) | ||
1. Классическое чтение ROM-диска по произвольному 16-битному адресу (эмуляция обычного параллельного ПЗУ) | 46 | 53 кб/с |
2. Последовательное SPI-чтение | 35 | 70 кб/с |
3. Последовательное 16-битное SPI-чтение | 28.5 | 86 кб/с |
4. То же с использование стековых инструкций с записью в ОЗУ в обратном порядке | 19 | 128 кб/с |
Требуется дополнительный проброс на флэш-диск линии CS от ППА F5 | ||
5. Последовательное SPI-чтение с использованием линии CS ППА F5 | 19 | 128 кб/с |
6. То же с использование стековых инструкций с записью в ОЗУ в обратном порядке | 12.5 | 200 кб/с |
Для высокоскоростных режимов чтения и записи становятся заметными временные затраты на организацию цикла. Рассмотрим пути по сокращению этих затрат для достаточно большого количества пересылаемых байт. В простейшем случае цикл можно организовать следующим образом:
; На входе BC - кол-во байт для передачи | ||
; | ||
LLL: | пересылка данных | |
dcx B | ||
mov A,B | ||
ora C | ||
jnz LLL |
Однако такая организация цикла является не удачной: она требует лишних 24 такта на каждую итерацию. Это число можно уменьшить путем использования следующего кода:
; На входе BC - кол-во байт для передачи | ||
; | ||
mov A,C | ; коррекция ВС: если С ≠ 0, то B++ | |
ana A | ||
jz $+4 | ; пропускаем след. инструкцию | |
inr B | ||
; | ||
LLL: | пересылка данных | |
dcr C | ||
jnz LLL | ||
dcr B | ||
jnz LLL |
Вначале счетчик итераций BC специальным образом корректируется: если C≠0, то B=B+1. Это позволяет в дальнейшем организовывать цикл оптимальным образом c использованием одной инструкции dcr. Расходы на организацию цикла уменьшаются почти до 15 тактов.
Дальнейшее снижение накладных затрат на организацию цикла возможно за счет пересылки в теле цикла M байт за раз с соответствующим уменьшением числа итераций. При этом относительные затраты на организацию цикла уменьшаются пропорционально M. Особенно эффективен данный подход, если BC кратно M и известно. В противном случае требуется деление BC на M, для чего можно использовать подход, показанный в примере ниже:
; На входе BC - кол-во байт для передачи | ||
; | ||
xra A | ; делим BC на два (BC >>= 1) | |
mov A,B | ||
rar | ||
mov B,A | ||
mov A,C | ||
rar | ||
mov C,A | ||
jnc LL_Skip1 | ; пропустим, если BC был четным | |
пересылка данных | ; и выполним для нечетного ВС | |
LL_Skip1: | ||
xra A | ; делим BC на два (BC >>= 1) | |
mov A,B | ||
rar | ||
mov B,A | ||
mov A,C | ||
rar | ||
mov C,A | ||
jnc LL_Skip2 | ||
пересылка данных | ; и выполним дважды | |
пересылка данных | ||
LL_Skip2: | ||
mov A,C | ; проверка на ВС = 0 | |
ora B | ||
jz выход | ||
; | ||
mov A,C | ; коррекция ВС: если С ≠ 0, то B++ | |
ana A | ||
jz $+4 | ; пропускаем след. инструкцию | |
inr B | ||
; | ||
LLL: | пересылка данных | |
пересылка данных | ||
пересылка данных | ||
пересылка данных | ||
dcr C | ||
jnz LLL | ||
dcr B | ||
jnz LLL |
В данном случае в теле основного цикла идет переcылка сразу четырех байт (M=4, расходы уменьшились до ~4 тактов). До начала основного цикла BC делится на 4, при этом остаток от деления определяет количество дополнительно пересылаемых байт.
Более сложные организации цикла хороши только при достаточно больших значениях BC. Поэтому имеет смысл предварительно грубо проверять исходное значение BC и выбирать усложнённые варианты только при достаточно больших BC.
Для подключения флэш-диска к IBM-PC используется com-порт в сочетании с переходником usb-com. Com-порт микроконтроллера может работать на очень высоких скоростях: его скорость = 16000000/n, где n=1,2,...,256 - целочисленный делитель. В реальности скорость ограничивается тем, как указанная выше сетка частот сочетается с допустимыми скоростями у переходника usb-com. Скорость 115200*8=921600 бод вероятно поддерживается всеми переходниками. Но возможно выбор более высокой скорости окажется предпочтительнее (например, PL2303 поддерживает скорость 1228800 бод, которая реализуется МК с большей точностью).
Сom-порт используется для начальной заливки с IBM-PC данных ROM-дисков во флэш-память при помощи специальной программы. Также он может использоваться для считывания сохраненных Орионом во флэш-памяти данных в компьютер. Для этих операций флэш-диск реализует прямое управление периферией МК с компьютера через com-порт, а протоколы записи и чтения реализуются программой на IBM-PC. Этот режим может использоваться для предварительной апробации алгоритмов работы с периферией флэш-диска на IBM-PC, например, с использованием языков высокого уровня.
Также com-порт может использоваться для обновления прошивок микроконтроллера при дальнейшем совершенствовании флэш-диска и расширении его функционала.
Также через com-порт может быть реализована функция подключения реального флэш-диска к программному имитатору Ориона-128. Такая возможность позволяет облегчить разработку ПО для Ориона, но использовать при этом реальную аппаратную часть флэш-диска (полные программные модели даже w25q128 достаточно сложны, не говоря уж о SD-картах).
Наконец com-порт может использоваться для прямого взаимодействия Ориона с IBM-PC. При этом также могут использоваться очень высокие скорости обмена, благо имеется буферизация данных.
В минимальной аппаратной конфигурации флэш-диск Ориона состоит из МК и единственной микросхемы флэш-памяти w25q128. Её объема 16 мб вполне достаточно для эффективного доступа ко всему программному наследию Ориона-128. Тем не менее, аппаратная часть и функционал флэш-диска могут быть расширены.
К интерфейсу SPI может быть подключено несколько различных абонентов, которые различаются сигналами выбора кристалла CS1, CS2 и CS3. Т.е. помимо одной микросхемы флэш-памяти w25q128 (выбирается CS1=0) может быть подключено два дополнительных абонента. Количество абонентов может быть увеличено до 8 при использовании дополнительного дешифратора адреса 3→8 или при использовании варианта микроконтроллера с большим числом выводов (к сожалению МК на 64 вывода уже не существует в винтажном корпусе dip40). При отказе от подключения SD-карты для сигналов выбора кристалла могут быть дополнительно использованы выходы МК RC0, RC1.
Пока нет никакой программной поддержки дополнительных абонентов и соответственно нет никаких ограничений на то, что может быть подключено. Орион-128 может работать с абонентами по своему усмотрению в режиме прямого управления периферией.
Для реально используемого накопителя данных желательно иметь часы реального времени (RTC), чтобы отмечать время записи. Поэтому вторым абонентом может стать какая-либо микросхема часов реального времени с SPI интерфейсом. Например, DS3234 имеет интегрированный точный (TCXO) резонатор и паябельный корпус SO-20. К сожалению она довольно дорогая даже по сравнению с I2C аналогом DS3231, который также можно подключить. Ещё пример - микросхема RTC DS1390, но её корпус уж слишком миниатюрен.
Третим абонентом можно подключить ещё одну микрохему w25q128 - для увеличения объёма диска или чтобы использовать только её для записи, отдав первую под ROM-диски без права изменений. Либо можно подключить одну или две SRAM 23LC1024 или 48LM01 (объём 128 кб) для оперативного сохранения состояния ориона.
При желании к флэш-диску можно подключить SD HC или SD XC - карту памяти. Вообще говоря, такая карта не является нормальным SPI абонентом (может работать в SD-режиме при CS=1) и потенциально может заблокировать работу других. Поэтому для подстраховки SD-карта подключается к отдельным линиям SD_SDO, SD_SDI.
Также в качестве абонента можно подключить 16-битный стерео ЦАП, например, PT8211 или BU9480. К сожалению, невозможно одновременно читать аудиопоток с SD-карты по SPI и выдавать выборки на SPI ЦАП с равномерной частотой дискретизации. В принципе, читаемые с SD-карты аудиоданные можно было бы выводить на встроенный в МК ШИМ-контроллер, но он обеспечивает лишь 10-битное качество (при частоте ШИМ в 62.5 КГц). Также проблему можно было бы решить более мощным МК, однако всё равно про воспроизведении звука флэш-диск не может решать других задач, поэтому при нажатии на кнопку сброс Ориона воспроизведение звука будет прервано. Наверное в этом плане эффективнее отдельный звуковой плеер с управлением от Ориона.
К флэш-диску можно подключить Ethernet-контроллер, например, на базе W5500 с встроенной поддержкой TCP/IP (китайцы делают готовые модули, которые подключаются элементарно). Это простой и быстрый способ подключения Ориона-128 к интернету.
Следует отметить, что флэш-диск построен на микроконтроллере, и в принципе все ресурсы МК (таймеры, АЦП, аппаратное умножение и многое другое) доступны Ориону-128. К сожалению, почти все выводы МК в корпусе Dip40 уже заняты (особенно если планируется подключать SD-карту памяти).
Ничто не мешает подключать к флэш-диску I2C периферию, за исключением острого дефицита выводов МК в корпусе dip40. В принципе, в качестве линии SCL можно использовать сигнал CS1 (предполагается, что у современной быстрой I2C периферии SCL является только входом, поскольку ей не требуется снижать скорость обмена), а качестве линии SDA - линию SD_SDO. При этом перед доступом к SD-карте следует дизактивировать I2C - абонентов посылками STOP.
Статья неплохая, но без прошивки МК напоминает рекламу самого себя, любимого. Или это коммерческая тайна? Если нет, выложите пожалуйста прошивку на МК, чтобы другие смогли повторить проект.
Первые версии прошивки для МК и программы для IBM-PC наконец готовы. Пришло время испытать собранный макет флэш-диска. И вот сегодня Орион-128 успешно загружен с флэш-диска. Имитация параллельного ПЗУ на w25q128 работает. Ура!
Теперь бы надо написать поддержку флэш-диска в ПО для Ориона - только почему то желание пропало... Совсем... Найдутся ли энтузиасты?
См. также обсуждение флэш-диска для Ориона на форуме zx-pk.ru и вк.