Почитавши цей пост і супутню йому дискусію, я вирішив спробувати внести ясність у те, що таке USB Power Delivery і як це працює насправді. На жаль у мене склалося враження, що більшість учасників дискусії сприймають 100 ватів по USB занадто буквально, і не до кінця розуміють, що за цим стоїть на рівні схематики та протоколів.

Отже, коротко – основні пункти:

  • USB PD визначає 5 стандартних профілів з електроживлення – до 5V@2А, до [email protected]А, до 12V@3А, до 12-20V@3А та до [email protected]А
  • Кабелі та порти для Power Delivery сертифікуються та мають додаткові піни у роз'ємі
  • Тип кабелю та його відповідність профілю визначаються автоматично через додаткові піни та визначення типу USB конектора (мікро, стандарт, A, B тощо)
  • Звичайні USB кабелі (не Power Delivery) сертифікуються лише за першим профілем до 5V@2A
  • При підключенні розподіляються ролі, тим часом хто дає струм ( Source / Джерело) і хто споживає ( Sink / Приймач)
  • Джерело та Приймач обмінюються повідомленнями за спеціальним протоколом, який працює паралельно традиційному USB
  • Як фізичний носій протокол використовує пару - VBus / GND. Саме тому Power Delivery не залежить від основного USB протоколу і назад сумісний із USB 2.0 та 3.0
  • Використовуючи повідомлення, джерело та приймач можуть у будь-який момент часу змінюватись ролями, змінювати силу струму та/або напругу, йти в сплячку або прокидатися, і т.д.
  • За бажанням пристрою можуть підтримувати управління PD через традиційні USB запити, дескриптори і т.д.
Під катом – деталі.

Про кабелі Про кабелі

USB Power Delivery працює з шістьма типами конекторів:

Відповідно попарно допустимі такі види сполук

  1. USB 3.0 PD Standard-A<->USB 3.0 PD Standard-B plug
  2. USB 3.0 PD Standard-A<->USB 3.0 PD Micro-B plug
  3. USB 3.0 PD Micro-A<->USB 3.0 PD Micro-B plug
  4. USB 3.0 PD Micro-A<->USB 3.0 PD Standard-B plug
  5. USB 2.0 PD Standard-A<->USB 2.0 PD Standard-B plug
  6. USB 2.0 PD Standard-A<->USB 2.0 PD Micro-B plug
  7. USB 2.0 PD Micro-A<->USB 2.0 PD Micro-B plug
  8. USB 2.0 PD Micro-A<->USB 2.0 PD Standard-B plug
Окремо варто зауважити, що специфікація прямо забороняє збочення з кількома конекторами на одній із сторін сполучного кабелю, що досить логічно, враховуючи струми до 100 Вт. З іншого боку використання перехідників та адаптерів не забороняється за умови, що вони відповідають профілю електроживлення, і не закорочують екран кабелю на його землю.

Про порти

Після сертифікації USB PD порти маркуються так:

Дане лого інформує про версію USB (2.0 або 3.0 SuperSpeed), а також про профілі електроживлення, які підтримує даний порт. Значення "I" означає споживаний профіль, необхідний для повноцінного функціонування пристрою, а значення "О" те який профіль порт може надати. Приклади маркування портів:

  • Перший порт підтримує USB2. Він може давати харчування за профілем 1 (2A@5V) і використовує Профіль 3 (5V@2A або 12V@3A) для повноцінного функціонування. Наприклад порт для планшета чи нетбука.
  • Другий порт підтримує USB2. Він може давати харчування за профілем 2 (2A@5V або [email protected]) та використовує Профіль 4 (5V@2A або 12V@3A або 20V@3A) для повноцінного функціонування. Наприклад порт для ноутбука чи лаптопа.
  • Третій порт підтримує USB3. Він тільки дає харчування за профілем 1 (5V@2A). Сам він за VBus не запитує. Наприклад порт робочого столу, монітора, телевізора, і т.д.
  • Четвертий порт підтримує USB3. Як і в першому прикладі, він може давати харчування за Профілем 1 (5V@2A) і сам вимагає харчування за Профілем 3 для повноцінного функціонування (5V@2A або 12V@3A). Приклад придумайте самі:)

Фізичний канал

USB PD визначає принципову схему фізичної організації з'єднання за допомогою кабелю наступним чином:

Як видно зі схеми, USB PD також вимагає, щоб і в джерелі і в приймачі були реалізовані схеми визначення падіння/стрибка напруги, а також методи визначення розрядженої батареї для випадків, коли одна зі сторін не може запитати від свого внутрішнього джерела.

