Еще один простой программатор ПЛИС

В прошлой статье я писал, что такое JTAG и TAP контроллер. Эти знания нам помогут сделать свой простой программатор для ПЛИС компании Альтера.

Я хочу сделать очень простой программатор, который будет работать через последовательный порт. Последовательный порт хорош тем, что он весьма распространен, прост в программировании и, к тому же, существуют недорогие устройства USB-to-COM. Есть надежда, что мой программатор будет работать и через такой переходник. На компьютере я буду запускать мою специальную программу, управляющую программатором. Нам ее предстоит написать (в смысле я ее уже написал и расскажу как она работает).

Итак, в разъеме JTAG есть 4 существенные для нас сигнала: TDI, TMS, TCK и TDO.
Первые три сигнала являются входами для программируемой микросхемы ПЛИС, то есть мы с компьютера должны ими управлять. Управление каждым сигналом должно быть произвольным, любой из них мы можем в любой момент времени установить или сбросить. У последовательного порта есть несколько сигналов, подходящих для этих целей:

  • RTS - он будет соответствовать сигналу TDI интерфейса JTAG
  • DTR - он будет соответствовать сигналу TMS
  • TX - будет соответствовать сигналу TCK

Кроме этого, на JTAG есть выходной сигнал TDO, состояние которого нам нужно уметь читать с компьютера. Будем использовать для этих целей сигнал CTS последовательного порта.

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

HIN202 ( 640086 bytes )
 

Мы (как всегда) пойдем своим путем. Сделаем программатор по вот такой схеме:

схема простого программатора ПЛИС через последовательный порт

Несколько резисторов, стабилитроны, светодиоды для отладки программы и.. это все - проще не бывает.

Вот фотографии нашего программатора, вид сверху:

простой программатор ПЛИС через последовательный порт

Вид снизу:

простой программатор последовательного порта вид снизу

Программу я буду писать на языке C в среде Microsoft Visual Studio v10.
Моя программа будет состоять как бы из двух логических частей. Первая часть - это управление сигналами последовательного порта, а значит это и управление сигналами JTAG. Вторая часть программы - это чтение *.SVF файла, его интерпретация и последовательное исполнение. В прошлой статье я писал, что SVF файл описывает последовательность команд для TAP контроллера программируемой микросхемы. Среда Altera Quartus II может генерировать SVF файлы для откомпилированных проектов.

Для управления последовательным портом я буду пользоваться API функциями OS Windows:

  1. CreateFile(..) - используется, чтобы открыть последовательный порт
  2. EscapeCommFunction(..) - с параметрами SETRTS или CLRRTS для установки или сброса сигнала TDI
  3. EscapeCommFunction(..) - с параметрами SETDTR или CLRDTR для установки или сброса сигнала TMS
  4. EscapeCommFunction(..) - с параметрами SETBREAK или CLRBREAK для установки или сброса сигнала TCK
  5. GetCommModemStatus(..) - чтобы прочитать состояние линии CTS и соответственно узнать значение сигнала TDO от интерфейса JTAG

В программе определены две очень важные функции:
int sir(int nclk, int val);
int sdr(int nclk, int val);

Первая функция sir(..) записывает в регистр команд TAP контроллера программируемой микросхемы значение val длинной nclk бит. Вторая функция sdr(..) записывает в регистр данных TAP контроллера программируемой микросхемы значение val длинной nclk бит.

Функции выглядят примерно одинаково и делают примерно одно и то же. Используя сигнал TMS и TCK они переводят TAP контроллер в состояние записи соответствующего регистра IR или DR согласно диаграмме состояний (TAP state-machine) описанной в предыдущей статье. Сигнал TDI используется для последовательной передачи данных в регистр TAP, а сигнал TDO используется для чтения из контроллера ответных данных.

Теперь об интерпретаторе SVF файла.
Итак, Вы сделали проект для ПЛИС, откомпилировали его с помощью Quartus и получили SVF файл для программирования микросхемы.

SVF - это текстовый файл. Наша программа будет построчно считывать его и интерпретировать команду в этой строке и исполнять ее. Я не знаю всех подробностей стандарта SVF файлов, но то что я вижу в файле сгенерированном квартусом - это очень простой файл. Одна строка - одна команда. Нет никаких условных или безусловных переходов или подпрограмм. Таким образом, чтение и построчное исполнение SVF файла - вполне удобное для нас решение.

Собственно нужно реализовать только несколько основных команд: RUNTEST, SIR, SDR. Как вы конечно догадались команда SIR - записать число в регистр команд TAP и SDR - записать число в регистр данных. RUNTEST - это пауза, когда контроллер остается в состоянии IDLE. Скажу честно, что паузы я в своей программе выдерживаю не строго. У нас и так получится очень медленная частота записи из-за программной реализации протокола передачи. Так что выдерживать паузы согласно SVF надеюсь не обязательно.

Ну вот собственно программа написана и откомпилирована с помощью Visual Studio.
Вы можете скачать ее исходники и бинарный файл на нашем сайте: 

Программа консольная, принимает 2 параметра в командной строке: имя последовательного порта и имя файла SVF. Например, вот так:


c:\MarsBlaster.exe COM4 my_proj.svf


Подключаю плату Марсоход к нашему программатору, подключаем его к компьютеру подаем питание.

программирование ПЛИС через последовательный порт

Вот как идет программирование:

Вот еще видео, как идет программирование с другого ракурса:

Похоже все работает!!!

PS: ложка дегтя.
Через переходник USB-to-COM тоже работает, но очень медленно. Программирование платы Марсоход (включая проверку после записи) занимает около 5 минут. Причина в том, что управление сигналами идет через USB и чтение ответного сигнала TDO занимает очень много времени (2-3 миллисекунды). Избавиться от этого вот так просто не получится. Нужно делать более сложный программатор, с более сложной логикой работы, что бы обмен вести не побитно, а хотя бы байтами, тогда можно сделать гораздо быстрее.

Ну и еще обратите внимание на схеме программатора есть "обратная связь" с 6й на 3ю ножки разъема COM порта. Это то же нужно - как раз для работы через переходник USB-to-COM. Эта обратная связь позволяет точно сказать пришли ли данные о статусе TDO или еще нет. Я устанавливаю TCK и читаю через обратную связь его же - пришел он или еще нет. Если пришел, значит с ним пришел и TDO. Немного мудрено получилось, но работает.

 

 

Добавить комментарий