2 पॉइंट द्वारा GN⁺ 2024-06-04 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • पहली बार USB डिवाइस बनाते समय ज़रूरी flow को physical wiring से लेकर PCB, USB 2.0 speed, protocol layers और STM32 practice तक एक साथ follow करने लायक तरीके से व्यवस्थित किया गया है
  • USB 2.0 का basic connection चार wires—+5V, GND, D+, D-—से होता है, और D+D- differential pair के रूप में मिलकर 1 bit transmit करते हैं
  • PCB में differential pair की length matching, पास-पास placement और impedance अहम हैं, लेकिन 12 Mbit/s full speed prototype तुलनात्मक रूप से forgiving हो सकता है
  • practice में NUCLEO-F103RB पर PA12 को USB_DP, PA11 को USB_DM के रूप में set करके, CDC virtual COM port के रूप में पहचाना जाने वाला USB serial device बनाया जाता है और 1 input देने पर LED जलती है
  • STM32CubeIDE approach में UI-based code generation और boilerplate का coupling बोझिल है, जबकि Linux-based USB device implementation अधिक standardized API और अलग-अलग structure दे सकता है

USB को पहली बार implement करते समय scope

  • लक्ष्य है ऐसा USB device सबसे सरल रूप में end-to-end बनाना, जिसे computer में plug करने पर वह पहचान लिया जाए
  • यहाँ device से मतलब computer की functionality बढ़ाने वाले peripheral से है, और computer को host कहा जाता है
  • scope में USB device और host के बीच physical connection से लेकर host पर USB device से interact करने वाली simple application तक शामिल है
  • यह authoritative specification explanation से ज़्यादा सबसे सरल E2E USB device बनाने के project और reference index जैसा है

USB की basic concepts

  • USB एक industry standard है जो कई electronic devices के बीच data exchange और power supply को संभव बनाता है
  • USB एक serial bus है, इसलिए bits parallel में नहीं बल्कि bus पर एक-एक करके transmit होते हैं
  • modern buses अधिकतर serial तरीके की होती हैं, और USB को host व device के बीच bits को serially exchange करने का तरीका माना जा सकता है
  • USB में दो devices को connect करने और bits भेजने-लेने की physical specification के साथ-साथ data transfer और power delivery के लिए communication protocol भी शामिल है
  • explanation का focus USB 2.0 पर है

USB wiring और differential pair

  • typical USB 2.0 connection को कम-से-कम चार wires से समझाया जाता है
    • +5 V: वह line जिससे host, device को power supply करता है
    • D-, D+: दो wires जो साथ में काम करके 1 bit transmit करने वाली differential pair हैं
    • GND: ground
  • कुछ connections में ID जैसे additional pins हो सकते हैं, लेकिन practice में केवल ऊपर की चार wires cover की जाती हैं
  • USB-C के बारे में सावधानी

    • USB-C भी internally differential pairs का उपयोग करता है, लेकिन इसे उल्टी दिशा में plug करने पर भी काम करना चाहिए जैसी बातों में यह general USB 2.0 explanation से अलग है
    • USB-C connector इस्तेमाल करने का मतलब यह नहीं कि speed या USB version तय हो जाता है
    • USB-C device भी USB 2.0 हो सकता है, या अधिक modern USB 3.0 device भी हो सकता है
    • आगे practice में USB-C को और cover नहीं किया गया है
  • differential pair noise कैसे घटाती है

    • single wire voltage को GND से compare करके bit value दिखाती है, लेकिन लंबे wired connection में noise का असर बड़ा हो सकता है
    • differential pair दो wires इस्तेमाल करती है; एक wire V और दूसरी wire -V carry करती है
    • receiver side दोनों wires के voltage difference को देखती है
    • अगर सरल करके मानें कि दोनों wires में same noise Vn जुड़ता है, तो (V + Vn) - (-V + Vn) = 2V हो जाता है, यानी noise cancel हो जाता है
    • यह model बहुत simplified explanation है, और differential pair को गहराई से समझने के लिए Zach Peterson का Altium YouTube video देखा जा सकता है
    • Video 15

