Это будет рассказ о технологиях предков.
Статья скорее всего не будет иметь большой практической пользы для большинства читателей. Я начал ее писать только потому, что этой информации просто нет в Интернете. Я в этом уверен совершенно, потому что когда потребовалось сделать программатор, я потратил пару недель на поиски, но в итоге разобрался сам. Просто хотел оставить след в Интернете. Но тут еще в комментариях к моей другой статье оказалось, что эта тема не совсем тухлая и небольшой интерес есть. В годы популярности GAL программаторы проходили сертификацию у производителя микросхем. Вероятно чтобы конечный пользователь не разочаровался в новой технологии. Примерно так объясняется закрытость этой информации.
Итак, микросхемы GAL. Здесь, на Хабре, уже были статьи про них. например эта. Хорошая статья, но как и все подобные, вопрос программирования микросхемы ограничен фразой “потребуется специальный программатор “. Эта статья именно про программирование. Но сначала все-таки немного про сами микросхемы.
Наверно лет 25 — 30 назад, когда GALы были популярны, покупка специального программатора имела смысл. Купить его можно и сейчас, на всяких маркетах достаточно предложений. Однако сами микросхемы продаются от 400 рублей за десяток, а программатор стоит от тысячи за конструктор до нескольких тысяч за готовый. Покупать такой, чтобы прошить одну-две микросхемы и забыть — совершенно нецелесообразно. Поэтому было принято решение сделать свой. Вот тут и оказалось, что это не так просто. Официальные даташиты на микросхемы не содержат описаний процесса прошивки. Я нашел только одну достойную статью про это. Но информации в ней недостаточно для самостоятельной сборки программатора. Есть еще два проекта самодельных программаторов. Один на Ардуино и второй более древний GALBlast, который просто подключается и управляется через LPT-порт. Там целое семейство вариантов. Нет смысла глубоко изучать.
Ардуиновский совершенно явно написан по мотивам GALBlast. Код во всем его повторяет. Собственно изучение этого кода и позволило мне разобраться в этом вопросе.
Дальше все будет описано в отношении GAL16V8B. Другие GALки отличаются количеством ног и немного другой разводкой сигналов программирования по ним, но суть прожига одинаковая. Кроме того, есть еще древние одноразовые PAL и современные ATF. Функционально они не полностью аналогичные, но для программатора это не имеет значение.
Структурно для программатора микросхема GAL представляет собой матрицу фьюзов (плавких перемычек). В GAL16V8 это матрица 64 строки на 64 бита (фьюза). Кроме строки 60, где длина 82 бита.
Пара слов про сами фьюзы. Название сложилось исторически от самых первых логических матриц (PAL), в которых это были реальные металлические перемычки, пережигаемые (расплавляемые) высоким напряжением. Точно как предохранитель в радиоаппаратуре. По сути это просто разрывало связь между “ножками” логических элементов внутри микросхемы так что в итоге оставалось только те, что требуются для реализации задуманной логики.
PAL были одноразовыми, поэтому им на смену пришли GAL, в которых ничего не плавилось. Фьюзы стали многоразовыми, но терминология уже закрепилась. Ресурс фьюзов в GAL невелик — гарантируется только 100 циклов восстановления. Сейчас им на смену пришли ATF. У них количество циклов может сильно отличаться в бОльшую сторону, но для ATF16V8 это те же 100 циклов.
У каждого фьюза есть свой номер или линейный адрес, если все фьюзы расположить в одну линию. Для GAL16V8 это диапазон от 0 до 2194.
Не все строки реально присутствуют в “адресном пространстве”. Часть строк зарезервирована, т.е. физически не существует. А те, что есть, распределены следующим образом:
32 - UES - строка для произвольной информации от пользователя.58 - PES - строка с информацией о микросхеме.54 - CLEARALL - стирание, т.е. восстановление фьюзов60 - CFG - строка конфигурации, здесь описываются вспомогательные соединения между выводами матрицы.61 - SECURITY - бит защиты информации от обратного прочтения.63 - CLEAR - тоже стирание.
Матрица логических элементов представляет собой поле элементов И. Каждый элемент И в матрице имеет 32 входа. Вообще входных линий для элемента 16, но каждая имеет вариант входа через инвертор. Выход каждого элемента подключен к одному из входов большого макроэлемента, в котором есть прежде всего 8ИЛИ на входе и еще всякое по мелочи:

D-триггер может логически исчезать, если в строке конфигурации прошить соответствующий режим работы.
Всего таких макроэлементов 8 штук по числу пинов, которые могут быть выходами.
Таким образом, получается, что микросхема может реализовать произвольную функцию И от сигналов на входных пинах, а потом сделать функцию ИЛИ с результатом работы матрицы И. Сигнал с выхода макроячейки не только идет к выходу из корпуса, но также возвращается обратно в матрицу для использования в более сложных логических функциях.
Можно упрощенно сказать, что в исходном состоянии (до прошивки) каждый элемент в матрице соединен со всеми входами и выходами прямо и через инверторы, а потом со всеми выходами через ИЛИ. Прошивка обрывает ненужные соединения и в итоге матрица и выходные макроячейки вместе приобретают вид необходимой логической схемы. Кроме того, часть фьюзов в строке 60 может включать или выключать D-триггер или инвертор (XOR), которые видно на картинке и некоторые другие соединения.
Но вообще, эта теория не особо важна, потому что это знание никак не помогает создавать прошивку. Просто для информации.
В чем разница строк 63 и 54, я так и не понял. Обе стирают все.
Для строк 64, 61 и 63 данные не требуются. Важен сам факт записи в эти строки.
Теперь о главном. Как программируется микросхема. Здесь описан полный алгоритм для сертифицированного программатора. На практике для личного применения можно многое пропустить.
Сама прошивка создается в специализированных программах, которые “знают” описанную выше структуру GAL (ATF) и умеют применять это знание к разным видам микросхем. Проще всего использовать web-редактор прошивки — нормально работает и не требует установки. Есть еще десктопные, например, WinCUPL, но мне они как-то не понравились.
Вот пример реальной прошивки GAL16V8 для galasm-web из моего самодельного XT:
GAL16V8UMB_DECODERNC A19 A18 A17 A16 A15 A14 A13 RW GNDNC NC NC NC NC NC VE WP NC VCCWP = A19 & A18 & /A17 & /A16 & /A15 & RW # A19 & A18 & /A17 & /A16 & A15 & /A14 & /A13 & RW # A19 & A18 & A17 & A16 & RW; VE = A19 & /A18 & A17;DESCRIPTIONWrite protect for ROM areas only (C0000-CBFFF and F0000-FFFFF)UMB area CC000-EFFFF is unprotected (WP=0)VE = 1 if video VGA select
Сначала идет понятный заголовок, потом описание ножек микросхемы с 1 по 10 и с 11 по 20, потом сама логика. Синтаксис тут достаточно очевидный, как мне кажется. Символ # — это функция ИЛИ. Символ / — функция НЕ. Обратите внимание на “;” после строк с логикой. В других строках этого нет.
Потом еще необязательный блок описания.
Этот исходник компилируется в такую прошивку:
GAL-Assembler: GALasm 2.1Device: GAL16V8*F0*G0*QF2194*L0256 01110111101110111011111111110111*L0288 01110111101110110111101110110111*L0320 01110111011101111111111111110111*L0512 01111011011111111111111111111111*L2048 01100000*L2056 0101010101001101010000100101111101000100010001010100001101001111*L2120 00000000*L2128 1111111111111111111111111111111111111111111111111111111111111111*L2192 1*L2193 0*C1c00*5c61
Это текстовый файл, но имеет расширение jedec. Он передается программатору для прошивки.
Как программатор должен понимать этот файл:
-
Прочитать модель микросхемы (Device) и соответственно перекоммутировать панельку микросхемы по выбранный корпус. Для самоделки под одну микросхему это не важно. Там уже все скоммутировано.
-
*F0 (или *F1) — состояние фьюзов по умолчанию. Т.е. прожигать (0) или нет (1) те фьюзы, про которые не будет указания дальше.
-
*G0 — не активировать защиту от обратного чтения после прошивки, или активировать, если *G1.
-
*QF2194 — всего в микросхеме 2194 фьюза. Для самоделки не имеет значения.
-
*L — сама прошивка.
-
5c61 — контрольная сумма прошивки. Для самоделки не имеет значения.
Теперь сам процесс. Если у вас самоделка для личного использования под один тип микросхем, то можно сразу переходить к пункту 6.
-
Перевести микросхему в режим чтения прошивки. Для этого подать на вход EDIT (2) напряжение VPP 12 Вольт.
-
Сделать такую конфигурацию сигналов:
-
Вход режима переключить на чтение: ножка P/V(19) — 0.
-
Вход стробирования прожига /STB (11) установить в 1.
-
Вход тактирования (стробирования) данных SCLK (8) установить в 0;
-
-
На входах RA0 — RA5 (18, 3 — 7) установить двоичный адрес строки PES (58).
-
Подать короткий импульс 0 на вход STB, около 10 мс. Выбранная строка загрузится во внутренний буфер, на выходе данных SDOUT (12) появится первый бит строки 58 (самый левый). Этот бит надо прочитать и далее короткими импульсами SCLK (лог 1 около 2 мкс, но точность тут не важна) проталкивать строку на выход и забирать биты. Повторять 64 раза.
-
Разобрать строку PES. В ней зашифрован алгоритм прошивки, т.е. величина VPP для прожига и длительность прожигающего импульса /STB, количество предыдущих прожигов. Для некоторых моделей GAL могут быть указаны дополнительные параметры прошивки. Настроить программатор по этим данным. Формат данных в строке может отличаться у разных моделей. Можно посмотреть все там же.
-
Перевести микросхему в режим записи:
-
VPP = 14.5 В (для ATF 12 В),
-
Вход режима переключить на запись: ножка P/V(19) — 1
-
Вход тактирования (стробирования) данных SCLK (8) установить в 0;
-
-
Стереть микросхему: Установить адрес 63, P/V = 1, подать импульс прожига: /STB = 0 длительностью из настроек PES или просто на 40 мс, если у вас самоделка.
-
Записать матрицу. Т.е. последовательно выставлять адреса от 0 до 31 и через вход SDIN (9) загрузить буфер данных битами соответствующей строки, стробируя биты импульсами SCLK. После чего прожечь строку импульсом на /STB = 0.
-
Записать cтроку UES — *L2056, если есть в прошивке.
-
Записать строку CFG — здесь 82 бита в отличии от предыдущих, где 64.
-
Записать обратно строку PES, но счетчик циклов записи в ней увеличить на 1.
-
Если в прошивке был указан бит защиты, то записать строку 61.
-
Снять VPP.
-
Там есть еще вычисление контрольной суммы по ходу прошивки. Должно сойтись.
-
Для чтения любой строки из микросхемы достаточно повторить пункты 1,2,3,4 выставляя нужный адрес.
На практике для личных проектов можно не читать и не писать PES. VPP для GAL16V8B и аналогичных равно 14.5 Вольт как для записи, так и для чтения, а прожигающий импульс 40 мс. Для микросхем ATF VPP = 12 В. Заниматься битом защиты и контрольной суммой тоже нет смысла. Строка UES тоже не имеет значения.
Теперь самое важное. Прошивка фьюзов передается в файле формата jedec. Принципиальное значение для прошивки имеют только строки *L. Это строки формата “*LAAAA bbbbbb…”:
*L2048 00100000*L2056 0101010101001101010000100101111101000100010001010100001101001111*L2120 00000000
AAAA — линейный адрес первого фьюза в этой строке, т.е. адрес просто по порядку от нулевого до самого последнего. bbb… — произвольное количество битов, отражающих состояние фьюзов после прошивки.
Пример реальной строки: “*L0256 01110111101110111011111111110111”. Здесь первый фьюз имеет адрес 256, состояние 0, второй 257-1 и т.д.
Первые 32 строки основной матрицы самые хитрые. Эту часть матрицы можно представить в виде таблицы 32 строки на 64 столбца. Фьюзы по порядку номеров расположены не в строках, а в столбцах — именно этот факт стал основным поводом для статьи. Этой информации я просто нигде не встретил. Дошел до нее сам. Чтобы было понятнее, если посмотреть на верхний левый угол этой матрицы, то там будет такое расположение фьюзов:

Соответственно при парсинге файла jedec нужно сначала залить всю матрицу состояниями фьюзов по умолчанию (*F0), а потом брать фьюзы по их номеру из строк *L и располагать их состояние в нужной ячейке этой таблицы, получая в конечном итоге строки для заливки в микросхему.
Строка 32, если есть желание, прошивается по порядку начиная от фьюза 2048 и далее вправо (единственная нормальная из всех).
Фьюзы строки 60 имеют следующий порядок слева направо:
2193,2120,2121,2122,2123,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2188,2189,2190,2191,2124,2125,2126,2127,2192,2052,2053,2054,2055
Вот так бессистемно. В других GAL, не GAL16V8B, строка 60 будет иметь другую структуру и длину. Здесь есть подробности.
После того, как матрица в памяти программатора заполнена, можно брать строки из нее по порядку, выставлять адрес строки на входах микросхемы и заливать биты через пин входа начиная с самого левого.
Директива “*G0” или “*G1” выключает или включает защиту от чтения. Если включить, то все строки будут читаться как сплошные единицы. Думаю, что опция не актуальна, если вы не планируете какой-то эксклюзивный бизнес на этом, поэтому можно просто игнорировать эту строку. Снять защиту от чтения невозможно. Нужно стирать всю микросхему целиком и прошивать без защиты от чтения.
Все остальные строки в файле jedec носят служебный характер и на логику работы GAL после прошивки не влияют.
Реализация.
Совершенно очевидно, что реализовать описанное выше можно бесконечно большим количеством аппаратных вариантов. Я тут расскажу только про один, который показался оптимальным лично мне на тот момент, когда решил сделать.
Всего потребуется три готовых заводских модуля. Переходник USB-COM, микроконтроллер для процесса прошивки и повышающий преобразователь напряжения для получения VPP. Еще нужна удобная панелька для установки микросхемы и монтажная плата, чтобы собрать это все в единое целое. Для удобства я добавил еще простой цифровой вольтметр, чтобы настраивать величину VPP, но можно использовать любой обычный вольтметр с щупами.
В моем случае почти все у меня было в наличии, именно поэтому были выбраны конкретные модели модулей. А не потому что они лучше других подходят для задачи. Вот полный список с картинками с Алиэкспресса:
-
Микроконтроллер STC8G1K08

-
Повышающий преобразователь напряжения MT3608

-
Панелька для микросхемы

-
Вольтметр (не обязательно)

-
USB-COM (любой)

-
Макетная плата на свой вкус.
Преобразователь напряжения нужно слегка доработать, чтобы управлять напряжением. Для этого надо нагреть паяльником пин 1 самого чипа и приподнять его над контактной площадкой:

Это контакт управления EN. К нему надо припаять проводок и залить это все любым компаундом, чтобы не отвалилось.

Когда я уже все сделал, мне попалась схема, где этот модуль управлялся через средний контакт переменного резистора. Наверно такой вариант тоже допустим.
Схема всего устройства очень простая:

Подключение к COM-порту тут не нарисовано, оно происходит через стандартные контакты на платке микроконтроллера.

Две гребенки контактов здесь сделаны для отладки, когда я разбирался с тем , как оно работает. Можно не обращать внимания.
Код прошивки микроконтроллера лежит здесь. Его можно пересобрать под любую другую модель STC, реализующую 8-битный C51.
Для управления этим программатором написана еще программа для ПК (C#). Скачать можно здесь.

Здесь все просто.
-
Установить правильный COM-порт.
-
Включить VPP и настроить регулятором на MT3608 нужный уровень: 14.5 Вольт для GAL или 12 Вольт для ATF. Сверхточность тут не требуется.
-
Выключить VPP.

-
Теперь можно установить микросхему.
-
В программе открыть прошивку, нажать “Прошить”.
-
Дождаться завершения процесса.
Здесь же можно посмотреть карту фьюзов, как они будут прошиваться.

Вот в общем-то и все. В программе есть много разных кнопочек, которые появились в процессе изучения алгоритма. Можно поиграть с ними, но помнить, что ресурс прошивок в GAL очень мал.
ссылка на оригинал статьи https://habr.com/ru/articles/1039562/