На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
Страницы: (51) « Первая ... 43 44 [45] 46 47 ...  50 51  ( Перейти к последнему сообщению )  
> Желающим USB под ДОС , Welcome!!!
    Вся система USB работает одинаково независимо от того, какой контроллер используется. Если рассмотреть систему USB как модель OSI, то уровень контроллера - это самый нижний, физический уровень.
    В общем виде алгоритм взаимодействия между хостом и устройством выглядит примерно так:
    1. Сбрасываем контроллер, проводим его инициализацию (устанавливаем все нужные адреса и маски прерываний).
    2. Выясняем количество портов на контроллере (N).
    3. Далее идет цикл по количеству портов. Полагаем i=1.
    4. Для порта номер i включаем питание, если контроллер это поддерживает, устанавливаем статус Port Enabled (если необходимо) и выясняем, подключено ли к порту устройство.
    5. Если ничего не подключено, идем на п.9.
    6. Если устройство есть, выясняем его скорость - low-speed, full-speed или high-speed (это для EHCI, USB 2.0).
    7. Присваиваем устройству адрес (SET_ADDRESS).
    7. Запрашиваем дескриптор устройства и выясняем VID, PID, серийный номер (если интересно) и класс устройства.
    8. Дальше делаем ветвление по классу устройства, делаем всю нужную обработку для тех классов, которые мы поддерживаем.
    9. i=i+1.
    10. Если i<N, то идем на п.4.
    11. Конец.

    Как именно делать все эти операции, зависит от типа контроллера, поэтому лично я делал обобщенные функции типа Setup, Control-In, Bulk-In, Bulk-Out, внутри которых уже шло ветвление по типу контроллера и вызывались функции вроде OHCI_Setup, UHCI_Setup, EHCI_Setup и т.д.

    Но мы сейчас говорим только про OHCI. В принципе то, что ты написал, верно. Только я сейчас плохо помню, как именно там использовалась HCCA. А тексты программ у меня на работе. Раньше 6-го числа посмотреть не смогу.
      Прочитал эту тему почти полностью. Как я понял когда посылаем порту Reset HC присваивает устройству подключенному к это порту адрес 0.
      Значит нужно сформировать 1 ED(для 0 устройства) записать его в соответствующий регистр, циклически посылать Reset портам к которым подключены устройства и после каждого Reset формировать TD с командой SET_ADDRESS, записываем этот TD в ED и радуемся?

      Добавлено
      А ED сохраняем по адресу которое в HCCA?
        Цитата Modulator @
        Как я понял когда посылаем порту Reset HC присваивает устройству подключенному к это порту адрес 0.

        Что-то не так. Откуда взят термин "Reset HC"? В спецификации есть бит HCR, это полный ресет контроллера, не имеет отношения к порту. В порт посылаем SetPortReset, выставляя бит PRS.

        Да, после ресета адрес устройства сбрасывается в 0. Поэтому нельзя ресетить несколько портов одновременно, иначе может включиться несколько устройств с адресом 0, и возникнет путаница, кому какой пакет предназначен. С портами работаем строго по очереди, в системе в каждый момент времени должно быть не больше одного устройства с адресом 0.
        После ресета устройство с адресом 0 способно принимать/передавать пакеты длиной не более 8 байтов и только на endpoint 0. Полный дескриптор устройства можно получить только после присвоения ему нормального адреса.

        Что касается конкретной работы с OHCI - я сейчас ничего сказать по памяти не могу. Делал все лет 5 назад. 6-го числа посмотрю, что там у меня в коде было.
          Просто забыл запятую между "Reset" и "HC". :)
          А ED только для 0 устройства в ручную формировать? А остальные ED после SET_ADDRESS хостом будут созданы или их тоже самому формировать?
            Давай еще немного определимся. Хост - это совокупность программно-аппаратных средств. Контроллер (HC) + драйвер (HCD). Вот ты как раз и делаешь HCD. Контроллер ничего не формирует сам, он же не знает, что ты вообще собираешься предпринять. Все дескрипторы для транзакций формируются софтом, то есть тобой.
            И еще. ты писал "HC присваивает устройству подключенному к этому порту адрес 0". Контроллер не присваивает никаких адресов. После сигнала RESET (это когда шины D+ и D- обе сразу выставляются в 0) устройство само сбрасывает свой адрес. После этого драйвер (HCD, то есть ты) должен присвоить этому устройству правильный адрес. Какой именно - неважно, главное, чтобы не 0. И чтобы у всех одновременно подключенных устройств адреса были разные.
            Сообщение отредактировано: zakharo -
              От себя добавлю, что есть такая штука как хабы, так вот, чтобы:
              Цитата Modulator @
              Мне нужно получить серийники всех подключенных USB устройств.

              По-уму нужно уметь с ними работать. Иначе ты получишь только список устройств, которые непосредственно подключены к хост-контроллеру. А бывают еще материки со встроенными хабами, тогда ты вообще ничего кроме этих самых хабов не получишь.

              Добавлено
              Modulator, для начала попробуй прочитать первые 8мь байт дескриптора устройства после сброса порта. Если это получится, то уже проще будет.
              Цитата zakharo @
              осле ресета устройство с адресом 0 способно принимать/передавать пакеты длиной не более 8 байтов и только на endpoint 0.

              ЕМНИП, то можно и больше 8ми байт. По крайней мере я со своей флешки считывал 64 байта сразу по нулевому адресу. Другое дело, что так делать нельзя в силу того, что мы не знаем макс. размер пакета этой самой КТ. А 8мь байт является минимально допустимой и из них уже можно вычислить максимальный размер пакета.
                Цитата shm @
                По крайней мере я со своей флешки считывал 64 байта сразу по нулевому адресу.

                Это тебе просто повезло. Мне тут довелось разбираться с микропрограммами некоторых USB-девайсов, там состояние устройства отслеживается строго. Если оно не пронумеровано, то на запрос дескриптора отдается только 8 байт. Если хост просит больше, то выставляется STALL. Понятно, что не все производители пишут именно такие микропрограммы и ставят такое ограничение, но вот мне такие попадались.
                Сообщение отредактировано: zakharo -
                  А что в HCCA должно быть?Адреса на ED или сами ED?
                    В HCCA все в куче идет и ED и TD, а завязаны они между собой через соответствующие поля?
                    То есть я формирую ED для нового устройства и записываю в свободное место в HCCA?
                      ".. 32 Dwords are pointers to interrupt EDs." 32 двойных слова - указатели на ED типа interrupt. КТ типа interrupt - это конечные точки, которые опрашиваются контроллером автоматически с некоторой периодичностью. Так удобно работать, например, с USB клавиатурой - контроллер сам все время опрашивает ее, а софт только смотрит на полученные данные. А также с изохронными КТ.
                      Насколько я помню, я вообще не завязывался с HCCA - только выделил 256 байт, поскольку контроллер активно работает с этой областью - там есть поля типа HccaFrameNumber и т.д.
                      А для обычных Control и Bulk транзакций у контроллера есть регистры HcControlHeadED и HcBulkHeadED. Можно сформировать нужные ED в любом месте памяти и записать в эти регистры их адреса.
                      Точнее все скажу 6-го, это уже послезавтра. Потерпи.
                        Значит в памяти формирую цепочку ED, адрес начального ED записываю в HcControlHeadED например.В одним из ED записываю адрес TD. А как контроллер понимает когда нужно выполнить транзакцию или ему нужно сообщить об этом?
                          В регистре HcCommandStatus есть биты CLF (ControlListFilled) и BLF (BulkListFilled), которые как раз и говорят контроллеру, что соответствующая очередь выстроена и ее пора исполнять. То есть ты заполняешь ТD и ED и записываешь 1 в нужный бит.

                          Кстати, вот забыл еще одну тему. При старте компьютера управление над USB контроллерами берет на себя BIOS. Чтобы забрать управление на себя, надо сделать кое-какие телодвижения - иначе BIOS будет думать, что контроллер все еще у нее и мешать тебе делать твои транзакции. Для отъема управление есть бит OCR (OwnershipChangeRequest) в том же регистре. Перед тем, как начинать работать с контроллером, надо выставить этот бит в 1. Тогда контроллер даст прерывание в BIOS, та аккуратно завершит свою работу, и после всего этого контроллер сам обнулит этот бит. Ты должен дождаться, когда этот бит обнулится и только после этого можешь начинаться свою работу с контроллером.
                            А ответ на отправленный запрос получать из буфера который я указал в TD, который в свою очередь находится в ED с направлением OUT?
                              Ответ - это не просто ответ. Ты же делаешь разные транзакции, в том числе SETUP и OUT, и никакого ответа в буфер там нет.
                              Сначала надо убедиться в том, что транзакция завершена.
                              Цитата
                              A transfer is completed when the Host Controller successfully transfers, to or from an endpoint,
                              the byte pointed to by BufferEnd. Upon successful completion, the Host Controller sets
                              CurrentBufferPointer to zero, sets ConditionCode to NOERROR, and retires the General TD to
                              the Done Queue.

                              ...При успешном завершении HC устанавливает CurrentBufferPointer в 0, ставит ConditionCode в состояние NOERROR.. - по этим критериям и надо ориентироваться. А когда убедищься, что все прошло, тогда уже делаешь дальнейшие действия. Если ты что-то запрашивал, то оно будет в буфере, который ты указал в TD. А если выводил из этого буфера в устройство, то, значит, информация выведена.

                              Кстати, не забудь после транзакции SET_ADDRESS (пакет типа SETUP) запросить от устройства пакет нулевой длины (пакет типа IN). Прием такого пакета является признаком того, что предыдущий пакет передан на устройство правильно.
                                То есть если я хочу отправить запрос Get_Configuration, я же записываю адрес на буфер с этим запросом в CurrentBufferPointer в TD?А при успешной транзакции ответ будет записан по этому же адресу?

                                Добавлено
                                Или нужно сформировать TD для ED OUT?
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (51) « Первая ... 43 44 [45] 46 47 ...  50 51


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0649 ]   [ 15 queries used ]   [ Generated: 19.07.25, 11:29 GMT ]