PCB में USB handle करते समय

  • अगर आप खुद hardware नहीं बना रहे और development board इस्तेमाल कर रहे हैं, तो PCB section skip किया जा सकता है, लेकिन USB connector को PCB पर लगाने के basic principles उपयोगी हैं
  • USB connector library part में ऊपर बताए गए pins होते हैं, और differential pair को microcontroller या SoC के relevant adjacent pins तक route करना चाहिए
  • differential pair routing के तीन basic principles हैं
    • D+ से chip के plus pin तक जाने वाले trace और दूसरी trace की length equal match करें
    • दोनों traces को एक-दूसरे के बहुत पास रखें
    • signal के हिसाब से impedance पर विचार करें
  • चूँकि दोनों wires को लगभग identical environment से गुज़ारा जाता है, इसलिए पहले के simple model में यह assumption की जा सकती है कि दोनों wires का noise same है
  • impedance calculation को manufacturer के calculator में target impedance, ground plane से distance, differential pair के बीच distance आदि डालकर ज़रूरी trace width निकालने के तरीके से handle किया जा सकता है
  • Zach Peterson के differential pair और USB routing videos reference के रूप में शामिल हैं

USB 2.0 की speed

  • USB 2.0 होने का मतलब यह नहीं कि speed एक ही fixed होगी
  • USB 2.0 में, उदाहरण के लिए, दो speed levels हो सकते हैं
    • full speed: 12 Mbit/s
    • high speed: 480 Mbit/s
  • device और host को connection के समय तय करना होता है कि कौन-सी speed इस्तेमाल करनी है
  • PCB पर high speed को reliably achieve करने के लिए impedance match करना अहम है
  • basic prototype में 12 Mbit/s full speed पर्याप्त हो सकता है, और अगर USB connector से chip तक traces छोटी हैं तो trace width आदि को लेकर system तुलनात्मक रूप से forgiving हो सकता है

protocol और software layers

  • USB में hardware के साथ-साथ host और device दोनों sides की software layers पर भी विचार करना पड़ता है
  • Linux perspective से USB समझाने वाला लगभग 45-minute video recommended reference के रूप में शामिल है
  • यह video USB frames, endpoint, configuration, और एक device के कई USB functions perform करने के तरीके आदि cover करता है
  • USB को devices के network की तरह सोचने का perspective महत्वपूर्ण है
  • host operating system के लिए हर USB device का driver अलग-अलग implement करना अव्यावहारिक है, इसलिए operating system कई USB device class पहचानता है
    • mass storage device
    • serial device
    • और कई अन्य classes
  • practice device host के perspective से serial port device के रूप में काम करता है

STM32 से USB serial port device बनाना

  • practice device एक simple USB device है जो host से request मिलने पर LED जलाता है
  • host इसे serial port device के रूप में पहचानता है
  • implementation approach broadly दो हिस्सों में बंटती है
    • USB support वाला microcontroller इस्तेमाल करना
    • Linux चला सकने वाला SoC इस्तेमाल करके kernel से बहुत-सा काम करवाना
  • simplicity के लिए practice में microcontroller approach इस्तेमाल की गई है
  • NUCLEO-F103RB board

    • development board के लिए NUCLEO-F103RB इस्तेमाल किया गया है
    • अमेरिका में इसे Digikey जैसी जगहों से 10 dollars से थोड़ा अधिक में खरीदा जा सकता है
    • यह board दो जुड़े हुए हिस्सों की structure वाला है
    • छोटा हिस्सा programmer area है, बड़ा हिस्सा actual programming वाला main MCU area है
    • board का default USB connection main MCU से नहीं, बल्कि programmer side MCU से जुड़ा होता है
    • यह programmer ST-LINK protocol का इस्तेमाल करके computer से USB messages exchange करता है, और फिर main MCU को program करता है
    • अगर आप खुद STM32-based PCB बनाते हैं, तो board पर केवल एक chip रखकर, USB से programming करने के बाद उसी USB port को device logic के लिए इस्तेमाल भी कर सकते हैं
    • STM32-based PCB और USB programming के references के रूप में Phil’s Lab videos शामिल हैं
    • Video 19
    • Video 20

