среда, 13 апреля 2022 г.

USB Virtual COM port on STM32, code

Now then, why we need COM port in 21 century? It is one of worthily forgotten technologies. But the reason on the surface. There are not too much ways to connect custom USB device without need to write a OS driver. In order to do this you need a Virtual COM Port device or hooligans custom HID. In other words, if you run VCP on your MCU, you can use it's connection with benefits of autodetect and a plenty of PC lib's. But in that post I will comment my code of a classical example of USB-UART.

USB application particular features.

As it studied in previous post. In order to make standard USB-COM adapter we need a device with two interfaces. First with not working interrupt endpoint (may was for configuration), the second with two bulk endpoints for data. But all configuration is provided by standard control endpoint, and why we need yet another one no one knows, even linux driver, but he is glad to see him. So, device structure is as shown at the picture in previous post.

As for additions to previous library, I needs to add SetLineCoding, GetLineCoding request into my request handler with requests DATA OUT handling. I add new endpoints with their receive/transmit functions (vcpRx(data,size), vcpTx(data,size)). And UART DMA transmit, interrupt receive functions with timer based receive timeout. Obviously, appropriate descriptors was written with addition to descriptor handler function of multipackage data stage.

After implementing and solving problems associated with not incomplete documentation yet another 8kByte firmware is complete. Yet another funny problem was related with descriptors order. Experiment shows that this order is acceptable by driver.

  • Configuration descriprtor
    • control interface
      • functional (class-specific) descriptor
        • control endpoint descriptor
    • data interface
      • data IN endpoint descriptor
      • data OUT endpoint descriptor

Build is as usual - simply run make in appropriate folder and upload binary. Here is folder with project and *.elf file.

Linux driver.

The linux really can plug-in any USB-COM out of box by it's cdc-acm module. Herein VID's PID's may be anyone. Even baudrate conviguration function is working too. For testing instructions from that post are userfull. Here are dmesg output and devices list.

[58656.232965] usb 5-1: new full-speed USB device number 32 using ohci-pci [58656.419890] usb 5-1: not running at top speed; connect to a high speed hub [58656.429890] usb 5-1: New USB device found, idVendor=0483, idProduct=5740, bcdDevice= 2.00 [58656.429895] usb 5-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [58656.429897] usb 5-1: Product: loger [58656.429898] usb 5-1: Manufacturer: dltech [58656.433947] cdc_acm 5-1:1.0: ttyACM0: USB ACM device T: Bus=05 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 32 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=02(comm.) Sub=02 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0483 ProdID=5740 Rev= 2.00 S: Manufacturer=dltech S: Product=loger C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=00 Driver=cdc_acm E: Ad=83(I) Atr=03(Int.) MxPS= 1 Ivl=255ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_acm E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms

As you seen, linux automatically adds my board with cdc-acm driver. Also in writing that firmware source code of linux driver helps me too. I was needed to find setLineCoding request in it's code in order to confirm in that it works. Also list of expected endpoints looked here.

Test.

A simple but fair test. I connect my STM32 to the PL2303 adapter and try to send data using USB. While varying baud rates and stop bits. Here are diagram of connections and video.


USB-COM lag

One blogger says that USB-COM is not working solution because that intermediate layer makes a delay. Which crashes datastream when using timing sensitive data protocols. But after writing this firmware I think that it is wrong. Actually data are repacked, USB packs into 64kByte packages uninterruppted stream of the serial data. But speed of USB 2.0 is 12 MBits while UART usually works on 9.6 kBaud. Therefore USB do not brakes continuity of serial data too much because of his instantaneous. In my firmware a decision in sending obtained data handles in the interrupt, what excludes additional delay. In PL and FTDI that moment without delay too. As well linux C kernel module is instant too. So, you can use any USB-COM adapter in linux, it work as well as hardware com port on old motherboard.

Perspectives

In reality i wrote that driver in order to make an usb oscilloscope.

3 комментария :

  1. мицуба белая джамис бомж ин зэ скай

    ОтветитьУдалить
    Ответы
    1. эпидемия вызванная мицубой белой уже побеждена, можно поставить прививку и продолжить заводить ЛУАЗ

      Удалить
  2. выпил 8 банок охота крепкое и упал

    ОтветитьУдалить