Usb руководство устройство

В этой статье мастер-электрик ChatGPT объяснит, как правильно распиновать USB. Распиновка USB является важной технической деталью, которую необходимо понимать для корректной работы устройств. Для начала, следует отметить, что USB имеет несколько разновидностей, таких как USB-A, USB-B, USB-C, и каждый тип имеет свои особенности и требования к распиновке.

Содержание

Основные типы разъемов USB

USB (Universal Serial Bus) — это стандартный интерфейс для подключения различных устройств к компьютеру или другому оборудованию. Существует несколько типов разъемов USB, каждый из которых имеет свои особенности:

  1. USB Type-A — наиболее распространенный тип разъема, который часто используется для подключения периферийных устройств, таких как мыши, клавиатуры, флэш-накопители и т.д.
  2. USB Type-B — этот тип разъема используется в основном для подключения принтеров, сканеров и других устройств с низкой скоростью передачи данных.
  3. USB Type-C — это новый стандарт разъема, который имеет множество преимуществ перед предыдущими типами, включая более высокую скорость передачи данных, поддержку быстрой зарядки и возможность подключения к любой стороне.

Независимо от типа разъема, правильная распиновка USB является ключевым фактором для обеспечения правильной работы устройств и передачи данных.

Назначение каждого пина

Каждый тип разъема USB имеет свою схему распиновки, которая определяет назначение каждого контакта. Приведем подробные сведения о том, для чего предназначен каждый пин:

Разъем USB Type-A

  • VBUS (+5 В) — напряжение питания, постоянно подключено к источнику питания.
  • D- и D+ — два сигнальных контакта, используемых для передачи данных.
  • GND — заземление, используемое для снижения уровня шума и помех.

USB Type-B

  • VBUS (+5 В) — напряжение питания, постоянно подключено к источнику питания.
  • D- и D+ — два сигнальных контакта, используемых для передачи данных.
  • GND — заземление, используемое для снижения уровня шума и помех.

Разъем USB Type-C

  • VBUS (+5 В) — напряжение питания, постоянно подключено к источнику питания.
  • D- и D+ — два сигнальных контакта, используемых для передачи данных.
  • CC1 и CC2 — два контакта, используемых для определения типа подключенного устройства и поддержки быстрой зарядки.
  • SBU1 и SBU2 — контакты, используемые для передачи аналоговых сигналов, таких как звук.

Что такое USB-хабы?

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

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

Как правильно подключить USB-хаб

Правильное подключение USB-хаба может сэкономить время и упростить работу с несколькими устройствами. Однако неправильное подключение может привести к проблемам с работой устройств и даже к их повреждению. Ниже приведены подробные инструкции о том, как правильно подключить USB-хаб.

Проверка хаба

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

Подключение к компьютеру

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

Подключение устройств

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

Проверка подключения

После подключения всех устройств, проверьте, работают ли они корректно. Если устройства не работают, убедитесь, что они правильно подключены к портам на хабе. Если проблема остается, попробуйте подключить устройства непосредственно к компьютеру, чтобы проверить, работают ли они корректно.

Распиновка USB-C разъема

USB Type-C — это новый стандарт разъема, который имеет более высокую скорость передачи данных и поддерживает быструю зарядку. Следуйте инструкции по распиновке USB Type-C разъема:

  1. Определите на вашем разъеме контакты VBUS, GND, D-, D+, CC1, CC2, SBU1 и SBU2.
  2. Подключите VBUS (+5 В) к источнику питания, чтобы обеспечить питание для подключенных устройств.
  3. Подключите GND к заземлению, чтобы снизить уровень шума и помех.
  4. Подключите D- и D+ к устройству, с которым вы хотите передавать данные. Обычно они используются для передачи данных между компьютером и устройством, таким как телефон или флэш-накопитель.
  5. Подключите CC1 и CC2 к соответствующим контактам на устройстве, чтобы определить тип подключенного устройства и поддерживать быструю зарядку.
  6. Подключите SBU1 и SBU2 к аналоговым контактам на устройстве, если это необходимо для передачи аналоговых сигналов, например, звука.
  7. Проверьте, что все подключения выполнены правильно, и что устройство работает корректно.

Распиновка USB Type-C разъема может различаться в зависимости от производителя и модели устройства. Перед подключением устройства к USB Type-C разъему, всегда проверяйте схему распиновки и инструкции производителя.

Распиновка USB-A разъема

Распиновка USB Type-A разъема является важным фактором для обеспечения правильной работы устройств и передачи данных. Ниже приведем подробные инструкции о том, для чего предназначен каждый контакт USB Type-A разъема.

Контакт VBUS (+5 В)

  • Этот контакт обеспечивает напряжение питания (+5 В) для подключенных устройств.
  • VBUS подключается к источнику питания и должен быть постоянно подключен для правильной работы устройств.

Контакты D- и D+

  • D- и D+ являются сигнальными контактами, используемыми для передачи данных между устройствами.
  • Контакт D- используется для передачи сигнала данных от устройства к компьютеру, а контакт D+ — для передачи сигнала данных от компьютера к устройству.

Контакт GND

  • Контакт GND используется для заземления и снижения уровня шума и помех.
  • Он должен подключаться к заземлению для обеспечения правильной работы устройств.

Распиновка USB Type-A разъема является стандартной, однако некоторые производители могут использовать другие схемы распиновки. Перед подключением устройства к USB Type-A разъему, всегда проверяйте схему распиновки и инструкции производителя.

Распиновка USB-B разъема

USB Type-B — это тип разъема USB, который обычно используется для подключения принтеров, сканеров и других устройств к компьютеру. Ниже приведем инструкция по распиновке USB Type-B разъема:

  1. Определите на вашем разъеме контакты VBUS, GND, D- и D+.
  2. Подключите VBUS (+5 В) к источнику питания, чтобы обеспечить питание для подключенных устройств.
  3. Подключите GND к заземлению, чтобы снизить уровень шума и помех.
  4. Подключите D- и D+ к устройству, с которым вы хотите передавать данные. Обычно они используются для передачи данных между компьютером и устройством, таким как принтер или сканер.
  5. Проверьте, что все подключения вы выполнили правильно, и что устройство работает корректно.

Распиновка Mini-USB разъема

Mini-USB — тип разъема USB, который ранее использовался для подключения различных устройств, таких как фотокамеры, мобильные телефоны и другие устройства. Ниже приведем подробные инструкции о том, для чего предназначен каждый контакт Mini-USB разъема:

Контакт VBUS (+5 В)

  • Этот контакт обеспечивает напряжение питания (+5 В) для подключенных устройств.
  • VBUS подключается к источнику питания и должен быть постоянно подключен для правильной работы устройств.

Контакты D- и D+

  • D- и D+ являются сигнальными контактами, используемыми для передачи данных между устройствами.
  • Контакт D- используется для передачи сигнала данных от устройства к компьютеру, а контакт D+ — для передачи сигнала данных от компьютера к устройству.

Контакт GND

  • Контакт GND используется для заземления и снижения уровня шума и помех.
  • Он должен подключаться к заземлению для обеспечения правильной работы устройств.

Контакт ID

  • Контакт ID используют для определения типа устройства, которое подключается к разъему.
  • Он может подключаться к контакту земли или оставаться неподключенным в зависимости от типа устройства.

Важно отметить, что Mini-USB разъем сейчас устарел и не рекомендуется для использования.

Распиновка Micro-USB разъема

