EEVblog® Electronics Community Forum
Electronics => Microcontrollers => Topic started by: bogdant on November 15, 2020, 12:47:29 pm
-
I am designing a CAN->USB convertor around STM32H750 and I stuck on transmitting CAN frames to USB, the CAN frames are generated by CAN1 and loopback on CAN1 RX and send to USB. I could not get more speed then 2500bytes/25ms(100kB/s). Sometimes after a while the transmit USB handler(CDC_Transmit_HS) in STM32 takes from usually 10us to more 45ms. I also realized that the internal is only FS not HS. :-// Is there still room for improvement in current hardware setup ?
https://github.com/bogdan-tirzioru/BusAnalizer/blob/master/factory/sampleA/schematic.PDF
https://github.com/bogdan-tirzioru/BusAnalizer/tree/master/Firmware
Any idea what configuration shall I try to improve this?
-
Max data rate for CDC on USB FS is around 1MByte/sec.
So, certainly 500kBytes/sec should be achievable with that MCU.
Are you using ping-pong buffers?
Direct to port connection, i.e. no hubs?
-
I had a bunch of issues with ST's USB driver. It isn't really interrupt or multi-thread safe, and it would lock up on me with bidirectional traffic - that is, no transaction completion interrupts would fire after a few packets going both directions at the same time.
I wrote a small new usb stack here with a H750 driver: https://github.com/jacobschloss/libusb_dev_cpp, https://github.com/jacobschloss/libusb_dev_cpp/blob/master/src/driver/stm32/stm32_h7xx_otghs2.cpp. It actually was also for a USB CAN adapter, coincidentally - https://github.com/suburbanembedded/hadoucan-fw. I have it working in HS mode (external PHY), haven't bench marked but its pretty fast, keeping up with 12Mbps CAN FD.
So, it could be ST's driver.
-
Are you using ping-pong buffers?
Direct to port connection, i.e. no hubs?
So far I have not implemented any buffering, I know that I need too, so far the consistency was not in the focus.
There is no hubs in the involved.
-
I had a bunch of issues with ST's USB driver. It isn't really interrupt or multi-thread safe, and it would lock up on me with bidirectional traffic - that is, no transaction completion interrupts would fire after a few packets going both directions at the same time.
I wrote a small new usb stack here with a H750 driver: https://github.com/jacobschloss/libusb_dev_cpp, https://github.com/jacobschloss/libusb_dev_cpp/blob/master/src/driver/stm32/stm32_h7xx_otghs2.cpp. It actually was also for a USB CAN adapter, coincidentally - https://github.com/suburbanembedded/hadoucan-fw. I have it working in HS mode (external PHY), haven't bench marked but its pretty fast, keeping up with 12Mbps CAN FD.
So, it could be ST's driver.
The change to HS PHY will be in the next hardware version, I am hopping to have a STM32H7xx version with included HS PHY, it is not a joy to route high speed signals on a custom board. In the stm32F735 there is included but it is not CANFD included. I will have a look on the project you are working. I my design initial plan was to include 2 CANFD, but limitation is clear now, I will be lucky if one CANFD will work OK.
Did you use more then 3 endpoints or dma ?
-
This Controller
https://www.microchip.com/wwwproducts/en/ATSAMV70N19 (https://www.microchip.com/wwwproducts/en/ATSAMV70N19)
has got built-in HS-USB including PHY and two CAN-FD interfaces. Might be more suitable for you.
fchk
-
If you want to stay inside the STM32 ecosystem, the STM32F730 also has integrated HS.
Not sure if they have CAN-FD (maybe the F733?)
edit:, ah if the 735 doesn't have CAN-FD.. then probably the 733 won't neither
HS has the advantage of being able to transfer 512 bytes from an bulk endpoint rather than 64 bytes. The Usbd_cdc descriptor (https://github.com/bogdan-tirzioru/BusAnalizer/blob/fb4d823828ce4c080188da11dc6bbeea4868652b/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c#L239) is now set up for 512 bytes (https://github.com/bogdan-tirzioru/BusAnalizer/blob/fb4d823828ce4c080188da11dc6bbeea4868652b/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h). I'm not sure how the stack performs if you still attempt so transmit 512 or 2K at a time.
-
HS has the advantage of being able to transfer 512 bytes from an bulk endpoint rather than 64 bytes. The Usbd_cdc descriptor (https://github.com/bogdan-tirzioru/BusAnalizer/blob/fb4d823828ce4c080188da11dc6bbeea4868652b/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c#L239) is now set up for 512 bytes (https://github.com/bogdan-tirzioru/BusAnalizer/blob/fb4d823828ce4c080188da11dc6bbeea4868652b/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h). I'm not sure how the stack performs if you still attempt so transmit 512 or 2K at a time.
I would expect to send 4 packets of 512 for each transmit trigger(CDC_Transmit_HS).
-
.. it is not a joy to route high speed signals on a custom board...
Did you use more then 3 endpoints or dma ?
Only 3 endpoints, no dma (just loading FIFO up to 512B at a time). My stack recently got support for composite devices so I might be adding another virtual com port for diagnostics (patches not public yet).
Our board was very small, I don't think we were /that/ precise laying out the ULPI bus. but the tracks were also only like 1-2 cm long so ymmv.
-
Another interesting example for USB connection is the TeensyUSB stack for STM32 inc. H7.
It has an example for a WinUSB WCID device, which means seamless (no user interaction) driver install for your device (WinUSB.sys/WinUSB.dll).
Your app can then use either WinUSB.dll directly or via libusb (cross-platform).
Thus it allows bulk transfer while avoiding both the clumsy driver install and COM ports.
I haven't tried it myself but its on my todo list.
https://github.com/xtoolbox/TeenyUSB/blob/master/sample/custom_bulk/teeny_usb_desc.c (https://github.com/xtoolbox/TeenyUSB/blob/master/sample/custom_bulk/teeny_usb_desc.c)
-
I'm not sure how the stack performs if you still attempt so transmit 512 or 2K at a time.
I have change to 2K in the define (usbd_cdc.h)
#define CDC_DATA_HS_MAX_PACKET_SIZE 2048U /* Endpoint IN & OUT Packet size */
I also succeeded to reduce to 5ms/2048 by tuning the windows application. Setting to 2ms the worker threed does not release anymore and lead to main tread not to update anymore.
What is the maxim packet endpoint size?
-
What are you using to receive the Virtual COM with?
-
What are you using to receive the Virtual COM with?
I have a MFC application based on PJ Naughter driver:
https://github.com/bogdan-tirzioru/BusAnalizer/tree/master/BusWinAppl/BusWinAppl (https://github.com/bogdan-tirzioru/BusAnalizer/tree/master/BusWinAppl/BusWinAppl)
I also compare it with Putty application.
http://www.naughter.com/serialport.html (http://www.naughter.com/serialport.html)
-
STM32 USB training:
https://www.st.com/content/st_com/en/support/learning/stm32-education/stm32-moocs/STM32-USB-training.html (https://www.st.com/content/st_com/en/support/learning/stm32-education/stm32-moocs/STM32-USB-training.html)
https://www.youtube.com/playlist?list=PLnMKNibPkDnFFRBVD206EfnnHhQZI4Hxa (https://www.youtube.com/playlist?list=PLnMKNibPkDnFFRBVD206EfnnHhQZI4Hxa)
-
https://github.com/suburbanembedded/hadoucan-fw. I have it working in HS mode (external PHY), haven't bench marked but its pretty fast, keeping up with 12Mbps CAN FD.
I could not find the schematic in the repository. The project you have is written in C++, most interesting :popcorn:
-
Another interesting example for USB connection is the TeensyUSB stack for STM32 inc. H7.
Teeny, as in TeenyUSB; not Teensy. (TeenyUSB has nothing to do with Teensy microcontrollers.)