На главную Наши проекты:
Журнал   ·   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) « Первая ... 26 27 [28] 29 30 ...  50 51  ( Перейти к последнему сообщению )  
> Желающим USB под ДОС , Welcome!!!
    Вот, еще вспомнил (прочитал) про бит CONFIGURED - после установки его в 1 все порты переходят к EHCI (биты 13 PORT_OWNER в регистрах PORTSC устанавливаются в 0).
    Потом просматриваем все PORTSC и делаем такие действия:
    1. Если бит 0 (Current Connect Status) стоит в 1, значит, что-то подключено. Если нет - пропускаем этот порт.
    2. Если биты 10,11 (Line Status) установлены в 01, значит, подключено low speed устройство, мы с ним не работаем. Выставляем бит 13 (Port Owner) в 1 и переходим к следующему порту.
    3. Делаем EHCI_RESET. Выставляем бит 8 (Port Reset) в 1 и одновременно бит 2 (Port Enable) в 0 и выдерживаем как минимум 10 миллисекунд (я держу 12). Потом устанавливаем Port Reset в 0, и дожидаемся, когда он действительно сбросится в 0. Если после этого бит 2 (Port Enable) установился в 1, то устройство поддерживает high speed, и мы можем с ним работать. Если Port Enable остается в 0, то устройство не поддерживает high speed, и мы должны отдать его компаньону (ставим Port Owner в 1).

    Дальше начинается работа непосредственно с устройством. Первое, что мы должны сделать - это пронумеровать устройство. Для этого надо послать пакет типа SETUP, содержащий стандартный Request. Структура всех request'ов на языке Си выглядит так:
    {
    unsigned char bmRequestType; // 1 байт
    unsigned char bRequest; // 1 байт
    unsigned short wValue; // 2 байта
    unsigned short wIndex; // 2 байта
    unsigned short wLength; // 2 байта
    };
    Общая длина - 8 байт. Значения полей для SET_ADDRESS : {0,5,адрес_устройства,0,0} в порядке little-endian, т.е. младшими байтами вперед. Если расписать в байтах, то при адресе устройства, например, 1, будет такая последовательность байтов: 0,5,1,0,0,0,0,0.

    Для посылки этого запроса через EHCI мы должны разместить этот запрос так, чтобы он не пересекал границу страницы физической памяти, записать его физический адрес в qTD, заполнить все остальные нужные поля qTD, выстроить очередь qTD и запустить контроллер на выполнение этой очереди.
    Очередь qTD должна состоять из двух qTD - на этот запрос устройство отвечает пакетом нулевой длины, и этот пакет надо принять.
      У qTD размер 32 байта, в
      Next qTD Pointer мы занесём адрес стедующего qTD и Т=0,
      Alternate Next qTD Pointer ставим 0
      dt=0 Total Bytes to Transfer=8 ioc=0 C_Page=0 Cerr=0 PID Code=10b(SETUP) Status=0
      Buffer Pointer (page 0)=адрес на пакет SET_ADDRESS из 8 байт Current Offset=?
      Buffer Pointer (page 1)=0
      Buffer Pointer (page 2)=0
      Buffer Pointer (page 3)=0
      Buffer Pointer (page 4)=0
      Следующий
      Next qTD Pointer=0 Т=1,
      Alternate Next qTD Pointer ставим 0
      dt=0 Total Bytes to Transfer=0 ioc=0 C_Page=0 Cerr=0 PID Code=? Status=0
      Buffer Pointer (page 0)=0 Current Offset=?
      Buffer Pointer (page 1)=0
      Buffer Pointer (page 2)=0
      Buffer Pointer (page 3)=0
      Buffer Pointer (page 4)=0

      А куда записывать адрес самого qTD
      и как понять что нам ответили и где будет этот ответ?
        Адрес первого qTD записывается в QH. Адрес QH - в соответствующщий регистр контроллера.
        Ответом будет факт приема пакета нулевой длины от устройства.
          Ответом будет факт приема пакета нулевой длины от устройства. :wacko:
          А как понять что у нас факт приема пакета нулевой длины от устройства.
            В qTD будет сброшен бит активности. И еще контроллер даст прерывание, если они не запрещены.
              Понял спасибо.
              Во втором нулевом?
              Сообщение отредактировано: StasNewOs -
                В каждом. Каждая транзакция приводит к сбросу бита активности соответствующего qTD. Я в своей программе пользуюсь этим для определения того, что транзакция произошла. Просто проверяю биты активности каждого qTD из очереди в цикле с таймаутом. Но мне спешить некуда, а вообще-то правильнее было бы работать с прерываниями.

                Добавлено
                Кстати, при построении qTD бит активности (бит 7 поля Status) надо взводить. В твоих терминах это будет записываться Status = 80h.
                Для второго qTD (прием пакета нулевой длины) PID Code будет 01b (пакет типа IN).
                  Понял, нужно проверять статус на изменения, и там будет либо ошибка либа выполнено. Мы отправим qTD в QH, а где в нём будет инфа о самом порте, которому мы номер посылать собрались, нашему порту с включеным битом enable.

                  Queue Head Horizontal Link Pointer= Т=
                  RL= C= Maximum Packet= Length= H= EndPt= Device Address=
                  Mult= Port Number*= Hub Addr*= μFrame C-mask*= μFrame S-mask=

                  А после всех заполнений Asynchronous Schedule Enable поставить 1, и кто его выключать должен.

                  С прерываниями кстати тоже проблемы, т.к. после их вызова нужно чтото делать с контроллером, иначе комп виснет.
                    Номер порта при транзакциях не используется вообще. Все транзакции однозначно определяются номером устройтсва на шине и номером конечной точки (endpoint) в устройстве.
                    При первой транзакции (нумерации) логика такая: мы дали ресет на конкретный порт. Устройство (если оно есть) после ресета имеет адрес 0, на этот адрес мы и посылаем пакет SET_ADDRESS. Все предудыщие порты уже обработаны - если там есть high-speed устройства, то им уже присвоены адреса, отличные от 0, если нет - то там нет бита Port Enable, т.е. порт недоступен из EHCI (либо уже отдан компаньону, либо просто пустой). Все последующие порты еще не обработаны, и там тоже нет бита Port Enable. То есть в каждый конкретный момент в системе может быть только одно устройство с адресом 0, именно ему и посылается пакет SET_ADDRESS. На конечную точку номер 0 (control endpoint).

                    Asynchronous Schedule Enable выключаешь сам, когда кончается очередь. В серьезных системах типа Windows или Linux очередь может пополняться динамически, и этот бит скорее всего вообще не выключается. Я в своей программе выключаю, поскольку работаю только с одним QH, и если я начну модифицировать очередь при включенном Asynchronous Schedule Enable, контроллер может начать ее выполнять раньше, чем я ее сформирую, а этого мне не надо. Поэтому я включаю этот бит тогда, когда очередь уже сформирована, и выключаю тогда, когда выполнены все qTD (проверяю по биту активности).

                    Поля Port Number и Hub Address нужно заполнять только тогда, когда используется хаб USB 2.0, к которому подключено устройство USB 1.1.

                    С прерываниями я не работаю, а в принципе, обработка прерываний должна быть стандартная - определить причину прерывания и сделать нужные действия, в т.ч. и с контроллером прерываний.
                      После номерации в Queue Head мы заносим этот номер в Device Address для посылки запроса на это устройство? Седьмой бит стоит какойто флаг I, значит номеров 128?
                        Что значит после нумерации в Queue Head?
                        Все наоборот. В QH ставится номер устройства, которому адресован пакет. Если оно еще не пронумеровано, его номер - 0. После того, как оно будет пронумеровано, мы для дальнейших транзакций будем ставить в QH его номер.

                        7-й бит в Queue Head DWord 1 - флаг I, да.. This field is only valid when the queue head is in the Periodic Schedule, т.е. для асинхронных транзакций значения не имеет. Адрес устройства занимает младшие 7 бит, т.е. может быть не более 127.
                        Сообщение отредактировано: zakharo -
                          При начальной загрузке захожу в bios и вижу названия устройств, подключенных через USB, например: JetFlash Trancend, WDC WD1001FALS-00J7B0. Интересно узнать, откуда bios эти названия берет? А если взял, то куда помещает, чтобы их можно было считать.
                            BIOS их берет из устройств. После того, как проделает все операции по инициализации и пр. Первой командой на уровне SCSI идет Inquiry, в ответ на которую устройство и возвращает свое название.
                            А куда помещает - фиг знает.. В какие-то свои буферы.
                            Сообщение отредактировано: zakharo -
                              Цитата zakharo @
                              Первой командой на уровне SCSI идет Inquiry, в ответ на которую устройство и возвращает свое название.

                              У меня UHC и EHC контроллеры. Может где есть ассемблерный пример с использованием Inquiry? А вообще, я пишу не программы, а батники, исполняемые в реальном режиме на уровне биоса, путем запуска специального загрузчика, позволяющего работать с памятью, прерываниями и портами ввода-вывода. Ассемблерный код переделываю под батник.
                                Боюсь, что только Inquiry не обойтись. Придется полностью брать на себя управление контроллером.
                                Может быть, легче в BIOSе найти эти имена? Если тебе доступна вся память, то и просканируй ее. Хотя не исключено, что BIOS хранит их где-нибудь в невидимой области.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (51) « Первая ... 26 27 [28] 29 30 ...  50 51


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0816 ]   [ 15 queries used ]   [ Generated: 21.07.25, 23:17 GMT ]