actual USB port wiring

  • Nucleo board का default USB connection main MCU से जुड़ा नहीं है, इसलिए main MCU के USB port को सीधे host से connect करना होगा
  • program upload करने के बाद ST-LINK programmer को computer से disconnect करें, और main MCU को actual USB port से power supply करें
  • software लिखने के लिए STM32CubeIDE और board पर upload करने के लिए STM32CubeProgrammer का इस्तेमाल किया जाता है
  • required pins और settings

    • USB 2.0 device बनाने के लिए चार pins चाहिए
    • host से आने वाली 5V power
    • GND
    • D+
    • D-
    • NUCLEO-F103RB पर main MCU side USB port से power लेने के लिए JP5 jumper बदलकर board को external 5 V supply लेने के लिए set करना होगा
    • STM32CubeIDE में pins को इस तरह set करें
    • PA12USB_DP
    • PA11USB_DM
    • इस board की chip को USB connection के लिए external 1.5 kΩ pull-up resistor चाहिए
    • resistor PA12 को 3.3V पर pull-up करता है
    • circuit को breadboard पर बनाया जाता है
    • MacBook Pro और individual pins को connect करने के लिए Amazon का USB breakout cable इस्तेमाल किया गया, terminal block हटाकर USB pins expose किए गए और jumper wire से Nucleo board और breadboard से connect किया गया
    • differential pair length matching और impedance control को strict तरीके से follow किए बिना भी इस practice में 12 Mbit/s connection संभव था

USB CDC software लिखना

  • CubeIDE में USB pins set करने पर clock settings से जुड़ा notification आता है, और CubeIDE द्वारा automatically handle करने वाला option चुना जा सकता है
  • Pinout & Configuration के Middleware and Software Packs के तहत USB_DEVICE set करें
  • practice में important mode यह है
Communication Device Class (Virtual Port Com)
  • इस setting से Nucleo board host perspective से CDC serial port device की तरह काम करता है
  • host इस class information के आधार पर custom device से communicate करने के लिए suitable driver set कर सकता है
  • CubeIDE C code generate करता है, और main.c में नीचे दिया initialization call शामिल होता है
MX_USB_DEVICE_Init();
  • LED जलाने के लिए CDC_Receive_FS routine में नीचे दिया code add करें
/* USER CODE BEGIN 6 */
if (Buf[0] == '1') {
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1);
}
  • यह HAL call port A के pin 5 से जुड़ी onboard LED जलाता है
  • step-by-step reference video यह है

flashing और run करना

  • ELF file build करने के बाद CubeProgrammer से board पर code upload करें
  • इसके बाद programmer को disconnect करें और ऊपर बताए तरीके से external 5V supply इस्तेमाल करके board wire करें
  • board चालू होने पर operating system के device manager में COM port या Serial port जैसे item के रूप में दिखाई देना चाहिए
  • CubeIDE के USB_DEVICE middleware menu में Device Descriptor values बदलकर operating system device manager में दिखने वाला custom device name set किया जा सकता है
  • Mac OS में नया device /dev file system के नीचे दिखाई देता है
    • example path: /dev/tty.usbmodem497A0F6739561
  • Linux में यह /dev/ttyUSB0 जैसे नाम से दिख सकता है
  • Minicom से serial device connect करने का example यह है
minicom --device /dev/tty.usbmodem497A0F6739561
  • connect होने के बाद keyboard से 1 enter करने पर Nucleo board की green LED जलती है