Micro-USB — это тип разъема USB, который используется в большинстве современных мобильных устройств, таких как смартфоны и планшеты. Ниже приведем инструкцию по распиновке Micro-USB разъема:

  1. Определите на вашем разъеме контакты VBUS, GND, D- и D+.
  2. Подключите VBUS (+5 В) к источнику питания, чтобы обеспечить питание для подключенных устройств.
  3. Подключите GND к заземлению, чтобы снизить уровень шума и помех.
  4. Подключите D- и D+ к устройству, с которым вы хотите передавать данные. Обычно они используются для передачи данных между компьютером и устройством, таким как смартфон или планшет.
  5. Проверьте, что все подключения выполнились правильно, и что устройство работает корректно.

Распиновка Micro-USB разъема является стандартной, однако некоторые производители могут использовать другие схемы распиновки. Перед подключением устройства к Micro-USB разъему всегда проверяйте схему распиновки и инструкции производителя.

USB-разъемы являются неотъемлемой частью современных устройств и используются для подключения к компьютерам и другим устройствам. Распиновка USB-разъемов определяет порядок подключения контактов и является важным фактором для обеспечения правильной работы устройств и передачи данных.

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

Схемы распиновки USB

Об авторе: Эксперт в области ремонта и отделки

Задать вопрос

В двух предыдущих статьях мы сделали USB 3.0 систему на базе контроллера FX3. Пришла пора научиться работать с нею из своих программ для PC. Ну, и попутно понять, насколько получившаяся система пригодна для практического применения. Действительно ли ширины канала хватает на весь поток? И не теряются ли единичные байты из потока? Кто хоть немного поработал тестировщиком, не поверит в то, что если система в принципе работает, значит, работает и в деталях. А я на этой должности проработал лет пять, не меньше, поэтому привык проверять всё на практике. В общем, приступаем.

1.1 Windows

Когда новое, доселе неизвестное системе USB-устройство впервые вставлено в ЭВМ, работающую под управлением Windows, оно отображается в диспетчере устройств с жёлтым знаком вопроса. Это связано с тем, что Windows обязательно нужен драйвер для работы с ним. Давайте я немного порассуждаю про эти драйверы, но не с научной точки зрения, а как инженер, раскрыв чисто практические аспекты, но несколько упростив теорию. Потому что мне не нужно, чтобы все уснули. Мне нужно, чтобы суть была понятна, так что ряд скучных деталей придётся опустить.

1.1.1 Драйверы, работающие на функциональном уровне

Что такое USB-устройство? Это набор конечных точек. Но прикладному программисту, если честно, эти точки не интересны. Давным-давно, ещё в прошлом тысячелетии, когда последовательные порты делались на микросхеме UART16550, под неё был сделан функциональный драйвер для Windows, и все прикладные программисты привыкли работать с абстракциями именно этого драйвера. И с этой привычкой трудно спорить. Представим на минутку, что с переходником USB-COM придётся работать в USB-шном стиле, на уровне конечных точек. Есть идеология CDC: две конечных точки туда-обратно, одна точка статуса в режиме прерываний и определённый набор команд, подаваемых через конечную точку EP0. Это всё описано в стандартах, относящихся к USB.

Всё? Нет, некоторым этого мало! Prolific сделала свой набор команд для точки EP0, не совместимый с CDC. А FTDI – свой. Он не совместим ни с CDC, ни с Prolific. Так что, если бы прикладной программист работал бы с переходниками USB-COM на уровне конечных точек, ему пришлось бы нелегко. К счастью, Prolific и FTDI предоставляют функциональные драйверы для своих чипов, а для CDC функциональный драйвер разработала сама Microsoft и прилагает его в составе Windows. Поэтому прикладной программист понятия не имеет, как работать с конкретным переходником (помню, мы целый NDA лет 15 назад с FTDI подписывали, чтобы получить от них руководство по их командам, причём я сразу же им послал информацию об ошибке в документе, так как пока работали бюрократы, я через дизассемблер всё сам уже успел изучить, так что сразу нашёл несовпадение их описания с моим). На прикладном уровне драйверы всех упомянутых производителей дают интерфейс такой же, как и при работе со старым добрым UART16550.

То же касается и USB-накопителей. Мало кто знает, что физически там две конечных точки. Почти никому не интересно, как там надо гонять пакеты, чтобы посылать команды и данные. Как разруливать ошибки, знает ещё меньше людей. Все работают через драйвер usbstor.sys, предоставляемый Microsoft, который обеспечивает работу точно так же, как и с дисками, подключёнными через локальную шину материнской платы.
Удобно? Однозначно! Но вот мы сделали своё устройство, не совместимое по логике работы ни с каким из стандартных. И что нам теперь, всенепременно писать для него персональный драйвер?

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

1.1.2 CyUSB

С этим драйвером я познакомился раньше других. Было это 12 лет назад. Вот с него и начну рассказ. Правда, скажу лишь вскользь. Фирма Cypress, выпуская замечательные контроллеры FX2LP, просто обязана была сделать драйвер, работающий на уровне конечных точек, чтобы облегчить жизнь своим клиентам. И она его сделала. Кому интересно – ищите по слову CyAPI. Это DLL-ка, предоставляющая ряд функций для прикладного программиста. Я как системщик старался обойтись без DLL, поэтому сделал себе библиотеку, работающую с драйвером на уровне IOCTL запросов.

Главный недостаток данной библиотеки заключается в её лицензионном соглашении. Её можно использовать только с контроллерами Cypress. А чтобы всё было убедительнее, начиная с некоторых версий, драйвер стал просто зависать, если он работает с контроллерами других производителей. По крайней мере, старые версии с AT90USB работали, а более свежие – нет. Поэтому я решил, что не буду пользоваться данным драйвером. Даже написал свой… Но вскоре обнаружился замечательный готовый вариант от Microsoft, и я перешёл на него.

1.1.3 WinUSB

Этот драйвер уходит своими корнями в инфраструктуру UMDF. Когда фирма Microsoft работала над возможностью запускать драйверы на пользовательском уровне защиты, они сделали специальный драйвер-прослойку WinUSB. Но через этот же драйвер можно работать и из обычных прикладных программ, а не только из UMDF-драйверов. Кому интересно – вбейте в поиск WinUSB API. Через эту функциональность можно делать то же самое, что и через CyUSB, но с контроллерами любых производителей.

Сам драйвер входит в состав Windows, поэтому в Win7 его можно было вообще ставить без каких-либо проблем с подписыванием. Можно было создать по инструкции от Microsoft или найти и скачать готовый inf файл, поменять в нём VID/PID на свои и установить. К сожалению, начиная с WIN8, обязательно надо подписывать не только сам драйвер, но и INF файл. Однако никто не мешает поправить VID/PID у устройства на тот, который будет найден. Вот у меня есть вот такой подписанный inf файл.

Посмотреть inf файл

;
; Android WinUsb driver installation.
;
[Version]
Signature           = "$Windows NT$"
Class               = AndroidUsbDeviceClass
ClassGuid           = {3F966BD9-FA04-4ec5-991C-D326973B5128}
Provider            = %ProviderName%
DriverVer           = 06/06/2017,2.0.0010.00003
CatalogFile.NTx86   = MT16_x86.cat
CatalogFile.NTamd64 = MT16_x64.cat

;
; This section seems to be required for WinUsb driver installation.
; If this section is removed the installer will report an error
; "Required section not found in INF file".
;
[ClassInstall32]
Addreg = AndroidWinUsbClassReg

[AndroidWinUsbClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,"-26"

[Manufacturer]
%ProviderName% = Google, NTx86, NTamd64

[Google.NTx86]
%CompositeAdbInterface1%     = USB_Install, USBVID_1234&PID_0001
%CompositeAdbInterface2%     = USB_Install, USBVID_1234&PID_0002
%CompositeAdbInterface3%     = USB_Install, USBVID_1234&PID_0003
%CompositeAdbInterface5%     = USB_Install, USBVID_1234&PID_0005
%OldBox%     		     = USB_Install, USBVID_4844&PID_8816
%HIDkey%     		     = USB_Install, USBVID_A1A2&PID_2001

[Google.NTamd64]
%CompositeAdbInterface1%     = USB_Install, USBVID_1234&PID_0001
%CompositeAdbInterface2%     = USB_Install, USBVID_1234&PID_0002
%CompositeAdbInterface3%     = USB_Install, USBVID_1234&PID_0003
%CompositeAdbInterface5%     = USB_Install, USBVID_1234&PID_0005
%OldBox%     		     = USB_Install, USBVID_4844&PID_8816
%HIDkey%     		     = USB_Install, USBVID_A1A2&PID_2001

[USB_Install]
Include = winusb.inf
Needs   = WINUSB.NT

[USB_Install.Services]
Include     = winusb.inf
AddService  = WinUSB,0x00000002,WinUSB_ServiceInstall

[WinUSB_ServiceInstall]
DisplayName     = %WinUSB_SvcDesc%
ServiceType     = 1
StartType       = 3
ErrorControl    = 1
ServiceBinary   = %12%WinUSB.sys

[USB_Install.Wdf]
KmdfService = WINUSB, WinUSB_Install

[WinUSB_Install]
KmdfLibraryVersion  = 1.7

[USB_Install.HW]
AddReg  = Dev_AddReg

[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,"{F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}"

[USB_Install.CoInstallers]
AddReg    = CoInstallers_AddReg
CopyFiles = CoInstallers_CopyFiles

[CoInstallers_AddReg]
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUSBCoInstaller2.dll"

[CoInstallers_CopyFiles]
WinUSBCoInstaller2.dll
WdfCoInstaller01009.dll

[DestinationDirs]
CoInstallers_CopyFiles=11

[SourceDisksNames]
1 = %DISK_NAME%,,,i386
2 = %DISK_NAME%,,,amd64

[SourceDisksFiles.x86]
WinUSBCoInstaller2.dll  = 1
WdfCoInstaller01009.dll = 1

[SourceDisksFiles.amd64]
WinUSBCoInstaller2.dll  = 2
WdfCoInstaller01009.dll = 2

[Strings]
ProviderName                = "GM Software"
CompositeAdbInterface1      = "MT16 Device"
CompositeAdbInterface2      = "MT16 Ports 1-5"
CompositeAdbInterface3      = "MT16 Ports 12-16"
CompositeAdbInterface5      = "TBR Flasher"
OldBox      		    = "Old MT16 Box"
HIDkey      		    = "HID Dongle via WinUSB"
WinUSB_SvcDesc              = "MT16 COM Ports"
DISK_NAME                   = "MT16 Driver Installation Directory"
ClassName                   = "MT16 USB Devices"

Раньше таких inf файлов на просторах сети было много. Андроид-телефоны через них подключались. Сейчас надо искать по слову WinUSB.sys внутри. Ну, или «ServiceBinary = %12%WinUSB.sys».

Я поправил «Прошивку» для FX3 вот так:

То же самое текстом.

const uint8_t CyFxUSB30DeviceDscr[] __attribute__ ((aligned (32))) =
{
    0x12,                           /* Descriptor size */
    CY_U3P_USB_DEVICE_DESCR,        /* Device descriptor type */
    0x00,0x03,                      /* USB 3.0 */
    0x00,                           /* Device class */
    0x00,                           /* Device sub-class */
    0x00,                           /* Device protocol */
    0x09,                           /* Maxpacket size for EP0 : 2^9 */
#ifdef CY_VID_PID
    0xB4,0x04,                      /* Vendor ID */
    0xF1,0x00,                      /* Product ID */
#else
    0x34,0x12,                      /* Vendor ID */
    0x05,0x00,                      /* Product ID */
#endif
…

И теперь могу собирать варианты хоть под CyUSB, хоть под WinUSB с привязкой к имеющемуся у меня inf файлу. А так — можно перевести ОС в режим, не требующий подписывания драйверов, хоть это и не очень удобно.

1.1.4 Библиотека libusb

Вариант с WinUSB отличный, но не кроссплатформенный. Насколько мне известно, под Linux нет точно такого же API, который предоставляет Microsoft для Windows. Кроссплатформенный вариант – это использование библиотеки libusb. Причём под Windows эта библиотека по умолчанию опирается на всё тот же драйвер WinUSB. Нашли драйвер, накатили его на устройство. Скачали библиотеку, начали через неё работать с этим драйвером. Надо будет – через неё же можно будет работать и под Linux. Замечательно? Да. Особенно если мы разработали полностью своё устройство. Но, увы, я просто обязан указать недостаток данного метода для общего случая.

Когда мы устанавливаем на устройство драйвер WinUSB, мы убираем оригинальный драйвер. В рамках данного блока статей мы теряем возможность общаться с нашим устройством при помощи утилиты ControlCenter. Ну, и я не упоминал в статьях про утилиту Streamer, позволяющую измерять скорость устройства… В общем, ею мы тоже не сможем пользоваться, если заменим штатный драйвер на WinUSB.

В рамках другой задачи мне надо было экспериментировать с аудиоустройствами из своего приложения. При этом я не хотел постигать все тонкости работы с ними. Я хотел только некоторые команды подавать, а чтобы всё остальное за меня делала сама операционка. Но если бы я посадил устройства на WinUSB, ОС бы потеряла контроль над ними и не могла бы оказывать мне всемерное содействие.

Можно ли работать из прикладной программы с устройствами, не пересаживая их на специальный драйвер? В принципе, да (правда, это очень аккуратное утверждение). Давайте я покажу этот метод… Правда, в конце — сильно раскритикую его.

1.1.5 Драйвер UsbDk

Библиотека libusb существует в двух версиях. Версия 0.1 и версия 1.0. Обе версии в настоящее время развиваются, создавая некоторую путаницу. И вот версия 1.0 может работать не только через драйвер WinUSB, но и через драйвер UsbDk. Последний является фильтр-драйвером. Что такое фильтр-драйверы? Вспоминаем детство, сказку о царе Салтане:

Собственно, фильтр-драйвер встаёт на пути IRP-пакетов от прикладной программы к основному драйверу и обратно. IRP — это гонцы, которые бегают туда-сюда. А фильтр-драйвер может их пропустить, не изменяя, а может подменить их содержимое. Он придуман для исправления ошибок, чтобы не менять основной драйвер, а просто немножко подправить пакеты, дабы те не вызывали проблем. Их можно править на прямом и на обратном пути. Но в целом, никто не мешает через этот фильтр-драйвер запустить в основной драйвер запросы от приложения, которое общается именно с фильтром. И UsbDk этим и занимается.

Очень схематично, опустив ряд неважных подробностей, это можно показать так:

Вот тут мы видим, что фильтр-драйвер UsbDK подсел на пути пакетов к нашему устройству (на самом деле, он подсел на пути ко всем USB-устройствам, так как прицепился к драйверу класса USB):

Если при открытии библиотеки libusb 1.0 сказать:

    libusb_init(&m_ctx);
    libusb_set_option(m_ctx, LIBUSB_OPTION_USE_USBDK);

то она будет использовать в качестве основы не WinUSB, а UsbDk. Ура? Не совсем. Приведу минимум две проблемы, создаваемые при использовании данного пути.

Первая проблема организационная. Если мы запустили программу, поработали, вышли, то всё будет хорошо. Но вот мы запустили программу, начали работать, а потом почему-то прервались. Да хоть у меня стояла точка останова, исполнение прервалось, я осмотрел переменные, увидел, что программа работает неверно, и завершил её. Могу я так сделать? Дело-то житейское при разработке программы. Или просто зациклилась она. В общем, мы её прервали. Снова запускаем – устройство уже не открывается. Смотрим код ошибки – он очень интересный.

Driver file operation error. DeviceIoControl failed (Cannot create a file when that file already exists.  Error code = 183)
Cannot Open USB Device

И всё. Выдёргивать-вставлять USB-кабель – бесполезно. Только полная перезагрузка Windows спасёт Отца Русской Демократии. Когда перезапускаешься третий-четвёртый раз за час – это начинает несколько раздражать. Поиск в сети не дал никаких результатов. Попытка бегло осмотреть исходники UsbDk – тоже, а на детальные разбирательства нет времени. Может, кто в комментариях чего подскажет…

Но на самом деле, эта проблема раздражает, но не является фатальной. Вторая проблема более серьёзная. Вот я поставил VirtualBox. Я просто запустил виртуальную машину и хочу подключить к ней, скажем, бластер. И что получаю?

Аналогично – любое другое устройство.

Поиск по сети даёт много вариантов типа: «У меня всё заработало после того, как я потёр заячьей лапкой по бубну из кожи тушканчика, спрыснутому кровью семидесятидвухлетней девственницы, полученной…» … Что там дальше в рецепте — сейчас уже не помню… Тем более, мне он не помог… Более осмысленные рекомендации требуют сносить фильтр-драйверы USB, пока не полегчает. Проблема уходит, когда сносишь именно UsbDK. Ну, значится, так тому и быть. Хотя для экспериментов с аудио, других приемлемых вариантов я не нашёл. Так что драйвер я снёс, но дистрибутив – оставил. Пригодится. Именно поэтому описываю эту методику. Ну, и вдруг кто в комментариях подскажет, как обходить эти две проблемы. Тогда станет совсем здорово.

1.1.6 Итого

Итого, сегодня мы будем работать через библиотеку libusb, посадив устройство на драйвер WinUSB. Да, мы потеряем возможность работать с устройством через стандартные приложения от Cypress. Зато всё будет стабильно и хорошо.

1.2 Linux

1.2.1 Драйвер

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

Некоторые устройства уже поддержаны в Линуксе по классу, либо по VID/PID. Вот, скажем, я подключил макетную плату ICE40 с ПЛИС Latice и подал сначала команду lsusb, чтобы увидеть USB устройства, а затем – уже полюбившуюся нам по прошлым статьям команду:
ls –l /dev/serial/by-path, чтобы увидеть, что мост фирмы FTDI сам прикинулся двумя последовательными портами.

С такими устройствами, если ничего не предпринимать, можно работать только на функциональном уровне. Однако, если функциональный драйвер не подключился, как уверяет начальник, в отличие от Windows такие устройства не станут неизвестными (а потому недоступными). Напротив, с ними можно сразу и без какой-либо подготовки работать через библиотеку libusb. А разработанное нами устройство относится к таковым. Поэтому никакой подготовки для начала работы не требуется. Надеюсь, начальник меня не обманул.

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

1.2.2 Отключение требований прав администратора при работе с USB-устройствами

Главная особенность USB-устройств в Linux состоит в том, что по умолчанию для доступа к ним надо обладать правами администратора. То есть, для сборки «прошивки» для ПЛИС ICE40 (к теме статьи они не относятся, но по проекту я сейчас их осваиваю, причём под Linux, так что скриншоты готовить проще для них) мне достаточно набрать make, а вот если для «прошивки» я наберу make prog, то получу такое сообщение:

Не хватает прав. Надо набирать sudo make prog.

Чтобы понизить требуемые права, надо прописать правила. А чтобы быстро выяснить, как их прописать, я обычно даю такой запрос Гуглю:

Usb blaster Linux

Ссылок будет много, все они разной степени шаманства. Вот более-менее подробная ссылка:
Using USB Blaster / USB Blaster II under Linux | Documentation | RocketBoards.org

Что сразу бросается в глаза: имена файлов с правилами для Debian и для Ubuntu разные.
/etc/udev/rules.d/92-usbblaster.rules и /etc/udev/rules.d/51-usbblaster.rules, соответственно.

Всё тот же начальник, а по совместительству – любитель Линукса, объяснил, что если в нескольких файлах есть правила для одного и того же устройства, число задаёт приоритет разбора файлов. Собственно, документ также говорит, что число 92 базируется на том, что в системе имеется файл /lib/udev/rules.d/91-permissions.rules.

Вообще, мне стало интересно, и я вбил в Гугля строку поиска
/etc/udev/rules.d/

Он нашёл мне много статей про udev. Некоторые более теоретические. Некоторые слишком практические. Пересказывать их не вижу смысла. При желании вы можете погуглить сами. Дам только ссылку на статью, которая мне кажется хорошо сбалансированной по теории и практике:
Igorka: Знакомство с udev в ubuntu

Итак. Иду в каталог /etc/udev/rules.d. Вижу файл 70-snap.snapd.rules, в котором есть правило, относящееся ко всем FTDI чипам:

FTDI-based serial adapters:

#   FTDI does USB to serial converter ICs; and it's very likely that they'll
#   never do modems themselves, so it should be safe to add a rule only based
#   on the vendor Id.
ATTRS{idVendor}=="0403", ENV{ID_MM_DEVICE_MANUAL_SCAN_ONLY}="1"

Не понимая до конца, что творю, запускаю не просто mc, а sudo mc и в его редакторе создаю файл /etc/udev/rules.d /71-ice40.rules со следующим содержимым:

#FTDI Programmer for latice
SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0666"

Закрываю терминал с админскими правами, открываю новый, с правами обычными. Отключаю-включаю устройство, и… Вуаля! Оно уже доступно без прав администратора!

Поэтому можете просто повторить мои шаманства, можете – почитать теорию по ссылкам, после чего у вас всё получится уже с пониманием физики процесса. А так – в рамках данной статьи я буду работать только через Windows, но через кроссплатформенную библиотеку libusb версии 1.0 (не путать с 0.1). Поэтому в Линуксе прописывать правила для устройства FX3 не буду.

2 Практика

Ох, и огромный сегодня получился теоретический раздел! Но наконец, мы владеем достаточным количеством знаний, чтобы приступить к опытам. Напомню, я буду работать в ОС Windows, пользуясь библиотекой libusb 1.0, опираясь на драйвер WinUSB. Я сейчас осваиваю работу с кроссплатформенной библиотекой Qt, поэтому буду разрабатывать код под неё.

2.1 Добавляем libusb в проект

Я скачал библиотеку libusb и распаковал её в каталог своего проекта. Чтобы подключить её к проекту, в файл *.pro пришлось добавить блок:

win32:{
LIBS +=  D:/Work/AS/2020/teensy/Qt/UsbSpeedTest/LibUSB/MinGW64/static/libusb-1.0.a
}

Кто сказал, что абсолютные пути – зло? Золотые слова! Я тоже так считаю. Но я уйму времени убил на эксперименты с относительными путями в этом месте. Ничего не получалось. Поэтому пока сделал так. Если кто-то знает тайну, как в проект добавляются относительные пути, да ещё так, чтобы работали, буду премного благодарен за разъяснения. А пока – отмечаю, что такой вариант работает, но однозначно является злом, так как он работает только у меня и только, пока я не соберусь перенести проект куда-то. Собственно, всё. Библиотека добавлена и готова к работе.

2.2 Класс для доступа к библиотеке

Обычно примеры для статей я пишу в слитном стиле. Но сегодняшний код получился несколько запутанным, поэтому пришлось вынести работу с платой FX3 в примитивный класс. Вот его интерфейсная часть:

#ifndef CUSBTESTER_H
#define CUSBTESTER_H
#include "./LibUSB/libusb.h"


class CUsbTester
{
public:
    CUsbTester();
    ~CUsbTester();
    virtual bool ConnectToDevice();
    virtual void DisconnectFromDevice();
    libusb_device_handle* m_hUsb;
protected:
    libusb_context * m_ctx = NULL;
};

#endif // CUSBTESTER_H

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

В конструкторе происходит инициализация и тонкая настройка библиотеки:

//#define CY_VID_PID

CUsbTester::CUsbTester()
{
    libusb_init(&m_ctx);
#ifdef CY_VID_PID
    libusb_set_option(m_ctx, LIBUSB_OPTION_USE_USBDK);
#endif
    libusb_set_option(m_ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
    m_hUsb = 0;
}

Как видим, возможна работа библиотеки через драйвер CyUSB и фильтр UsbDk, но сейчас она отключена. И мы включаем расширенную диагностику работы библиотеки. Все сообщения о проблемах будут сыпаться в окно отладочного вывода. Помните, я показывал сообщение об ошибке при работе UsbDk? Без этой опции никто бы ничего не узнал. Ошибка и ошибка.

Деструктор, соответственно, всё деинициализирует. Класс тестовый, заботиться о наличии дополнительных пользователей библиотекой нет смысла. Так что просто деинициализируем и всё.

CUsbTester::~CUsbTester()
{
    DisconnectFromDevice();
    libusb_exit(m_ctx);
}

Подключение к устройству интересно лишь тем, что может работать по разным парам VID/PID. Как я уже говорил, я могу собирать «прошивку» под штатные VID/PID от Cypress, если идёт работа через UsbDk, и под те, на которые у меня нашёлся inf-файл, устанавливающий драйвер WinUSB. В остальном, ничем не примечательные типовые вызовы функции библиотеки libusb:

bool CUsbTester::ConnectToDevice()
{
#ifdef CY_VID_PID
    m_hUsb = libusb_open_device_with_vid_pid(m_ctx,0x4b4,0xf1);
#else
    m_hUsb = libusb_open_device_with_vid_pid(m_ctx,0x1234,0x0005);
#endif
    if (m_hUsb == 0)
    {
        qDebug()<<"Cannot Open USB Device";
        return false;
    }
    int res = libusb_claim_interface(m_hUsb,0);
    if (res != 0)
    {
        qDebug()<<"Cannot claim interface - "<<libusb_error_name(res);
    }
    return true;
}

Ну, и отключаемся от устройства тоже типовым методом:

void CUsbTester::DisconnectFromDevice()
{
    if (m_hUsb != 0)
    {
        libusb_release_interface(m_hUsb,0);
        libusb_close(m_hUsb);
        m_hUsb = 0;
    }
}

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

2.3 Тестовая программа

Программа состоит из функции main() и тестовой функции.

Тестовая функция делится на две части. Первая часть измеряет скорость передачи данных. Вторая — проверяет то, что данные из счётчика приходят с инкрементом. При обнаружении разрыва – сведения об этом выдаются в консоль отладочного вывода. Собственно, вот текст функции:

bool TestStep(CUsbTester& tester,uint16_t* pData, const int bytesCnt)
{
    bool bResult = true;
    qDebug() << "Testing...";

    QElapsedTimer timer;
    timer.start();

    int actualLength;
    int res = libusb_bulk_transfer(tester.m_hUsb,0x81,(uint8_t*)pData,bytesCnt,&actualLength,10000);
    if (res != 0)
    {
        qDebug() << libusb_error_name(res);
        return false;
    }

    quint64 after = timer.elapsed();

    qDebug() << "Read Result = " << res;
    qDebug() << "Actual Length = " << actualLength;
    qDebug() << "Time = " << after;

    double speed = bytesCnt/after;
    qDebug() << speed << "Bytes / Sec";

    uint16_t prevData = pData[0];
    for (int i=1;i<bytesCnt/2;i++)
    {
        if (pData[i] != ((prevData + 1)&0xffff))
        {
            qDebug() << Qt::hex << i << " : " << prevData << ", " << pData[i];
        }
        prevData = pData[i];
    }
    return bResult;
}

В будущем я планирую вызывать эту функцию многократно, но пока — функция main() вызывает её один раз:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    CUsbTester tester;
    if (tester.ConnectToDevice())
    {

        QByteArray ar1;
        ar1.resize(128*1024*1024);

        for (int i=0;i<1;i++)
        {
            TestStep (tester,(uint16_t*)ar1.constData(),ar1.size());
        }
        tester.DisconnectFromDevice();
    }


    return a.exec();
}

Собственно, и вся программа.

2.4 Результат тестового прогона

2.4.1 Скорость

При тестовом прогоне мы видим, что скорость близка к требуемой. Напомню, что источник гонит 16-битные данные на скорости 60 МГц, так что нам требуется поток 120 миллионов байт в секунду. Когда на временных диаграммах наблюдался огромный дефицит колбасы, скорость была всего 30 Мегабайт в секунду. Даже меньше, чем практически достижимая скорость на шине USB 2.0. Так что текущие результаты вполне приемлемые.

Правда, чтобы окончательно успокоиться, я решил немного поэкспериментировать со скоростью. Чаще всего она была равна 119 0XX XXX байт в секунду. Изредка – 119 4XX XXX. Ну, и совсем редко – промежуточные значения, похожие на указанные выше. Сначала я решил, что это могут быть ошибки округления. У нас идёт округление показаний таймера, и возникают округления при делении. Тогда я переписал вычисление скорости так (перешёл на наносекунды и стал умножать перед делением, чтобы минимизировать ошибку округления):

    QElapsedTimer timer;
    int actualLength;

    timer.start();
    int res = libusb_bulk_transfer(tester.m_hUsb,0x81,(uint8_t*)pData,bytesCnt,&actualLength,10000);
    quint64 after = timer.nsecsElapsed();

    if (res != 0)
    {
        qDebug() << libusb_error_name(res);
        return false;
    }

    qDebug() << "Read Result = " << res;
    qDebug() << "Actual Length = " << actualLength;
    qDebug() << "Time = " << after;

    quint64 size = bytesCnt;
    size *= 1000000000;
    quint64 speed = size/after;
    qDebug() << speed << "Bytes / Sec";

Результат ничуть не изменился. Следующее подозрение было, что источник имеет некоторую ошибку кварцевого резонатора и шлёт данные чуть медленнее, чем надо. Но другая плата даёт точно такие же показания! Значит, дело не в экземпляре. Мало того, осциллограф (правда, весьма дешёвый китайский) говорит, что тактовая частота нисколько не занижена, даже чуть завышена.

Тогда я полез в исходники библиотеки libusb и просто-таки утонул в коде, который исполняется при ожидании конца передачи данных. Там такая цепочка функций – просто закачаешься! И много, где может возникать задержка. Но давайте прикинем, какова задержка.

120 мегабайт в секунду… Округлим до ста. Это 1 мегабайт в 10 миллисекунд. А у нас просадка как раз на 1 мегабайт. Неужели начало и конец прокачки съедают так много времени? Как бы проверить хотя бы начерно? Я решил переписать на пробу код под прямой вызов WinUSB API. Полностью объяснять я его не стану, там устройство открывается хитро, через SetupDi API. Я просто воспользовался готовыми своими старыми классами, поэтому всё было сделано под Visual Studio. Но вместо страшных километровых текстов ожидания завершения библиотеки WinUSB, моя функция чтения выглядит вполне канонически:

int CWinUSBConnector::ReadViaBulk (void* pData,int count,int timeOut)
{
	DWORD dwRead;

	ResetEvent (m_hEvRead);
	if ((!WinUsb_ReadPipe (m_hUsbDrive,m_nReadEP,(BYTE*)pData,count,&dwRead,&m_ovRead)) && (GetLastError() != ERROR_IO_PENDING))
	{
		return -1;
	}
	if (WaitForSingleObject(m_hEvRead,timeOut)!=WAIT_OBJECT_0)
	{
		WinUsb_AbortPipe (m_hUsbDrive,m_nReadEP);
		return -2;
	} else
	{
		WinUsb_GetOverlappedResult (m_hUsbDrive,&m_ovRead,&dwRead,FALSE);
	}
	return dwRead;
}

А тест теперь выглядит так:

#include <iostream>
#include <windows.h>

#include "./USB/WinUSBConnector.h"

CWinUSBConnector m_connector;


int main()
{
    std::cout << "Hello World!n";
	if (m_connector.Open() != 0)
	{
		std::cerr << "Cannot Open Driven";
		return 1;
	}

	LARGE_INTEGER Frequency;
	QueryPerformanceFrequency(&Frequency);

	static const UINT64 cnt = 128 * 1024 * 1024;
	BYTE* pData = new BYTE [cnt];

	LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;

	QueryPerformanceCounter(&StartingTime);
	UINT64 realSize = m_connector.ReadViaBulk(pData, (int)cnt, 10000);
	QueryPerformanceCounter(&EndingTime);
	if (realSize != cnt)
	{
		std::cerr << "Cannot Read Datan";
		return 2;
	}
	ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
	ElapsedMicroseconds.QuadPart *= 1000000;
	ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

	UINT64 bytesPerSeconds = (cnt*1000000LL) / ElapsedMicroseconds.QuadPart;

	std::cout << "Test Finished! " << bytesPerSeconds << " Bytes  per second n";

	delete[] pData;
	return 0;
}

Теперь скорость стабильно находится в районе 119 2XX XXX байт в секунду. Вот какой красивый результат я подловил для красного словца:

А вот результат нескольких прогонов подряд:

В общем, никто не запрещает просадке возникать и на входе-выходе в функцию чтения. Если разрывов в показаниях счётчика не будет, то и ладно.

2.4.2 Пропуски в показаниях счётчика

Но на тему разрывов у нас тоже имеется пара строк в выводе основной тестовой программы:

Имеется два нарушения последовательности счёта. Неужели мы нарвались на выпадение данных? К счастью, всё в порядке. Множественные прогоны говорят, что проблемы всегда в одном и том же месте. И мы с таким уже сталкивались в одной из старых статей. У нас есть две точки буферизации данных: буфер контроллера и FIFO в ПЛИС. Готовы ли мы принимать данные или нет, они с выхода счётчика будут заливаться в буфер FX3. Когда тот переполнится, заливка остановится. Кроме буфера FX3, есть ещё FIFO в ПЛИС. Вот у нас и имеется две ёмкости, которые заполнились, но счётчик продолжил работу. При чтении мы увидели разрывы в счёте.

Соответственно, мы наблюдаем явление переходных процессов. При реальной работе надо будет настроить источник так, чтобы он не заполнял буфер данными, пока мы не готовы их принимать (собственно, в статье про голову USB-Анализатора мы уже делали такую функцию через добавление бита «Go»), а пока – просто будем игнорировать ошибки в этой области. Считаем, что это – не баги, а фичи. Меняем проверку разрывов на такую:

То же самое текстом.

    int from = 0xc001;
    uint16_t prevData = pData[from];
    for (int i=from+1;i<bytesCnt/2;i++)
    {
        if (pData[i] != ((prevData + 1)&0xffff))
        {
            qDebug() << Qt::hex << i << " : " << prevData << ", " << pData[i];
        }
        prevData = pData[i];
    }

Делаем массовый прогон для такого варианта… И тут я понял, кто даёт задержку… Отладочный вывод!!! Вот так всё выглядит:

Масса вспомогательных текстов, выдаваемых библиотекой. Ну и отлично. Закомментируем в конструкторе класса, обслуживающего libusb, строку:

// libusb_set_option(m_ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);

Получаем красоту, ничем не отличимую от того, что мы получали при прямом вызове WinUSB API (жаль только, что не идеальный результат):

Но главное – нет сообщений про разрывы в показаниях счётчика (известные точки разрывов мы игнорируем).

А что там нам про таймауты промежуточные говорили? Попробуем читать не 128, а 32 мегабайта! Получаем уже скорость вплоть до 119 8XX XXX мегабайт в секунду!

В общем, всё хорошо… Кроме одного. Я нашёл такой нестандартный вариант теста, при котором штатная «прошивка» FX3 подвисает. Но статья получилась такой большой, что как это найти, а главное – как исправить, я расскажу в следующий раз.

3 Заключение

Мы познакомились с теоретическими особенностями работы с USB устройствами в ОС Windows и Linux, а также получили практический навык работы с кроссплатформенной библиотекой libusb. Начерно, разработанное USB 3.0 устройство на базе контроллера FX обеспечивает требуемый поток данных для приёма данных из микросхемы ULPI без промежуточного их сохранения в SDRAM. В потоке не выявлено разрывов, то есть, протокол передачи с виду устойчивый. Автор утверждает, что выявил принципиальную проблему в системе, но выносит её обсуждение в следующую статью.

USB (“универсальная последовательная шина”) — это интерфейс передачи данных с внешних носителей к компьютеру, устанавливая подключение и взаимообмен между ними. Сегодня без него не обходится большинство гаджетов. USB выпускается с 1996 года и на данный момент считается стандартным.

На данный момент существует четыре поколения спецификаций USB: USB 1.x, USB 2.0, USB 3.x и USB4.

USB делится на 2 типа: А и В. В первую группу входят активные (подключаются к “маме” и дают питание), в другую (подключаются к “папе”, это подключаемые устройства) — пассивные.

Помимо типов, USB разделяется на “папу” (Male) и “маму” (Female).

Виды USB

Распиновка USB разъема

На схеме представлены распиновки разных вариаций USB. Можно увидеть что на «розетке» и «вилке» USB A и В есть 4 контакта. Отметим, что расположение контактов зеркальны, но при пайке на это лучше не ориентироваться, так как очень легко ошибиться. В таком случае есть совет: посмотрите распиновку вашего USB.

У USB B необычный расположение контактов необычное — контакты находятся либо на стенках, либо в середине.

У USB Mini уже 5 контактов (5 обозначен x).

USB в разрезе

Распиновка micro USB разъема для зарядки колонки

micro USB — самый популярный вид разъема в наши дни. Современнее и меньше чем Mini, что позволило получить ему большее признание.

Распиновка micro USB разъема для зарядки колонки аналогична телефону, но здесь нет перемычек и резисторов. На изображении распиновки показано, что отсчет начинается слева направо, имеется 5 контактов. Как правило, USB на некоторых видах колонок не предназначено для передачи информации. Его основная функция — заряжать. Здесь представлена самая обычная модель колонки, используемая в машинах. У нее имеется 3 вывода: microUSB, аудиоштерек и USB (AM) на 4 контакта.

Красный контакт (+5V) micro USB подключается к красному контакту USB AM, проделываем тоже самое с черным контактом (GND).

Контакты белый (D-), зеленый (D+) и фиолетовый (может обозначаться по-разному, ID) присоединяется с аудиоштекеру.

Распиновка micro USB разъема колонки

Распиновка USB на материнской плате

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

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

На материнской плате может использоваться как спецификация USB 2.0, так и 3.0. Последняя более усовершенствована и встречается в более новых материнках.

USB 2.0 считается более доступным, поэтому он всегда будет находиться на материнской плате.

Чуть дальше мы рассмотрим распиновки USB 2.0 и 3.0 отдельно.

USB 2.0 возможно преобразовать в 3.0. На схеме видно, чтобы совершить данную идею, надо правильно соединить контакты. Красные контакты (+5V) 2.0 подсоединяем в таком порядке:

  1. 1 (USB 2.0) -> 17 (USB 3.0);
  2. 2 (USB 2.0) -> 20 (USB 3.0).

Подсоединение белого контакта (D-):

  1. 3 (USB 2.0) -> 6 (USB 3.0);
  2. 4 (USB 2.0) -> 4 (USB 3.0).

Подсоединение зеленого контакта (D+):

  1. 5 (USB 2.0) -> 1 (USB 3.0);
  2. 6 (USB 2.0) -> 3 (USB 3.0).

Последние черного контакта (GND):

  1. 7 (USB 2.0) -> 5 (USB 3.0);
  2. 8 (USB 2.0) -> 8 (USB 3.0).

Также нужно соединить контакты 10 и 12 на USB 3.0 и сделать перемычку 3, 6 и 8 на USB 2.0.

ЮСБ распиновка на материнке

Распиновка mini USB

Mini USB позволяет передавать данные на ПК, а также заряжать устройства. На данный момент сложно найти этот вид разъема у современных гаджетов, но он все же применяется в съемочной аппаратуре (камеры и т.д.). Скорость передачи информации составляет до 480 Мбит/с.

У него присутствует 5 контактов (+5V, D-, D+, GND, ID). Контакты при “маме” находятся сверху (отсчет справа налево), а при “папе” — снизу (отсчет слева направо), как и во всех других USB.

Распиновка mini USB

Распайка USB

Распайку рассмотрим на примере USB 3.0 типа А.

Видно, что здесь есть 9 контактов (+5V (здесь обозначен как VCC), D+, D-, GND, RX-, RX+, TX-, TX+, GND Drain).

Контакты RX и TX отвечают за прием и передачу информации. VCC и GND, в свою очередь, отвечают за питание.

Распайка гнезда USB 3.0

USB Type C распиновка

USB Type разделяется на А, В, В (mini), B (micro) и C.

ЮСБ Type A и B имеют по 4 контакта:

  • +5V;
  • D-;
  • D+;
  • GND.

К USB Type B mini и micro, а также Type С добавляется еще один контакт — ID.

У USB есть “вилка” и “розетка”. На распиновке “розетка” находится слева, а “вилка” — справа.

Примечательные особенности USB-C:

  • Есть перекидной разъем. Он разработан таким образом, что вилку возможно переместить относительно розетки.
  • Есть поддержка USB 2.0, 3.0 и 3.1 Gen 2,а также сторонние протоколы (например, HDMI), в альтернативном режиме.

Благодаря этому устройства способны самостоятельно согласовать и определить необходимый поток мощности через интерфейс.

  • USB Type C способен передавать изображение и аудио
  • Может выдерживать большие токи, поэтому существует возможность запитывать много устройств одновременно.

С учетом всех вышеописанных преимуществ можно назвать usb type-c поистине универсальным разъемом будущего. Он способен заменить почти любой существующий коннектор. Сейчас, к примеру, компания apple выпускает модели ноутбуков, наделенными лишь type-c разъёмами.

USB Type C

Распиновка micro USB разъема для зарядки телефона

Каждый сталкивался с проблемой, когда зарядник отказывался заряжать телефон, как его не крути. Вариантов такого поведения может быть множество: начиная от сгорания внутренностей адаптера, до отсутствия контакта в разъеме.

Консорциум USB, принял новый стандарт, известный как micro-B, меньший по размеру USB-разъем, который будет использоваться в первую очередь на небольших портативных устройствах, где пространство ограничено (например, сотовые телефоны). Разъем micro USB составляет примерно половину высоты разъема mini USB, что позволяет более тонким устройствам иметь доступ к USB.

GSMA приняла его как универсальное решение для зарядки, поэтому 90% новых мобильных телефонов будут иметь этот разъем.

На распиновке представлен micro USB, которым часто пользуется компания Samsung. Здесь можно видеть, что контактов 5 (присутствует ID), отсчет идет справа налево, а также имеется перемычка между зеленым (D+) и белым (D-) контактами.

Распиновка для зарядки телефона

У того же самсунга можно встретить перемычку не только на белом (D-) и зеленом (D+), но и на черном (GND) и фиолетовом (ID) с использованием резистора.

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

Благодаря этому устройство понимает когда подавать ток и в каком количестве.

Распиновка УСБ

Распиновка USB 2.0

USB 2.0 — самый распространенный разъем. Поддерживается на всех ОС (что не скажешь о 3.0). Очень удобен, ведь его провод тонкий и длинный. Сила тока составляет 500 мА, она достаточно мала, так как на рынке уже есть более усовершенствованные модели USB, обеспечивающие быстроту передачи данных.

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

Чтобы сделать обмен данными между этим устройством и хостом (uP или uC), когда USB-устройство подключено, сначала дескриптор устройства сообщает хосту, что такое идентификатор поставщика и идентификатор продукта, который используется для загрузки определенного драйвера для устройства, затем идет дескриптор конфигурации, который в основном используется для определения значений энергопотребления, затем есть дескриптор интерфейса, ведущее устройство может быть принтером, сканером или флэш-накопителем USB, этот дескриптор отвечает за определение того, что это за устройство, наконец, есть дескриптор конечной точки; этот дескриптор используется для определения скорости типа передачи, пропускной способности размера пакета и т. д. Имеется четыре конечных точки для низкоскоростного устройства USB 2.0 и 16 для высокоскоростного устройства USB 2.0.

Поговорим про D. Их по два, (+ и -), так как USB C предполагается возвратным. Если подключить вилку в обе стороны, и это будет считаться действительным соединением USB 2.0, потому что usb 2.0 не выполняет согласование закрепления. Поверните штекер на 180 градусов, и эти контакты подключаются в том же порядке. Ваша плата должна соединять оба вместе для максимальной связи.

Идентификационного контакта нет, так как он применяется только на вилках. В USB C с этим справляются контакты CC, и подключение их к GND с помощью резистора 5K создает режим OTG HOST на противоположной стороне соединения.

На этой распиновке можно увидеть распределение контактов на материнской плате. Видно, что красный контакт — это 1 и 2 разделение, белый — 3 и 4, зеленый — 5 и 6, черный — 7, 8, 10. 9 контакта тут нет. Контакты находятся друг под другом.

USB 2.0

Распиновка USB 3.0

Начнем с того, что USB 3.0 намного мощнее 2.0. Сила тока у 3.0 до 900 мА, что позволяет заряжать устройство намного быстрее, а также больше гаджетов. Несмотря на то, что 3 поколение свежее, толщина его провода больше, а длина меньше. Есть проблемы с поддержкой на ОС. Дело в том, что не все операционки хотят его использовать, так как он является самым дорогим из возможных вариантов. Но даже его дороговизна окупается одним существенным фактом — передача информации в две стороны происходит на максимальной скорости.

USB 3.0 содержит 5 контактов.

Контакты USB 3.0 на плате диагональны.

Контакты USB 3.0

Распиновка USB по цветам

В USB есть контакты, обозначенные цветами. В обычном варианте в разъеме имеется 4 контакта, а в mini и micro — 5.

Распиновка USB по цветам

  • Красный проводник +5V предназначен для питания (максимальный ток питания не превышает 500 мА). Напряжение +5V относительно контакту GND.
  • Черный контакт предназначен для “земли”. Имеет значение 0V.
  • Белый контакт подсоединяется к минусу.
  • Зеленый контакт подсоединяется к плюсу.

Порядок в классическом варианте контактов такой: красный, белый, зеленый, черный.

В mini и micro: красный, белый, зеленый, ID (может обозначаться по-всякому — фиолетовый, черный крест на белом фоне), черный.

Работа контакта ID заключена в двух типах по-разному. Например, в типе А он должен сохранять функцию OTG, а вот в типе В его нет.

Общая цоколевка USB разъема

Рассмотрим провод, который идет от разъема USB, потому как он полностью репрезентирует его цоколевку. Провод состоит из четырех контактов: плюс и минус питания (красный и черный), плюс и минус шины данных (белый и зелёный). Эти контакты можно соединять с другими.

Цоколевка USB разъема

Интересное видео на эту тему от наших коллег — «Радиолюбитель»:

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

Существует ряд различных спецификаций USB. Началось все с USB 1.0 и USB 1.1, затем интерфейс эволюционировал в USB 2.0, относительно недавно (на момент написания статьи) появилась окончательная спецификация USB 3.0. Но на данный момент наиболее распространенной является реализация USB 2.0. И для начала рассмотрим основные характеристики. Интерфейс USB 2.0 поддерживает три режима работы:

  • High Speed — до 480 Мб/с
  • Full Speed — до 12 Мб/с
  • Low Speed — до 1.5 Мб/с

Командует на шине USB хост (например, ПК), к которому можно подключить до 127 различных устройств. Если этого мало, то нужно добавить еще один хост. Причем немаловажно, что устройство не может само послать/принять данные хосту/от хоста, необходимо, чтобы хост сам обратился к устройству.

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

Давайте немного отвлечемся и поговорим о «железной части» интерфейса. Существуют два типа коннекторов — Type A и Type B.

Как уже понятно из рисунка Type A всегда обращен к хосту. Именно такие разъемы мы можем наблюдать на ПК. Коннекторы Type B всегда относятся к подключаемым USB-устройствам. Кабель состоит из 4 проводов разных цветов. Ну, собственно, красный — это питание (+5 В), черный — земля, белый и зеленый предназначены для передачи данных.

Несмотря на то, что именно такая цветовая маркировка является наиболее распространенной, тем не менее некоторые производители могут использовать и другие цвета. Более того, у меня был кабель, в котором провода красного и черного цветов были перепутаны, то есть красный шел на землю. Так что, если оперируете непосредственно с внутренностями кабеля, будьте аккуратны и не доверяйте цвету безоговорочно. Лучше прозвонить и перепроверить.

Помимо изображенных на рисунке, существуют также другие варианты исполнения USB-коннекторов, например, mini-USB и другие, тут я думаю секрета никакого не открою.

Пожалуй, стоит коснуться способа передачи данных, но углубляться в это пока не будем. Итак, при передаче данных по шине USB используется принцип кодирования NRZI (без возврата к нулю с инверсией). Для передачи логической «1» необходимо повысить уровень линии D+ выше +2.8 В, а уровень линии D- понизить ниже +0.3 В. Для передачи нуля ситуация противоположная — (D- > 2.8 В) и (D+ < 0.3 В).

Отдельно стоит обсудить питание устройств. И тут также возможно несколько вариантов. Во-первых, устройства могут питаться от шины, тогда их можно разделить на два класса:

  • Low-power
  • High-power

Разница тут заключается в том, что low-power устройства не могут потреблять больше, чем 100 мА. А устройства high-power должны потреблять не более 100 мА лишь на этапе конфигурации. После того, как они сконфигурированы хостом, их потребление может составлять до 500 мА. Кроме того, устройства могут иметь свой собственный источник питания. В этом случае они могут получать до 100 мА от шины, а все остальное забирать у своего источника.

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

Вся информация передается кадрами, которые отправляются через равные промежутки времени. В свою очередь каждый кадр состоит из транзакций::

Интерфейс USB, структура данных.

Каждый кадр включает в себя пакет SOF (Start Of Frame), затем следуют транзакции для разных конечных точек, и завершается все это пакетом EOF (End Of Frame). Если говорить совсем точно, то EOF — это не совсем пакет в привычном понимании этого слова — это интервал времени, в течение которого обмен данными запрещен.

Каждая транзакция имеет следующий вид:

USB транзакции.

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

Уже очень много раз прозвучало слово «пакет» применительно к интерфейсу USB, так что следует разобраться, что он из себя представляет. Начнем с пакета Token:

Структура Token пакета интерфейса USB.

Пакеты Token бывают трех типов:

  • In
  • Out
  • Setup
  • Start Of Frame

Пакет In сообщает USB-устройству, что хост готов принять от него информацию. Пакет Out, напротив, сигнализирует о готовности и желании хоста поделиться информацией. Пакет Setup нужен для использования управляющих передач. Ну а пакет Start Of Frame используется для того, чтобы инициировать начало кадра.

В зависимости от типа пакета значение поля PID в Token-пакете может принимать следующие значения:

  • Token пакет типа OUT — PID = 0001
  • Token пакет типа IN — PID = 1001
  • Token пакет типа SETUP — PID = 1101
  • Token пакет типа SOF — PID = 0101

Кроме того, есть еще один немаловажный нюанс. Поле PID включает в себя 4 бита, но при передаче они дополняются еще 4-мя битами, которые получаются путем инвертирования первых 4-ых.

Переходим к следующей составной части пакета Token — поля Address и Endpoint — в них содержатся адрес USB устройства и номер конечной точки, которой предназначена транзакция. И, наконец, поле CRC — это контрольная сумма, с этим понятно. Она как и обычно используется для контроля целостности и безошибочности данных.

На очереди Data пакет — то есть пакет данных:

Структура Data пакета.

Тут все, в принципе, так же, как и в пакете Token, только вместо адреса устройства и номера конечной точки здесь в наличии передаваемые данные. Таким образом, осталось рассмотреть Status пакеты и пакеты SOF, начинаем с первого из них:

Структура Status пакета.

Тут PID может принимать всего лишь два значения:

  • Пакет принят корректно — PID = 0010
  • Ошибка при приеме пакета — PID = 1010

Start Of Frame пакет:

Структура SOF пакета.

Видим новое поле Frame — оно содержит в себе номер передаваемого кадра. Давайте в качестве примера рассмотрим процесс записи данных в USB-устройство, то есть полную структуру кадра для записи. Кадр, как вы помните состоит из транзакций и имеет следующий вид:

Кадр интерфейса USB.

Что представляют из себя все эти транзакции? Сейчас разберемся, транзакция SETUP:

Транзакция Setup.

Транзакция OUT:

Транзакция Out.

Аналогично при чтении данных из USB-устройства кадр выглядит так:

Кадр USB при чтении данных.

Транзакцию SETUP мы уже видели, посмотрим на транзакцию IN:

Транзакция In.

Как видите, все эти транзакции имеют именно такую структуру, как мы обсуждали выше. В общем, думаю достаточно на сегодня, довольно-таки длинная статья получилась, в ближайшее время обязательно будем использовать данные теоретические аспекты на практике 👍

Понравилась статья? Поделить с друзьями:
  • Руководство пользователя по asus wifi
  • Хвоща полевого трава инструкция по применению цена
  • Тест ваш стиль руководства
  • Дренажный насос quattro elementi drenaggio 400 zero инструкция
  • Руководство garrett ace 250