МАРСОХОД

Open Source Hardware Project

Проекты Altera Quartus II для платы Марсоход

USB устройство из платы Марсоход

Я уже писал кое-что про USB. 

usbplug

Тема эта очень сложная, но с другой стороны очень полезная и нужная. У меня одна статья была про USB протокол вообще, а вторая – это был уже первый проект USB для платы Марсоход.  Хорошо бы, чтоб Вы сперва прочитали те статьи. Тогда и эту будет легче понять. К сожалению в том первом проекте не все было сделано достаточно хорошо, и вот, потратив еще немного времени, мы выпускаем следующую версию проекта низкоскоростного устройства USB для нашей платы Марсоход.
Что было улучшено?

  • Десктипторы и всякие другие пакеты раньше кодировались в логике, а теперь перенесены в UFM (User Flash Memory) чипа. Это позволило освободить немного места в чипе и сделать дескрипторы «длиннее и осмысленней».
  • Теперь мы предлагаем Windows драйвер для нашего устройства!
  • Теперь устройство должно правильно распознавать назначение USB адреса, а значит, может работать через USB хабы без конфликтов с другими устройствими.
  • Были исправлены ошибки связанные с «bit stuffing»
  • Теперь в наше устройство можно не только писать, но и можно читать из него!

Итак, попробую описать мой проект.


В этом проекте USB сейчас всего 5 модулей. Это модуль чтения пакетов из флешки чипа pkt_reader, модуль altufm_none0, который представляет флеш память  чипа и встроенный генератор (около 5Mhz), USB приемник ls_usb_recv, USB передатчик ls_usb_send, и ядро USB функции ls_usb_core.

Схема проекта USB устройства на ПЛИС платы Марсоход

1.    Чтение USB пакетов из UFM.

Чип CPLD, который установлен на плате Марсоход имеет встроенную флеш память небольшого объема – всего 512 шестнадцатибитных слов. Это не много, но вполне достаточно для хранения всяких USB descriptors – описателей USB устройства. Как я уже писал в предыдущих статьях, при подключении USB устройтва оно должно быть распознано системой. Операционная система определяет тип устройства, его название, серийный номер (если есть) читая эти описатели из устройства. Кроме того, устройству назначается USB адрес, который оно должно использовать во время работы. Для всех эти обменов данными в обе стороны нужны зараннее заготовленные пакеты. Мы разместили все пакеты дескрипторов в этой флеш памяти UFM в специальном формате.
Например, вот фрагмент файла table2.mif, который описывает содержимое флеш:

-- Descriptor String Serial Number
01e0 : 4b8d;
01e1 : 0312;
01e2 : 0030;
01e3 : 0030;
01e4 : 0030;
01e5 : d112;
01e6 : 0000;
01e7 : 0000;


Пакет дескриптора описан так, как он будет передаваться в USB шину: байт за байтом, от первого байта PID, до последних двух байтов контрольной суммы включительно. Единственное исключение – нулевой байт описателя. Младшая тетрада обозначает длину передаваемого пакета. Вместо этого нулевого байта всегда будет посылаться, как положено байт SYN == 0x80, обозначающий начало пакета.
Кроме этого, в самом начале файла table2.mif имеется 32 специальных коротких пакета – это те пакеты, которые мы сможем читать из нашего устройства как "полезные данные". Я решил, что нужно сделать возможным чтение состояния 4-х кнопочек платы Марсоход. Четыре кнопочки – это 16 комбинаций. Но поскольку передача пакетов по шине USB нумеруется как четный-нечетный, то всего нужно «заготовить» уже 32 пакета. Таким образом, когда программа на компьютере захочет прочитать состояние кнопочек платы, она посылает запрос на чтение и наше USB CORE сразу знает адрес флеш памяти для ответного пакета – адрес прямо определяется 4-мя битами кнопок плюс один бит четности. Зараннее заготовленные пакеты хороши тем, что не нужно делать логику по подсчету контрольной суммы USB.

Исходный текст модуля чтения пакетов из флешки можно посмотреть здесь.

2.    Модуль USB приемника.

В этот модуль были внесены несколько важных изменений. Во-первых, исправлена ошибка приема при «bit stuffing». Во-вторых, добавлено детектирование сигнала сброса шины USB. Конечно, оно несколько примитивное, но вполне работоспособное. У меня сигнал usb_reset появляется если обе линии USB DP и DM находятся в нуле более 16 тактов. Это конечно не 10мс, как по USB спецификации, но такое решение работает. Сигнал USB сброса важен для правильного назначения USB адреса устройству.

Приемник не работает, когда наше устройство само что-то передает. То есть мы не принимаем свои же данные. Это сделано с помощью входного сигнала enable (инверсия от bus_enable).

Принятые байты выдаются на шине rdata[7..0] по сигналу rdata_ready. Кроме того, номер принятого байта в принимаемом пакете выдается по шине rbyte_cnt[3:0]. Все эти сигналы подаются на вход USB CORE, которое и решает, что же дальше нужно делать.