STM32 approach और Linux approach के software differences

  • practice का result mainstream operating systems द्वारा पहचाना जाने वाला USB serial port device बनाना है
  • STM32CubeIDE-based approach में software engineering perspective से कुछ असुविधाएँ हैं
    • UI menus click करके बहुत-सा boilerplate generate करना पड़ता है
    • यह InitUsbDevice(UsbClass.CDC) जैसे code में flexibly parameterized library इस्तेमाल करने वाला तरीका नहीं है
    • generated code user code से tightly coupled हो सकता है, जिससे code review मुश्किल हो सकता है
    • नया version आने पर boilerplate को कैसे update करना है, यह clear नहीं है
    • current setup STM32 ecosystem से मजबूती से बंधा है
  • Linux का USB device की तरह काम करने का तरीका अधिक साफ approach माना जाता है
    • Linux API अधिक robust और standardized है
    • यह pseudo-file और system call के साथ interaction पर आधारित हो सकता है
    • user space और kernel space अलग-अलग हैं
    • Linux को HAL layer की तरह देखा जा सकता है
  • हालांकि अगर lightweight, सस्ता और आसानी से produce होने वाला USB device चाहिए, तो Linux SoC भारी पड़ सकता है और कई use cases में overkill हो सकता है
  • निष्कर्ष यह है कि bare metal USB device development के लिए अधिक portable और कम opinionated framework होना अच्छा रहेगा