Як алгоритми для визначення розрядженої батареї пропонуються наступне. Якщо одна із сторін виставляє опір в 1кОм між екраном та землею, це свідчить про те, що її батарея розряджена. У такій ситуації інша сторона бере на себе роль джерела і починає віддавати мінімальні 5В, щоб дати через VBus живлення протилежній стороні та почати обмін повідомленнями за протоколом USB PD.

Як згадувалося раніше, для обміну повідомленнями USB PD протокол використовує лінію VBus. Нижче наведено блок-схему, що визначає ключові функціональні елементи передавача:

І відповідно така сама блок-схема для приймача:

Серіалізоване кодування 4b5b і декодування 5b4b передбачає що всі дані по шині, крім преамбули пакета, передаються п'ятибітними послідовностями відповідно до таблиці кодування, що визначається стандартом. Кожна така послідовність кодує або одну з 16 цифр (0x00..0x0F), або сигнали початку/синхронізації/скидання та кінця пакета. Таким чином передача одного байта займає 10 біт, 16-бітного слова – 20 біт та 32-бітного подвійного слова – 40 біт тощо.

Логічний канал

USB PD протокол ґрунтується на послідовних парах типу запит-відповідь. Запити та відповіді надсилаються з використанням пакетів. Пакети складаються з преамбули (фаза підготовки до передачі), початку пакету SOP (три сигнали Sync-1 і завершальний Sync-2 у кодуванні 4b5b), заголовок, 0..N байт корисного навантаження, контрольної суми (CRC-32) та сигналу кінця пакета (одиночний сигнал EOP):

Як згадувалося вище, преамбула не кодується в 4b5b. SOP, CRC та EOP кодуються 4b5b фізично, заголовок і корисне навантаження кодуються на рівні логічного протоколу.
Скидання шини здійснюється шляхом посилки трьох сигналів RST1 і завершального сигналу RST2, відповідно до кодування 4b5b.

Протокол

Всі USB PD повідомлення складаються із заголовка та порції даних довільної довжини. Повідомлення або генеруються на рівні логічного протоколу і потім пересилаються на фізичний рівень, або приймаються фізично і потім пересилаються на рівень логічного протоколу.

Заголовок повідомлення має фіксовану довжину 16 біт і складається з наступних полів:

Повідомлення бувають двох видів – керуючі (control) та інформаційні (data).

Керуючі повідомлення
Контрольні повідомлення складаються лише із заголовка та CRC. Кількість об'єктів даних для таких повідомлень завжди встановлюється в 0. Типи керуючих повідомлень USB PD представлені в таблиці нижче:

Окремо слід згадати, що поля виду tSourceActivity, tSinkRequestі т.д. - це константи, значення яких глобально задані самою специфікацією в окремому розділі. Зроблено це тому, що вони визначалися дослідним шляхом у результаті прототипування, і знайдені оптимальні значення просто підставили в окремий розділ, щоб не нишпорити по всій специфікації.

Інформаційні повідомлення
Даний вид повідомлень призначений для отримання детальної інформації про джерело або приймач, а також для передачі характеристик електроживлення, що запитуються - сила струму, напруга і т.д. Інформаційні повідомлення завжди містять ненульове значення у полі Number of Data Objects.

Специфікація визначає чотири види інформаційних повідомлень:

  • Power Data Objec t (PDO) – використовується для опису характеристик порту джерела або вимог приймача
  • Request Data Object(RDO) – використовується портом приймача для встановлення угоди щодо характеристик електроживлення
  • BIST(Built In Self Test) Data Object(BDO) – використовується для тестування підключення на відповідність вимогам специфікації для фізичного з'єднання
  • Vendor Data Object(VDO) – використовується для передачі нестандартної, додаткової або іншої пропрієтарної інформації, що визначається виробником обладнання та спеціфікації USB PD, що виходить за рамки.
Види інформаційних повідомлень кодуються в полі Message Type заголовка повідомлення наступним чином:

Повідомлення про характеристики
Порт джерела завжди зобов'язаний повідомляти свої характеристики приймача шляхом передачі серії 32-бітових об'єктів PDO. Інформація передана у вигляді цих об'єктів використовується визначення можливостей джерела, зокрема включаючи можливість працювати у режимі приймача.
Повідомлення про характеристики подаються у вигляді одного або декількох об'єктів наступних за заголовком:

Повідомлення про характеристики передаються:

  • Від джерела до приймача через певний часовий інтервал при безпосередньому підключенні кабелю. Джерело має продовжувати надсилати повідомлення протягом однієї хвилини після підключення до тих пір, поки не буде встановлено успішну угоду з електроживлення, або приймач не поверне RDO з прапором Capability Mismatch – невідповідність характеристик.
  • Від джерела до приймача з метою примусового перевстановлення угоди з електроживлення або зміни характеристик.
  • У відповідь на керуючі повідомлення Get_Source_Capабо Get_Sink_Cap
