Перейти к содержанию

    

Проблема с enumeration при подключенииЕсть RTL-код USB функции, зашиваемый в FPGA, при подключении к хосту начинается процесс енумерации. USB-функции

Есть RTL-код USB функции, зашиваемый в FPGA, при подключении к хосту начинается процесс енумерации.

Выполняется следующая последовательность:

1. setup-data0(get_descriptor)-ack

2. in-data1-ack

3. out-data1(null packet)-ack

4. reset line

5. setup-data0(set_address)-ack

6. in-data1(null packet)-ack

7. setup(по присвоенному адресу 0x3)-data0(get_descriptor)-ack

 

На следующем шаге начинаются проблемы

8. in(address-0x3)-data1 - ...

Хост не отвечает подтверждением на отправленный ему дескриптор.

Смотрел на осциллографе - пакет правильный, PID на месте, CRC сходится, межпакетный интервал - тоже.

При этом, если вместо дескриптора отправить ему нулевой пакет данных, то подтверждение появится и перейдем к шагу 9.

 

9. out-data1(null packet)-ack

 

Из этого возникают следующие вопросы:

1. точно ли в п.8 нужно отправлять дескриптор

2. зачем хост отвечает подтверждением на нулевой пакет и продолжает процесс енумерации, если требовал дескриптор

3. зачем вообще нужно два раза отправлять дескриптор?

 

Ответьте, пожалуйста, если кто-нибудь сталкивался с чем-нибудь подобным или знает в чем тут дело.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть логи энумерации флешки, снятые аппаратным анализатором. Один из них - под w98se на full speed (с каким-то универсальным драйвером), второй - на XPsp1 на high speed. Прикладываю их к сообщению - вдруг поможет.

LOGW.ZIP

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Packet id<IN> devAddr<1> epNum<0> crc5<0x1D> speed<HS> time<4.406

554 267>

Packet id<DATA1> length<18> data<12 01 00 02 00 00 00 40 05 10 13

B1 00 01 01 02 03 01> crc16<0x38CC> speed<HS> time<4.406 554 600>

 

Packet id<ACK> speed<HS> time<4.406 555 317> - отсутствует

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По моему нужно сделать FAQ по USB и занести туда первым описание порядка энумерации.

Цитата из "USB in a Nutshell" www.beyondlogic.org :

 

Enumeration is the process of determining what device has just been connected to the bus and what

parameters it requires such as power consumption, number and type of endpoint(s), class of product etc. The

host will then assign the device an address and enable a configuration allowing the device to transfer data on

the bus. A fairly generic enumeration process is detailed in section 9.1.2 of the USB specification. However

when writing USB firmware for the first time, it is handy to know exactly how the host responds during

enumeration, rather than the general enumeration process detailed in the specification.

 

A common Windows enumeration involves the following steps,

 

1. The host or hub detects the connection of a new device via the device's pull up resistors on the

data pair. The host waits for at least 100ms allowing for the plug to be inserted fully and for power

to stabilise on the device.

 

2. Host issues a reset placing the device is the default state. The device may now respond to the

default address zero.

 

3. The MS Windows host asks for the first 64 bytes of the Device Descriptor.

 

4. After receiving the first 8 bytes of the Device Descriptor, it immediately issues another bus reset.

 

5. The host now issues a Set Address command, placing the device in the addressed state.

 

6. The host asks for the entire 18 bytes of the Device Descriptor.

 

7. It then asks for 9 bytes of the Configuration Descriptor to determine the overall size.

 

8. The host asks for 255 bytes of the Configuration Descriptor.

 

9. Host asks for any String Descriptors if they were specified.

 

At the end of Step 9, Windows will ask for a driver for your device. It is then common to see it request all the

descriptors again before it issues a Set Configuration request.

 

The above enumeration process is common to Windows 2000, Windows XP and Windows 98 SE.

Step 4 often confuses people writing firmware for the first time. The Host asks for the first 64 bytes of the

device descriptor, so when the host resets your device after it receives the first 8 bytes, it is only natural to think

there is something wrong with your device descriptor or how your firmware handles the request. However as

many will tell you, if you keep persisting by implementing the Set Address Command it will pay off by asking for