1 टिप्पणियां

 
GN⁺ 2024-06-04
Hacker News रायें
  • USB की शुरुआत के लिए यह लेख बहुत अच्छा है, लेकिन यह ST microcontroller के इस्तेमाल की ओर काफ़ी झुका हुआ है, और हाल के ESP32 ecosystem जैसे तरीकों की तुलना में, जहाँ USB device आसानी से जोड़े जा सकते हैं, इसमें steps और toolchain कहीं ज़्यादा लगते हैं
    साथ ही differential pair को लेकर, कई USB boards खुद बना चुके व्यक्ति के तौर पर, मुझे नहीं लगता कि beginner को इस पर बहुत ज़्यादा चिंता करनी चाहिए; यह मुख्यतः high-speed काम में अहम हो जाता है
    Arduino/ESP में आम तौर पर इस्तेमाल होने वाले USB controller IC बहुत-सी details संभाल लेते हैं, इसलिए अपना पहला device बना रहे व्यक्ति से calculations करवाना कुछ ज़्यादा लगता है

    • हाल ही में ATmega32U4 वाले Arduino Pro Micro से hand-wired macro pad बनाया था, और custom keyboard बनाने वाले hobbyists के बीच यह काफ़ी लोकप्रिय लगता है
      Beginners के लिए यह तेज़ और मज़ेदार project था, और सबसे झंझट वाला हिस्सा wooden case तराशना था
    • मुझे लगता है कि differential pair और impedance की बुनियादी समझ होना अच्छा है
      असल calculations मैंने लगभग कभी नहीं कीं, और जो ECAD software इस्तेमाल करता हूँ वह differential pair routing और impedance signal analysis tools देता है
      फिर भी अगर traces को बहुत छोटा रखा जाए तो आम तौर पर कोई बड़ी समस्या नहीं होती
    • USB controller IC के लिए सुझाव चाहिए
      आम तौर पर अब तक सिर्फ़ USB built-in microcontroller ही इस्तेमाल किए हैं
  • काफ़ी पहले USB compliance testing की थी, और जिन items में अक्सर समस्या दिखती थी उनमें से एक inrush current test था
    मूल रूप से 5V side पर bypass capacitors बहुत ज़्यादा होने का मामला था, और लेख में यह हिस्सा दिखा नहीं
    high-speed digital design पर ध्यान देना आसान है, लेकिन compliance में कभी-कभी कम चमकदार दिखने वाली चीज़ें अड़चन बन जाती हैं
    latest standards में यह कैसे काम करता है, पता नहीं, लेकिन लगता है test अब भी है, और लेख अपने आप में अच्छा था
    https://compliance.usb.org/index.asp?UpdateFile=Electrical#:...

    • inrush current limiting के लिए कौन-से components इस्तेमाल किए जाते हैं, यह जानना चाहूँगा
      कुछ transistors से current limiter बनाया जा सकता है, लेकिन temperature protection जैसी features वाला कोई बेहतर integrated solution होना चाहिए
  • USB-C के बारे में लेख में जोड़ना चाहूँ तो, CC pins को सही resistors से connect करना चाहिए
    ऐसा नहीं किया तो शायद उसके काम न करने की संभावना बहुत ज़्यादा है
    और differential routing व impedance USB 2.0 में इतना बड़ा मुद्दा नहीं है
    trace lengths को लगभग समान रखें, समझदारी से सीधे connect करें, और संभव हो तो उन्हें साथ-साथ रखें
    length/trace width की fine tuning, impedance control, और RF best practices को लेकर ज़रूरत से ज़्यादा परेशान होने की जरूरत नहीं; बस nets connect कर दें

    • 480Mbit/s काफ़ी तेज़ है, इसलिए best practices और लगभग 10% के भीतर impedance matching का ध्यान रखना चाहिए
      कई MCU में USB PHY pins और connector के बीच series resistors भी चाहिए होते हैं
      24mil के बजाय 20mil trace इस्तेमाल करनी पड़े, इसलिए board फिर से बनवाने की नौबत शायद नहीं आएगी, लेकिन USB 2.0 differential pair layout का बोझ कम होने पर भी इसे सही करने की कोशिश करना अच्छी practice है
  • अगर ARM processor जैसे soldering में मुश्किल components की चिंता है, तो ज़रूरी नहीं कि इतना बड़ा component ही इस्तेमाल करें
    performance चाहिए तो STM32 अच्छा है, लेकिन छोटे tasks के लिए छोटा controller बेहतर हो सकता है
    उदाहरण के लिए VUSB छोटे Atmel microcontrollers पर USB को bit-bang करने वाली library है: https://www.obdev.at/products/vusb/index.html
    students को Linux kernel module programming सिखाते समय इस्तेमाल किए गए example board के schematics भी हैं: https://gitlab.cs.fau.de/i4/passt/passtboard-v2
    firmware यहाँ है: http://www.poempelfox.de/ds1820tousb/ और https://gitlab.cs.fau.de/i4/passt/ds1820tousb
    अगर आप Arduino-style programming पसंद करते हैं, तो ऐसे कई boards भी हैं जिन्हें included libraries की कुछ lines से USB device की तरह इस्तेमाल किया जा सकता है, जैसे https://www.az-delivery.de/en/products/digispark-board

    • अगर soldering की चिंता है, तो microcontroller USB port पहले से लगा और working हालत में वाला development board काफ़ी reasonable price पर खरीदा जा सकता है
      उदाहरण के लिए NUCLEO-F429ZI है: https://www.st.com/en/evaluation-tools/nucleo-f429zi.html
      यह लेखक द्वारा इस्तेमाल किए गए NUCLEO-F103RB से बहुत मिलता-जुलता है, लेकिन built-in programmer/debugger के लिए ऊपर वाले USB connector के अलावा नीचे भी microcontroller से सीधे जुड़ा USB connector है
      ESD protection जैसी choices देखनी हों तो board schematics भी download किए जा सकते हैं
    • CH32V203 जैसा विकल्प भी है
      यह hardware USB वाला TSSOP-20 है, और single-unit price करीब 0.81 डॉलर है
      हालांकि software side थोड़ी ज़्यादा tricky हो सकती है
      https://www.wch-ic.com/products/CH32V203.html?
  • MCU पर bare-metal USB code लिखकर देखा है, और SPI या I2C जैसे सरल digital protocols से तुलना करें तो यह काफ़ी चौंकाने वाला था
    physical layer और data link layer CAN से बहुत ज़्यादा जटिल तो नहीं हैं, लेकिन उसके तुरंत बाद descriptors, endpoints और driver setup की दीवार सामने आ जाती है
    USB को शुरुआत से ही PC के लिए plug-and-play ecosystem के तौर पर design किया गया था, और उसकी यह खासियत साफ़ दिखती है
    संभव हो तो vendor-provided software का अधिकतम उपयोग करना निश्चित रूप से बेहतर रास्ता है
    धुंधली-सी याद में एक tip है: high throughput के लिए bulk transfers इस्तेमाल करें और isochronous transfers की तरफ़ देखें भी नहीं
    USB master/slave protocol है, इसलिए maximum throughput न मिले तो आम तौर पर वजह host यानी PC side पर होती है
    अगर LGPL license आपकी requirements से match करता है, तो libusb इस्तेमाल करने में काफ़ी आसान है
    vendor driver इस्तेमाल न कर रहे हों तो hardware USB protocol analyzer सच में बहुत उपयोगी है, और protocol समझने के लिए USB in a NutShell एक ठीक web reference है: https://www.beyondlogic.org/usbnutshell/usb1.shtml

  • STM32 पर USB संभालने की बात निकली है तो पूछना चाहूँगा: क्या किसी को पता है कि एक frame में 64 bytes से ज़्यादा receive करना कैसे support किया जाता है
    अभी software में 64-byte frames को बार-बार process कर रहा हूँ, लेकिन पता है कि इससे बड़ा संभव है
    शायद maximum 1MB तक था
    समस्या यह है कि Reference Manual में ये settings सामान्य registers के बजाय एक तरह के pseudo-registers के रूप में दी गई हैं
    जानना चाहता हूँ कि कोई आसान workaround है क्या
    OTG नहीं, USB peripheral के संदर्भ में

    • USB full-speed bulk transfers 64 bytes तक सीमित होते हैं
      आप कौन-सा STM32 कह रहे हैं, नहीं पता, लेकिन stm32g4 सिर्फ full-speed support करता है
  • मुख्य रूप से ESP32 इस्तेमाल करता हूँ, लेकिन कई projects के लिए एक सस्ता hacking तरीका है
    अगर बहुत तेज़ और आसान custom controller चाहिए, तो फेंके गए USB keyboard के control board को निकालकर इस्तेमाल करने पर विचार किया जा सकता है
    soldering की जगह conductive adhesive से contacts पर wires चिपकाएँ, और glue gun से मजबूती से fix कर दें
    spacebar input भेजने वाला arcade button आधारित 1-button game controller सस्ते में लेकिन काफ़ी मजबूत बनाया था; debounce वगैरह सब संभल जाता है और code की ज़रूरत नहीं पड़ती

  • क्या कोई USB 3 support वाली development board है, यह जानना चाहता हूँ
    USB-C monitor sink prototype करना चाहता हूँ, लेकिन USB से DisplayPort receive करने लायक performance वाली board मिलना मुश्किल हो रहा है

    • USB से DisplayPort receive करने के लिए बहुत ज़्यादा performance की ज़रूरत नहीं होती
      मानकर चलें कि आप पहले से DisplayPort signal receive कर सकते हैं या उसे external monitor पर route कर सकते हैं
      USB billboard device implement करें, और सही alternate mode signal करें
      operation के लिए यह optional है, लेकिन याद के हिसाब से spec में इसकी ज़रूरत होती है
      फिर USB-C plug पर DisplayPort signal निकलता है, और सही AUX lines को DisplayPort connector से जोड़ दें
    • ऐसी board है: https://octopart.com/cyusb3kit-003-cypress+semiconductor-494...
      कीमत भी reasonable लगती है
      2 साल पहले जब ऐसी ही चीज़ ढूँढी थी, तो कीमत एक digit ज़्यादा महँगी थी
    • transceiver वाले ज़्यादातर FPGA से यह संभव है
  • Raspberry Pi को PC में plug करके https://github.com/xairy/raw-gadget से virtual USB device बना रहा हूँ
    अभी proprietary software को धोखा देने के लिए MTP camera emulate करने में इसका इस्तेमाल कर रहा हूँ

  • Raspberry Pi Zero और Linux kernel के composite USB से कुछ USB devices prototype करके देखे हैं
    कम-से-कम storage device और serial device को काफ़ी आसानी से चलाया जा सका
    Raspberry Pi पर composite kernel module initialize करने वाली shell script जैसी चीज़ चाहिए होती है, और boilerplate code kernel docs में मिल जाता है

    • Pi से webcam जैसा virtual USB device बनाकर देखना चाहता हूँ
      pikvm भी एक दिलचस्प project है
      PC से connect करने पर USB connection सिर्फ keyboard और mouse की तरह काम नहीं करता, बल्कि system boot के लिए इस्तेमाल होने वाली USB drive भी बन सकता है
      installation work के लिए यह काफ़ी दिलचस्प तरीका है