Кожен об'єкт PDO повинен характеризувати окремий елемент електроживлення, що входить до складу пристрою на максимально допустимих значеннях напруги. Наприклад, вбудована батарея 2.8-4.1V, стаціонарний блок живлення 12V і т.д. Всі елементи електроживлення повинні підтримувати щонайменше 5V і відповідно кожне джерело має мати хоча б один PDO відповідний профілю з характеристиками 5V.

PDO відповідний елемент з постійним типом електроживлення 5V завжди повинен йти першим в ланцюжку об'єктів.

Структура об'єкта PDO:

До кожного типу електроживлення пропонуються різні характеристики.

Постійнийтип електроживлення, напруга постійна. Джерело повинне мати хоча б один такий елемент:

Програмованийтип електроживлення, напруга може регулюватися шляхом запитів у межах між мінімальним та максимальним:

Варіативнийтип електроживлення, напруга може змінюватися в межах абсолютного мінімуму і абсолютного максимуму, але може регулюватися:

Батарея, даний тип використовується для позначення батарей, які можуть бути безпосередньо підключені до лінії VBus:

Повідомлення про запит
Повідомлення про запити передаються приймачем до джерела передачі своїх вимог у фазі встановлення угоди з електроживленню. Дане повідомлення надсилається у відповідь на повідомлення про характеристики і має містити один і лише один об'єкт запиту даних – RDO, який описує інформацію про необхідні характеристики електроживлення приймача.

Цей запит має два типи, залежно від типу типу електроживлення, що адресується, переданого в повідомленні про характеристики джерела. Для запитів до елемента електроживлення постійного або варіативного типу, або батареї поля ”Operating Current/Power” та ”Total Current/Prog Voltage” інтерпретуються одним шляхом, а для запитів до елемента програмованого типу – іншим шляхом, тому що в цьому випадку запитується і напруга , і сила струму.

Структура об'єкта RDO:

На мій погляд, цієї інформації достатньо, щоб отримати гарне уявлення про принципи роботи USB Power Delivery. Я свідомо не став заглиблюватися в нетрі, пов'язані з таймерами, лічильниками та обробкою помилок.

Взаємодія з традиційним USB

Як вже було згадано вище, Power Delivery – це самостійна підсистема, яка функціонує паралельно та незалежно від канонічного USB. Тим не менш, у випадках коли пристрої реалізують обидва протоколи – USB і Power Delivery, специфікація рекомендує реалізацію т.зв. System Policy Manager або SPM, компонент, який може контролювати обладнання USB PD за допомогою традиційних запитів USB.

Для систем з підтримкою SPM специфікація рекомендує надати PD інформацію за допомогою спеціальних типів USB дескрипторів. Не вважаю за потрібне в них детально заглиблюватися, просто перерахую їх назви:

  • Power Delivery Capability Descriptor, є складовою BOS дескриптора і повідомляє про те чи підтримує пристрій зарядку батареї через USB, чи підтримує воно стандарт USB PD, чи може воно виступати джерелом живлення, і може бути приймачем. Крім того, даний дескриптор містить інформацію про кількість портів-джерел, портів-приймачів і версії специфікацій USB Battery Charging і Power Delivery, що підтримуються.
  • Battery Info Capability Descriptor, потрібно для всіх пристроїв, які заявили батарею в якості одного з елементів електроживлення. Містить інформацію про назву, серійний номер і виробника батареї, її ємність, а також про порогові значення струму в зарядженому та розрядженому стані.
  • PD Consumer Port Capability Descriptor, потрібно для всіх пристроїв, які заявили підтримку хоча б одного порту-приймача. Містить інформацію про підтримку стандартів Power Delivery та Battery Charging, мінімальну та максимальну напругу, операційну потужність, максимальну пікову потужність та максимальний час, який він може цю пікову потужність споживати
  • PD Provider Port Capability Descriptor, потрібно для всіх пристроїв, які заявили підтримку хоча б одного порту-джерела живлення. Містить інформацію про підтримку стандартів Power Delivery та Battery Charging, а також список всіх PDO об'єктів, що характеризують елементи електроживлення доступних для пристрою.
  • PD Power Requirement Descriptor, потрібно для всіх пристроїв-приймачів, що підтримують USB PD. Кожен пристрій повинен повертати хоча б один дескриптор у складі дескриптора конфігурації. Цей дескриптор повинен йти одразу після першого дескриптора інтерфейсу. Якщо їх кілька, він повинен йти після кожного першого дескриптора інтерфейсу функції, якщо використовується IAD, або у випадку композитного пристрою без IAD, безпосередньо після кожного дескриптора інтерфейсу, і до endpoint дескрипторів.