a full 18 bytes of device descriptor next.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем спасибо за помощь - натолкнули на решенеие.

 

Теперь сам могу ответить на поставленные мною вопросы.

 

1. точно ли в п.8 нужно отправлять дескриптор ----- Да.

2. зачем хост отвечает подтверждением на нулевой пакет и продолжает процесс енумерации, если требовал дескриптор ----- он считает, что получил дескриптор, просто тот нулевой.

3. зачем вообще нужно два раза отправлять дескриптор? ----- первый раз дескриптор отправляется для того, чтобы хост выделил область памяти в соответствии с тем размером, который я ему задаю в 8-ом байте дескриптора. У меня изначально было 0x08, поменял на 0x40 и при подключении к компьютеру вижу свой дескриптор в usbview.

 

"4. After receiving the first 8 bytes of the Device Descriptor, it immediately issues another bus reset."

На самом деле, не совсем так. Reset приходит не сразу, а по окончании транзакции - проверено на осциллографе и логами от vmp.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
"4. After receiving the first 8 bytes of the Device Descriptor, it immediately issues another bus reset."

На самом деле, не совсем так. Reset приходит не сразу, а по окончании транзакции - проверено на осциллографе и логами от vmp.

 

Совершенно верно.

Хост анализирует первые 8 байт, чтобы определить размер пакета для EP0, и транзакция состоит из одного пакета. (Минимальный размер пакета 8 байт).

Изменено пользователем Седой

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо большое vmp (Дата Nov 21 2007, 14:33) за лог, очень помогло.

возникли вопросики касательно некоторых моментов:

1. касательно фрагмента

______________________________________________________________________________

Container title<GetDescriptor (Configuration)> device<1> endpoint<0>

status<OK> speed<HS> time<4.408 958 750>

Transaction type<SETUP> device<1> endpoint<0> status<ACK> speed<HS>

time<4.408 958 750>

Packet id<SETUP> devAddr<1> epNum<0> crc5<0x1D> speed<HS>

time<4.408 958 750>

Packet id<DATA0> length<8> data<80 06 00 02 00 00 FF 00> crc16<0xA4E9>

speed<HS> time<4.408 959 083>

Packet id<ACK> speed<HS> time<4.408 959 567>

ConsecutiveTransaction count<216> type<IN> device<1> endpoint<0>

status<NAK> speed<HS> time<4.408 963 050>

Transaction type<IN> device<1> endpoint<0> status<ACK> speed<HS>

time<4.409 551 517>

Packet id<IN> devAddr<1> epNum<0> crc5<0x1D> speed<HS> time<4.409

551 517>

Packet id<DATA1> length<32> data<09 02 20 00 01 01 00 80 64 09 04 00

00 02 08 06 50 00 07 05 81 02 00 02 00 07 05 02 02 00 02 00>

crc16<0x434A> speed<HS> time<4.409 551 833>

Packet id<ACK> speed<HS> time<4.409 552 883>

Transaction type<OUT> device<1> endpoint<0> status<ACK> speed<HS>

time<4.409 555 850>

Packet id<OUT> devAddr<1> epNum<0> crc5<0x1D> speed<HS> time<4.409

555 850>

Packet id<DATA1> length<0> crc16<0x0000> speed<HS> time<4.409 556 167>

Packet id<ACK> speed<HS> time<4.409 556 500>

______________________________________________________________________________

 

как я понимаю, осуществляется запрос на дескриптор конфигурации, длина которого составляет 9байт судя по документации. до этого приходил аналогичный запрос на длину 9байт (и они были отправлены - все согласно штатному расписанию усб), а теперь он снова пришел, но уже ожидается 256 байт.

(1-й вопрос: почему отправляется повторный запрос 80 06 00 02 00 00 FF 00 и каков формат ответа на него)

 

2. также непонятно, почему на запрос 9-байтного дескриптора отправляется ответ не 9 байт, а 32 (!). я смотрел исходники на ИАРе и там тоже почему-то этот дескриптор был МАЛО ТОГО что длинее 9байт, да еще и имел в своем составе другие дескрипторы:

#pragma data_alignment=4

const Int8U UsbStandardConfigurationDescriptor[] =