Вот исходный текст модуля на Verilog. Зараннее хочу попросить прощения у некоторых возможных критиков. В этом модуле кое-где используется ассинхронный сброс триггеров не по прямому назначению (приведение схемы в исходное состояние после включения питания), а для непосредственной работы приемника. Это сделано умышленно с единственной целью экономии места в чипе. Все таки у меня не очень тривиальная задача сделать правильно работающее устройство в 240 логических элементах ПЛИС. Пришлось реально поломать голову как разместить всю логику, чтобы еще и на будущее развитие осталось.

Здесь можно посмотреть как USB приемник работает, его временные диаграммы (кликните на изображении, чтобы увеличить):

сигналы в модуле USB приемника

3.    Модуль USB передатчика.

Передатчик простой. По сигналу start_pkt начинается передача первого байта. Включается сигнал bus_enable и двунаправленная шина USB переключается на передачу от нашего устройства к хосту. Передаваемые данные подаются в передатчик по шине sbyte[7..0]. Когда передатчику требуется следующий байт пакета он выставляет сигнал show_next и USB CORE должно предоставить этот следующий байт на шине sbyte[7..0]. Так же, USB CORE должно зараннее уведомить передатчик о последнем байте в пакете сигналом last_pkt_byte. Когде передан последний байт, передача завершается состоянием SE0 (сигналы DP и DM в нуле в течении двух периодов передающей частоты 1,5Mhz) и затем снимается сигнал bus_enable, шина переводится в направление «на прием».

Вот исходный текст модуля USB передатчика на Verilog.

Временные диаграммы (кликните на изображение, чтобы увидеть крупнее):

Сигналы модуля USB передатчика платы Марсоход

Вот еще крупнее:

Сигналы модуля USB передатчика платы Марсоход

4.    Модуль USB CORE, определяет всю логику устройства.

Самое главное предназначение этого модуля – распознавать принятые от хоста пакеты и решать, что с ними делать дальше, возможно отвечать своими пакетами в нужной последовательности. Именно этот модуль определяет когда и какой пакет из какого дескриптора посылать. Этот модуль вырабатывает запрос на чтение пакета из флешки и передает считанные данные в передающий модуль. Адрес пакета во влеш памяти UFM определяется типом запроса от хоста.

Еще одна необходимая и важная функция этого модуля – правильная реакция на назначение USB адреса. Устройство не должно ничего отвечать, если запрос от хоста идет для другого адреса. Такое возможно, если устройство подключенно через USB хаб.

Исходный текст модуля здесь.

5.    Драйвер устройства и пользовательская программа.

Поскольку мы решили все сделать как можно правильней, то нам, конечно, нужен драйвер к нашему устройству. Написание драйверов операционной системы Windows - это отдельная и сложная тема. Скажу лишь, что в данном случае мы не написали ни строчки кода. Мы взяли пример драйвера USB устройства из пакета Microsoft Windows Driver Developer Kit. У меня сейчас стоит версия WINDDK 2600.1106. Возможно (наверняка) есть и более свежий пакет разработчика драйверов от Microsoft. Поищите на сайте Microsoft.
В том DDK, что есть у меня, я нашел пример прототипа драйвера в папке c:\winddk\2600.1106\src\wdm\usb\bulkusb
В этой папке есть пример драйвера bulkusb.sys и пример пользовательского приложения, которое читает из устройства или пишет в него RwBulk.exe.
Я просто откомпилировал эти программы и их сразу можно пытаться использовать и нашим устройством. Правда есть одно небольшое «но». Сперва нужно установить драйвер в ОС и для этого нужно иметь INF файл.
В примере Microsoft есть и пример INF файла. Он нам, в общем, подходит. Только нужно заменить в нем строку описывающую идентификатор производителя устройства и идентификатор устройства. Эти параметры напрямую определяются USB дескрипторами устройства – а они у нас записаны во флеш памяти.

Наша строка должна выглядеть вот так:

%USB\VID_09FB&PID_60A5.DeviceDesc%=BULKUSB.Dev, USB\VID_09FB&PID_60A5

Для нашего устройства мы взяли idVendor = 0x9FB (Altera) и idProduct=0x60A5. Эти числа стоят в нашем Configuration Descriptor.

Итак. Компилируем наш проект. Прошиваем плату Марсоход. Подключаем провод с разъемом USB к плате. Подключаем плату к USB порту компьютера. Появляется окно «Найдено новое устройство».  Далее следуете указаниям в этом окне. Установка драйвера вручную.  Указываете путь к INF фйлу и путь к драйверу bulkusb.sys. Все. Драйвер установлен. В этом легко убедиться, если зайти в диспетчер устройств:

USB устройство плата Марсоход виднав диспетчере устройств компьютера

Для работы с устройством я написал (Microsoft Visual Studio v6.0) простую тестовую программу. Она позволяет зажигать на плате Марсоход светодиодики и читать состояние кнопочек платы.

Программа для работы с платой Марсоход через USB

Теперь у нас все сделано более правильно. Чтобы зажечь светодиод программа пишет в устройство. Передача туда идет на USB Endpoint = 2. Чтение из устройства идет на USB Endpoint =1.