Для керування USB Power Delivery через запити USB, якщо пристрій підтримує Power Delivery клас, специфікація пропонує команди, які можуть використовуватися для передачі PD запитів та об'єктів за допомогою USB, тобто через шину даних. Зведена таблиця подана нижче:

Висновок

Сподіваюся, що цим постом я підігрів інтерес публіки до USB Power Delivery. Скромно зауважу, що автор має безпосереднє відношення до даної специфікації, тому готовий відповісти на будь-які питання щодо Power Delivery зокрема та USB загалом.

Периферійні пристрої, такі як миша, клавіатура, Web-камера, принтер зазвичай підключаються до комп'ютера через порти USB. У цьому нерідко трапляється, що чи кілька портів перестають працювати. Тобто, при підключенні до комп'ютера, наприклад, флешки вона не розпізнається, клавіатура чи мишка може зависати, а принтер може не відповідати та не друкувати сторінки.

Існує кілька ймовірних причин, з яких частина або всі порти USB на комп'ютері не працюють. Спробуємо розібратися в цьому питанні та з'ясувати, що потрібно зробити, щоб відновити нормальне функціонування комп'ютера.

Перевірка налаштувань BIOS

Перше, на що слід звернути увагу, це налаштування BIOS комп'ютера. Для входу в BIOS вам знадобиться працездатна клавіатура. Якщо клавіатура підключається до комп'ютера через USB і вона не працює, вам необхідно підключити клавіатуру з роз'ємом PS/2. Інакше ви просто нічого не зможете зробити.

Отже, заходимо в BIOS, навіщо під час запуску комп'ютера потрібно натиснути клавішу входу, зазвичай це DEL. Може бути й інша клавіша, яка відображається на екрані та вказана у посібнику до материнської плати. Увійшовши до BIOS, знайдіть розділ, який відповідає за інтегровані пристрої (Integrated Peripherals) або розділ «Додатково» (Advanced). Тут слід знайти підрозділ "Налаштування конфігурації пристроїв" (Onboard Devices Configuration). Саме в ньому знаходяться параметри, що відповідають за роботу контролерів USB: USB Function або USB 2.0 Controller. Ці параметри повинні бути включені (Enabled). І якщо один з них відключений (Disabled), то наведіть на нього та натисніть Enter, тим самим увімкнувши його. Щоб внесені зміни не скинулися, необхідно їх зберегти, натиснувши F10, і підтвердити збереження, натиснувши клавішу Y або Enter.

Після перезавантаження комп'ютера перевіряємо, чи порти USB працюють. І якщо ні, слід пошукати причину в іншому місці.

USB-порти не працюють на передній панелі комп'ютера

Як окремий випадок у вас можуть не працювати USB тільки на передній панелі. У такій ситуації необхідно перевірити, чи підключені необхідні роз'єми на материнській платі та чи не пошкоджені дроти. Для цього відкриваємо бічну кришку системного блоку та звертаємо увагу на роз'єм внизу материнської плати. На самій платі є напис USB1 або USB2, як і на колодці. Провід від колодки йде на передню панель, і якщо вони відключені або в одному місці обірвані, то ви виявили причину несправності. Пошкоджені дроти слід з'єднати або замінити. Не зайвим буде перевірити контакт у роз'ємі на материнській платі. Також варто звернути увагу на плату, розташовану на передній панелі. Можливо, має місце коротке замикання, до речі, таке замикання може бути спровоковано пилом, що скупчився. Тому обов'язково очистіть системний блок від пилу.

Проблеми з самим пристроєм чи кабелем

Наступним джерелом проблем USB може бути кабель, за допомогою якого підключений, наприклад, принтер. Цю несправність легко виявити та усунути. Приєднуємо до роз'єму флешку, що перевіряється. Якщо вона працює, то пробуємо підключити за допомогою підозрілого кабелю інше свідомо справне обладнання, наприклад USB-хаб. Якщо він також відмовляється працювати, причина однозначно в кабелі і його слід замінити.

Перебої з харчуванням