{

sizeof(UsbStandardConfigurationDescriptor_t),

UsbDescriptorConfiguration,

(1*sizeof(UsbStandardConfigurationDescriptor_t)+

1*sizeof(UsbStandardInterfaceDescriptor_t)+

2*sizeof(UsbStandardEpDescriptor_t)),

(1*sizeof(UsbStandardConfigurationDescriptor_t)+

1*sizeof(UsbStandardInterfaceDescriptor_t)+

2*sizeof(UsbStandardEpDescriptor_t)) >> 8,

1,

1,

0,

UsbConfigurationCommmonAttr,

UsbConfigPower_mA(100),

sizeof(UsbStandardInterfaceDescriptor_t),

UsbDescriptorInterface,

0,

0,

2,

UsbDeviceClassStorage,

MscSubClassScsi,

MscProtocolBulkOnly,

0,

sizeof(UsbStandardEpDescriptor_t),

UsbDescriptorEp,

UsbEpIn(BulkInEp>>1),

UsbEpTransferBulk,

BulkInEpMaxSize,

BulkInEpMaxSize>>8,

0,

sizeof(UsbStandardEpDescriptor_t),

UsbDescriptorEp,

UsbEpOut(BulkOutEp>>1),

UsbEpTransferBulk,

BulkOutEpMaxSize,

BulkOutEpMaxSize>>8,

0,

0,

};

 

============ но простите, UsbStandardInterfaceDescriptor и UsbStandardEpDescriptor должны по идее отправляться на запросы типа 80 06 00 04 .... и на 80 06 00 05