Исходные тексты драйвера, INF файла и этой программы Вы найдете в архиве вместе с проектом Altera Quartus II для платы Марсоход: icon Простое USB устройство на плате Марсоход. Версия 2 (161.95 Кбайт)

Вот подключаем нашу плату к ноутбуку через USB хаб.

Плата Марсоход с функцией USB

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

Вот на этом видео это то же видно. Я могу зажигать светодиоды на плате нажимая чекбоксы в программе. Когда нажимаю кнопочки на плате Марсоход, то программа это видит и меняет имя кнопочки на экране.

Вот так. Надеюсь на базе этого проекта скоро мы сможем показать вам еще много интересных вещей.

 

 

Комментарии  

0 #15 Роман 07.09.2012 14:31
Цитирую nckma:
Цитирую Роман:
Устройство в диспетчере не опознано. Драйвер не устанавливается. Win7/ 32-bit/ что делать?

попробуйте улучшить проект вот так: http://marsohod.org/index.php/projects/117-usbenh

так и сделал. только в качестве внешнего генератора у меня сигнал идёт с отладочной платы Altera. Чистый сигнал 12 Мгц. Может быть с дровами для Win7 проблемы? Не хочет устанавливать драйвер вообще.
0 #14 nckma 07.09.2012 12:46
Цитирую Роман:
Устройство в диспетчере не опознано. Драйвер не устанавливается. Win7/ 32-bit/ что делать?

попробуйте улучшить проект вот так: http://marsohod.org/index.php/projects/117-usbenh
0 #13 Роман 07.09.2012 12:26
Устройство в диспетчере не опознано. Драйвер не устанавливается . Win7/ 32-bit/ что делать?
0 #12 sTs 07.05.2011 21:55
Приглашаю админов сайта и всех желающих поучаствовать в довольно редком явлении- конкурсе самоделок. http://mozgochiny.ru/konkurs/
Главный приз $30/ Сумма не большая, но выкладываю его из своего кармана как организатор. Если будет спрос на подобные конкурсы, то обещаю сделать их регулярным явлением. Спешите, до конца осталось меньше месяца! :-)
В конкурсе может принять участие КАЖДЫЙ с любой самоделкой.
друг другу удачи :bo: !
0 #11 nckm 30.12.2010 07:39
Цитирую foxit:
А можно ли сделать адаптер USB - 4COM?

трудно сказать. Главная проблема - объем чипа. Свободного места осталось не так уж много (сказать по правде совсем мало). И так очень многое сильно упрощено..
0 #10 foxit 29.12.2010 16:42
А можно ли сделать адаптер USB - 4COM?
0 #9 Ю р и й 27.12.2010 06:23
Скорее всего дело в тактовой частоте.
Вам нужно найти генератор на 24МГЦ и
взять какой-нибудь из более новых проектов.
0 #8 Ensase 27.12.2010 06:07
Еще раз здравствуйте!
Залил конфигурацию и подключил плату к USB.
Когда запитываю от 3.3 через программатор устройство находится, драйвера пытаются установиться, но в результате устройство в диспетчере отображается как Marsohod.Org с восклицательным знаком и не видится программой. Когда же запитываю от USB появляется сообщение "Устройство не опознано"
0 #7 Ensase 27.12.2010 04:48
На той плате, что у меня почему-то всего один диод.
Попробую запитать напрямую от USB.
В datasheet указано напряжением питания 3.3.

Спасибо за ответы.
0 #6 nckm 26.12.2010 20:06
Цитирую Ensase:
Добрый день!

Выложите, пожалуйста распайку подключения USB и расскажите, если не трудно куда припаять стабилизатор напряжения на 3.3В.
Заранее спасибо.

На схеме платы Марсоход есть 4 контакта подряд +5В, DN, DP, GND - вот это 4 сигнала для разъема USB.

Насчет стабилизатора напряжения я не очень понял вопроса. С разъема USB берется +5В и через 2 диодика питается вся плата. Никаких стабилизаторов как бы и не надо
0 #5 Ensase 26.12.2010 12:02
Добрый день!

Выложите, пожалуйста распайку подключения USB и расскажите, если не трудно куда припаять стабилизатор напряжения на 3.3В.
Заранее спасибо.
0 #4 Ю р и й 02.12.2010 10:20
Не возражаем.
0 #3 TerraMan 02.12.2010 07:17
Очень понравился ваш марсоход! Не возражаете против публикации ваших проектов на сайте Терраэлектроник и с обратными ссылками?
0 #2 Kiriller73 26.10.2010 15:58
:lol:
Круто, продолжайте в тоже духе. Лучше чтобы что-то уже двигалось, куда-то. И ... стреляло !
:lol:
0 #1 zchel 26.10.2010 14:15
котэ внимательно наблюдает за происходящим :lol:

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


Защитный код
Обновить


GitHub YouTube Twitter
Вы здесь: Начало Проекты Проект Марсоход USB устройство из платы Марсоход