Трапляються такі ситуації, коли живлення для всіх пристроїв просто не вистачає. Наприклад, при підключенні зовнішнього жорсткого диска, який використовує відразу два роз'єми USB, може вимикатися принтер або клавіатура. У такому разі потужності блоку живлення недостатньо, щоб забезпечити енергію всіх споживачів. При цьому проблема може виявлятися не відразу, а через деякий час після ввімкнення комп'ютера. Шляхів виходу із ситуації кілька. Якщо у вас встановлено малопотужний блок живлення, наприклад, 300 Вт, то було б логічно його поміняти на потужніший, 450-600 Вт. Також можна використовувати активний USB-хаб (із зовнішнім живленням). Він дозволить не тільки збільшити кількість USB-пристроїв, що підключаються, але і запитати їх від окремого блоку живлення.

Ще одна причина, що впливає на роботу USB - це батарея CMOS, що сіла. Але при цьому ви будете при кожному включенні комп'ютера спостерігати системний час і дату, що збився. Після заміни батареї проблема йде. Але це не часто, тому слід перевірити інші можливі джерела несправності.

Відсутність або неправильне встановлення драйверів USB

Причини, пов'язані з програмними несправностями Windows 7/10, можна виявити за допомогою Диспетчера пристроїв. Якщо ви помічаєте, що не працює конкретно одне або кілька пристроїв незалежно від порту, то це може говорити про те, що проблема в самому пристрої. Відкрийте Панель керування та перейдіть до розділу Менеджер пристроїв. Там будуть відображатися всі підключені пристрої. Якщо у списку є пункти, біля яких стоїть жовтий знак оклику або замість назви стоїть Невідомий пристрій, то проблема в цьому самому пристрої. Тут може бути кілька варіантів неполадок.

Часто USB-входи перестають працювати після переустановки Windows 7/10. Причиною є неправильне встановлення драйверів або необхідні драйвера можуть бути взагалі не знайдені. Доведеться здійснювати підбір та інсталяцію вручну.

Нерідко для усунення несправності потрібно просто оновити драйвера. Так, якщо відключено автоматичне оновлення Windows, та й сама система була встановлена ​​досить давно, то втрачається актуальність програмного забезпечення, можуть з'являтися системні помилки. Пристрій при цьому починає працювати некоректно, а то й зовсім перестає функціонувати. Для оновлення (перевстановлення) драйверів контролера USB можна скористатися CD/DVD-диском з драйверами для материнської плати або завантажити необхідні драйвери з сайту виробника системної плати.

Також за допомогою диспетчера пристроїв можна вимкнути функцію економії електроживлення для всіх портів. Розкрийте список пристроїв, що використовуються, прихованих у розділах «Контролери USB», «Миша та інші вказівні пристрої», «Клавіатури». Клацаємо двічі мишкою по потрібному пристрої, щоб відкрити вікно властивостей. Тепер перемикаємось на вкладку «Управління електроживленням» та прибираємо галочку «Дозволити відключення цього пристрою для економії електроживлення». Таким чином, пристрій буде задіяний завжди і за будь-яких обставин.

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

USB-порти не працюють через пошкодження контролера

Якщо жодна з вищезгаданих дій не допомогла відновити працездатність портів USB, слід перевірити контролер USB материнської плати, який міг вийти з ладу. Якісний ремонт та діагностику у такому разі слід доручити фахівцям сервісного центру. Як варіант виходу із проблеми – спробуйте встановити плату розширення, так званий USB PC контролер, що встановлюється у роз'єм PCI на материнській платі. Таке рішення помітно дешевше за ремонт контролера USB материнської плати, а при використанні додаткового USB-хаба проблема з нестачею портів буде взагалі не актуальна.

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

Якщо ми підключаємо флешку 3.0 до комп'ютера, який передбачає підтримку портів USB 3.0, бачимо повідомлення « Цей пристрій може працювати швидше при підключенні до Super-Speed ​​USB 3.0», Це, друзі, означає, що ми або вставляємо флешку не в порти USB 3.0 (з синім язичком), або з їх функціонуванням є проблеми, і вони працюють в режимі USB 2.0. У чому криються причини проблем з роботою портів USB 3.0 на комп'ютерах, і як вирішуються такі проблеми, спробуємо розібратися в сьогоднішній статті.

Нагадаю, пропускна спроможність інтерфейсу USB 2.0 – 60 Мб/с, а USB 3.0 – у 10 разів більше, 625 Мб/с. Звичайно, рідкісні зі знімних накопичувачів, що підключаються до портів USB 3.0 комп'ютера, працюють на межі можливостей цього інтерфейсу, але він має важливе значення для окремих пристроїв зберігання інформації. Так, наприклад, багато сучасних моделей зовнішніх HDD на інтерфейсі USB 3.0 зможуть видати лінійну швидкість 100-170 Мб/с. Власне, те саме, що при підключенні внутрішніх жорстких дисків до SATA-інтерфейсу. Тоді як на інтерфейсі USB 2.0 лінійна швидкість зовнішніх жорстких дисків зазвичай тримається на позначці 30 Мб/с. Флешки 3.0 на інтерфейсі USB 3.0 записують дані швидше в 2-3 рази, а читають - швидше в 3-5 разів. До речі, ми детально говорили про швидкості роботи флешок на інтерфейсах USB 2.0 і 3.0. Загалом, друзі, якщо у вас є знімний накопичувач 3.0, вважаю, що розумітися на працездатності порту USB 3.0, якщо з ним виникли проблеми - справа стоїть.

Налаштування в BIOS

Порти USB 3.0 можуть працювати в межах можливостей USB 2.0, якщо вони налаштовані в BIOS. Цей момент необхідно перевірити насамперед. Заходимо в BIOS і шукаємо, де налаштовуються USB-порти, зазвичай це розділ розширених налаштувань Advanced і підрозділ USB Configuration. Або щось із подібними назвами. Тут потрібно перевірити, чи активна підтримка USB 3.0. Параметр USB 3.0 Support повинен мати значення Enable (Увімкнено). Значення Enable також має бути у параметра XHCI hand-off, він може називатися XHCI Pre-Boot Mode, просто XHCI або якось по-іншому, але з присутністю ключового терміна XHCI.

XHCI – це контролер USB 3.0, і якщо в BIOS не реалізований окремим пунктом параметр підтримки цього інтерфейсу типу USB 3.0 Support, його включення/відключення реалізується за рахунок контролера. На деяких материнських платах у параметра контролера XHCI можуть бути інші значення типу «Auto» або «Smart Auto», що забезпечують роботу портів USB 3.0 в режимі 2.0 до завантаження операційної системи зі своїми драйверами USB 3.0. І такі значення виробниками комп'ютерних пристроїв зазвичай виставляються за умовчанням, щоб уможливити роботу з сучасним інтерфейсом USB всередині операційних систем, при цьому уникнути краху установки окремих з них, у складі дистрибутива яких немає драйверів USB 3.0. Найяскравіший приклад – офіційні збірки Windows 7, проблему з відсутністю драйверів якої ми обговорювали та вирішували. Якщо на вашому, друзі, ПК або ноутбуку для випадків встановлення Windows 7 без інтегрованих драйверів USB 3.0 є робочі порти USB 2.0 (з чорним язичком), можна сміливо ставити налаштування контролера XHCI в положення Enable. Тільки при установці "Сімки" не забувати про те, що флешку потрібно вставляти в порт USB 2.0.

Оновлення драйвера

Всередині Windows працювати на рівні USB 2.0 інтерфейс USB 3.0 може через банальну причину некоректної установки драйвера контролера. Вирішується така проблема будь-яким із способів боротьби з некоректно встановленими драйверами – це їх оновлення, або переустановка. Використовуємо для початку штатні можливості Windows. Ідемо в диспетчер пристроїв. Розкриваємо гілку «Контролери USB». Клікаємо хост-контролер, що розширюється. Найчастіше він значиться як «Хост-контролер Intel(R) USB 3.0, що розширюється», але в нашому випадку, наприклад, його виробником є ​​японська компанія Renesas. Викликаємо на ньому контекстне меню та вибираємо оновлення драйвера.

Почнемо з мінімуму:
include 18f2455 - бібліотека для використовуваного МК
--
enable_digital_io () -- перемикання всіх входів на цифровий режим
--
alias Button is pin_B7 - якщо вже в нас підключена кнопка, оголосимо її
pin_B7_direction = input - кнопка у нас працює на вхід
--
-- один рядок - і ми маємо все необхідне для роботи з USB CDC
include usb_serial - бібілотека для роботи з usb
--
usb_serial_init() -- --ініціалізуємо USB CDC
forever loop- Основний цикл, виконується постійно
usb_serial_flush() - Обновлення usb. Ця процедура виконує всі необхідні
-- дії підтримки з'єднання з ПК
end loop

Скомпілювавши цей код, записавши отриманий HEX файл в МК за допомогою бутлоадера і запустивши пристрій можна буде спостерігати як в системі визначається новий пристрій: Віртуальний com-порт.

Тепер, коли пристрій працює, навчимо його спілкуватися.

Для читання прийнятого байта існує функція usb_serial_read( byte ) :boolean. За наявності отриманого байта вона заносить його у вказану змінну та повертає true, інакше повертає false.

Для надсилання байта існує процедура usb_serial_data. Вона замаскована під змінну, тому для відправки байта достатньо присвоїти їй значення байта, що відправляється.

Оголосимо змінну розміром в байт до основного циклу, в основному циклі перевірятимемо наявність отриманих байт, і за наявності відправляти їх назад.

include 18f2455
--
enable_digital_io ()
--
alias Button is pin_B7
pin_B7_direction = input
--
--
include usb_serial
--
usb_serial_init()
var byte ch -- оголошуємо змінну
forever loop- Основний цикл
usb_serial_flush()
if(usb_serial_read (ch)) then-- якщо байт отримано, він буде записаний у ch
usb_serial_data = ch -- відправляємо отриманий байт назад
end if
end loop

Компілюємо, затискаємо кнопку, пересмикуємо живлення, запускаючи бутлоадер, міняємо прошивку, запускаємо.
Пристрій знову визначився в системі, тепер нам потрібний софт, щоб протестувати роботу пристрою.

Поки ми не маємо свого, використовуємо готовий термінал: я використовував програму RealTerm.
Відкриваємо порт з потрібним номером та надсилаємо дані.


І нам у відповідь надходить те, що ми відправили. Отже, все працює як слід.

Софт

Отже, наш мікроконтролер вміє приймати байти і відразу відправляти їх назад. Тепер напишемо свій софт для спілкування з ним (я використовуватиму Delphi).

Створюємо новий проект, розкидаємо формою необхідні компоненти:
SpinEdit1 – для вказівки номера порту
Button1 - для встановлення з'єднання
Button2 – для розриву з'єднання
SpinEdit2 - для введення байта у десятковому вигляді
Button3 - для відправки байта
Memo1 – для виведення прийнятої інформації.

Як вже було сказано вище, з com-портом потрібно працювати так само, як і зі звичайним текстовим файлом: використовуючи функції CreateFile, WriteFile та ReadFile.

Щоб не вдаватися до подробиць, візьмемо готову бібліотеку для роботи з com-портом: ComPort.

Вішаємо на кожну кнопку необхідне завдання та отримуємо кінцевий код:

unit Unit1;

interface

Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin, ComPort;

Type
TForm1 = class (TForm)
SpinEdit1: TSpinEdit;
Button1: TButton;
Button2: TButton;
SpinEdit2: TSpinEdit;
Button3: TButton;
Memo1: TMemo;
procedure OnRead(Sender: TObject; ReadBytes: array of Byte);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
(Private declarations)
Port: TComPort;
public
(Public declarations)
end;

var
Form1: TForm1;
num: integer;
implementation

Procedure TForm1.Button1Click(Sender: TObject);
begin
Port:= TComPort.Create(SpinEdit1.Value, br115200); //створюємо з'єднання
Port.OnRead:= OnRead; //Створюємо потік читання прийнятих даних
Button2.Enabled:= true; //активуємо кнопку закриття з'єднання
end;

Procedure TForm1.Button2Click(Sender: TObject);
begin
Port.Free; //закриваємо з'єднання
Button2.Enabled:= false ; //відключаємо кнопку
end;

Procedure TForm1.Button3Click(Sender: TObject);
begin
if Button2.Enabled then Port.Write();
end;

Procedure TForm1.FormDestroy(Sender: TObject);
begin
if Button2.Enabled then
Port.Free;
end;

Procedure TForm1.OnRead(Sender: TObject; ReadBytes: array of Byte);
var
i:integer;
begin
for i:= Low(ReadBytes) to High(ReadBytes) do //проходимо масивом прийнятих байт
begin
Memo1.Text:= Memo1.Text + "." +InttoHex(ReadBytes[i],2); //додаємо його HEX значення у вікно
inc(num); //Вважаємо колв-о прийнятих байт
end;
if num > 10 then begin
Memo1.Lines.Add(""); //переносимо рядок
num: = 0;
end;
end;

Запускаємо, встановлюємо з'єднання, відправляємо байти:

Ось і готовий наш найпростіший термінал для роботи з найпростішим USB-пристроєм.

Як видно, читання та запис відбувається динамічними масивами байт.

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

include 18f2455
--
enable_digital_io ()
--
alias Button is pin_B7
pin_B7_direction = input
--
--
include usb_serial
--
usb_serial_init()
var byte ch
var byte i -- оголошуємо другу змінну
forever loop- Основний цикл
usb_serial_flush()
if(usb_serial_read (ch)) then-- якщо байт отримано виконуємо необхідні дії
case ch of - перебираємо номер байта
0 : usb_serial_data = 0xff
1: usb_serial_data = Button -- надсилання стану кнопки
OTHERWISE block- якщо отримано щось інше
for 16 using i loop- відправляємо 10 байт із даними
usb_serial_data = ch +i - від ch до ch +15
end loop
end block
end case
end if
end loop

Додаткові можливості

Якщо на цьому зупинитися, вийде проста стаття з детальним описом прикладу використання бібліотеки, яких на просторах мережі достатньо. Тому додам трохи більш поглибленої інформації.

Спрощення надсилання даних

Відправляти інформацію по одному байту – не завжди зручно. Дуже часто може стати в нагоді бібліотека print. Вона містить процедури з надсилання даних всілякої довжини різними форматами: byte,hex,dec,bin,boolean що може спростити виведення даних у програмі.
>include print
...
var dword data
print_dword_hex (usb_serial_data, data)

Назву всіх команд можна переглянути у файлі бібліотеки.

Очікування підключення до ПК

Якщо перед стартом основного циклу мікроконтролера необхідно попередньо встановити з'єднання з ПК, можна дописати перед ним рядки
while(usb_cdc_line_status () == 0x00 ) loop
end loop

Прив'язуємо до пристрою номер порту

Якщо залишити все як є, система при кожному новому підключенні виділятиме перший вільний номер порту. А це означає, що за ним доведеться завжди стежити.
Для того, щоб цього не відбувалося, необхідно пристрою присвоїти унікальне значення серійного номера до підключення бібліотеки usb:
Номер може бути будь-якої довжини та містити різні символи.
const byte USB_STRING3 =
{
24 , - Довжина масиву
0x03 , -- bDescriptorType
"0" , 0x00 ,
"1" , 0x00 ,
"2" , 0x00 ,
"3" , 0x00 ,
"4" , 0x00 ,
"5" , 0x00 ,
"6" , 0x00 ,
"7" , 0x00 ,
"8" , 0x00 ,
"9" , 0x00 ,
"X", 0x00
}

Змінюємо ім'я пристрою на своє

Змінити ім'я пристрою, видиме в системі до встановлення драйверів, можна оголосивши масив з ім'ям, як і серійний номер, це необхідно зробити до підключення бібліотеки USB.
const byte USB_STRING2 =
{
28 , --
0x03 , -- bDescriptorType
"D", 0x00 ,
"e", 0x00 ,
"m", 0x00 ,
"o", 0x00 ,
" " , 0x00 ,
"B", 0x00 ,
"o", 0x00 ,
"a", 0x00 ,
"r", 0x00 ,
"d", 0x00 ,
" " , 0x00 ,
"=" , 0x00 ,
")" , 0x00
}

Але на жаль, після установки драйверів пристрій змінить ім'я на вказане в.inf файлі, тому змінимо ім'я і там


DESCRIPTION=«Demo CDC»

Організуємо автопідключення пристрою

На жаль, ніяких прямих шляхів виконати це завдання немає, тому доведеться хитрувати.

Насамперед необхідно надати своєму пристрою унікальне значення виробника та продукту, щоб легко визначати його серед сотень інших стандартних CDC-прошивок.
VID і PID видаються за денюжку, тому підемо по шляху китайців: нишком візьмемо собі свідомо вільні значення.

Прошивка:
У прошивці необхідно оголосити дві змінні до підключення бібліотеки USB

const word USB_SERIAL_PRODUCT_ID = 0xFF10
const word USB_SERIAL_VENDOR_ID = 0xFF10

Замість FF10 можна вставити будь-які два слова (2 байти). Кінцевий результат міститься в архіві, що додається.

Драйвера:
Оскільки драйвера не призначені для нашої комбінації VID та PID, допишемо наші значення в.inf файл вручну:


%DESCRIPTION%=DriverInstall, USB\VID_FF10&PID_FF10


%DESCRIPTION%=DriverInstall, USB\VID_FF10&PID_FF10

Софт:
Для вилову подій підключення\відключення пристрою підключимо бібліотеку ComponentUSB. Не вважаю за потрібне пояснювати кожний рядок: всі зміни можна побачити в проекті, що додається.

Результат

На скріншоті складно розглянути, але кнопка відправки активна тільки в момент наявності підключеного пристрою, при цьому кожні 50мс програма подає запит на отримання стану кнопки (що, втім, неправильно, тому що натискання кнопки має оброблятися на МК).

Як видно, організувати обмін даними між МК та ПК через USB – не найскладніше заняття. Отримане з'єднання можна використовувати не тільки для кінцевих цілей: воно так само підходить для налагодження програми. Адже відправити на комп'ютер результати розрахунків, поточні стани регістрів і змінних набагато наочніше, ніж моргати парою світлодіодів азбукою морзе.

І насамкінець: раджу заглянути у вихідний код лампи настрою. Там можна знайти досить хороший варіант обробки даних для організації зручного протоколу обміну.