в ОБЩЕМ НЕПОНЯТНО (((

 

2-й вопрос: почему UsbStandardInterfaceDescriptor и UsbStandardEpDescriptor выдаются на запрос UsbStandardConfigurationDescriptor а не на свои индивидуальные?

 

3. в моей программе выдаются ответы на запросы, согласно логу энумерации флешки (на XPsp1 на high speed) и до приведеного выше момента (включительно) они совпадают. но после этого вместо запроса

Packet id<DATA0> length<8> data<80 06 00 03 00 00 FF 00>

у меня появляется запрос <80 06 00 06 00 00 0a 00> на уточняющий дескриптор устройства....

3-й вопрос: что мне ответить на запрос <80 06 00 06 00 00 0a 00>?

заранее благодарю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
============ но простите, UsbStandardInterfaceDescriptor и UsbStandardEpDescriptor должны по идее отправляться на запросы типа 80 06 00 04 .... и на 80 06 00 05

в ОБЩЕМ НЕПОНЯТНО (((

Таких запросов в USB не бывает.

2-й вопрос: почему UsbStandardInterfaceDescriptor и UsbStandardEpDescriptor выдаются на запрос UsbStandardConfigurationDescriptor а не на свои индивидуальные?

См. выше. full speed режим имеет запросы DEVICE=1, CONFIGURATION=2, STRING=3 и всё. Поэтому обычно CONFIGURATION сначала 4 байта запрашивают чтоб общую длину узнать (она в 3..4 байтах), а потом с этой длиной запрос делают.( В W98 не так было. Там сразу > килобайта запрашивали. А в вашем случае почему то FF запрашивает, что ОЧЕНЬ странно.) Это чтоб все дескрипторы всех интерфейсов, EP, классов (HID, MassStorage и т.п.), присоединённые дескрипторы и т.д. и т.д. получить. А в high speed ещё запрос =6 добавляется.

3. в моей программе выдаются ответы на запросы, согласно логу энумерации флешки (на XPsp1 на high speed) и до приведеного выше момента (включительно) они совпадают. но после этого вместо запроса

Packet id<DATA0> length<8> data<80 06 00 03 00 00 FF 00>

Это запрос стринга. В смысле на каком языке у вас стринги написаны. Хотя тоже длина =FF почему то??? Раз его не запросил - до этого что то не поняли.

у меня появляется запрос <80 06 00 06 00 00 0a 00> на уточняющий дескриптор устройства....

3-й вопрос: что мне ответить на запрос <80 06 00 06 00 00 0a 00>?

заранее благодарю.

Это high speed запрос. Рекомендую сначала в режиме full speed работы добится. А high speed уж потом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

galjoen, благодарю за ответ.

еще вопросик появился. мое устройство сейчас выдает ответы на первые стандартные запросы, согласно логу энумерации флешки, приведеному во втором посте этой ветки. в общем после этого РС видит девайс как ЗАПОМИНАЮЩЕЕ УСТРОЙСТВО ДЛЯ USB.

ответы на запросы давались следующие (после того как устройство было адресовано):

 

Reciver request 80 06 00 02 00 00 09 00 (standart configuration descriptor)

// Prepare to respond <09 02 12 00 01 01 00 80 64>

 

Reciver request 80 06 00 03 00 00 ff 00(<GetDescriptor (String lang IDs)>)

// Prepare to respond <04 03 09 04>

 

Reciver request 80 06 03 03 09 04 ff 00<GetDescriptor (String iSerialNumber)>

// Prepare to respond <1A 03 31 00 39 00 36 00 42 00 30 00 41 00 30 00 30 00 30 00 39 00 36 00 36 00>

 

Reciver request 80 06 00 02 00 00 ff 00 GetDescriptor (Configuration)

// Prepare to respond <09 02 20(12) 00 01 01 00 80 64 09 04 00 00 02(00) 08 06 50 00

 

вопрос - где и что в ответах на запросы нужно поменять, чтоб РС увидел девайс не ЗАПОМИНАЮЩИМ УСТРОЙСТВОМ ДЛЯ USB, а чем либо другим (например джойстиком)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Reciver request 80 06 00 02 00 00 09 00 (standart configuration descriptor)

// Prepare to respond <09 02 12 00 01 01 00 80 64>

Вот здесь почему-то не всё запрошено. Общая длина 0x12, а запрошено всего 9 байт. И дескриптора Mass Storage интерфейса из-за этого не видно.

Reciver request 80 06 00 02 00 00 ff 00 GetDescriptor (Configuration)

// Prepare to respond <09 02 20(12) 00 01 01 00 80 64 09 04 00 00 02(00) 08 06 50 00

Вот теперь всё запросили вместе с дескриптором интерфейса Mass Storage. Но что-то длина запроса странная 0xFF. К этому моменту ведь известно, что общая длина 0x12 (или 0x20 что-то я не понял). Это вы под какой ОС проверяете? Или там хаб у вас какой нибудь чудит.

вопрос - где и что в ответах на запросы нужно поменять, чтоб РС увидел девайс не ЗАПОМИНАЮЩИМ УСТРОЙСТВОМ ДЛЯ USB, а чем либо другим (например джойстиком)?

В дескрипторе конфигурации нужно вместо/совместно с дескриптором интерфейса Mass Storage описать интерфейс HID. А в HID-овских УСАГАХ описать, что это у вас джойстик.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
....В дескрипторе конфигурации нужно вместо/совместно с дескриптором интерфейса Mass Storage описать интерфейс HID. А в HID-овских УСАГАХ описать, что это у вас джойстик.

это сделать в каких полях дескриптора USB_CONFIGURATION_DESCRIPTOR_TYPE?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
это сделать в каких полях дескриптора USB_CONFIGURATION_DESCRIPTOR_TYPE?

Если у вас 2 интерфейса будет (составное устройство Mass Storage + HID), то надо в поле bNumInterfaces 2 поставить. Дескриптор Mass Storage интерфейса у вас уже есть. Он должен ОБЯЗАТЕЛЬНО 1м идти (виндоусовский глюк). За ним дескрипторы EP (2шт.), относящихся к Mass Storage. В дескрипторе HID интерфейса bInterfaceClass д.б. 3=HID. В bInterfaceSubClass вроде 1=джойстик, но не уверен. У меня там 0 (не джойстик и не клавиатура), а разбираться щас некогда. Ну и т.д. и т.д.

А вообще рекомендую на usb.org сходить. Там всё про дескрипторы найдёте. Повозится конечно придётся т.к. все запутано.

 

А вот насчёт длины в запросах =FF - поясните пожалуиста. Я с таким никогда не сталкивался - интересно. Вы через хаб работаете? А под какой ОС?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация