Getting a USB stack to work on STM32 lazarus / 79-Embedded - ARM ---------------------------------------------------------------------- petex · 2021-02-07 20:49 hello, I have got the USB stack by Laksen (mentioned in a previous post on USB) compiled and running on the STM32 Bluepill. From what I can see and trace, the code is working as intended and valid config packets are sent back to the host. It is configured for a CDC USB class which is supposed to be supported by Windows 10 with a generic driver. When I plug in, the device is recognised and added to the devices page. It defines a virtual com port, but there is an error 10. (device not started) which is pretty unhelpful. The port cannot be opened. I have attached the relevant properties pages :- ---------------------------------------------------------------------- petex · 2021-02-08 13:52 Made some progress with this stack .... I installed a virtual com driver from the ST microelectronics site. I also changed the VENDOR and PRODUCT codes in the device descriptor to match this driver. It has installed a virtual com port in Windows 10 with no errors this time. When i type stuff in the terminal to this com port I can see the data transfer using a USB monitor tool, but not got the data out at the STM32 end yet. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  devDesc: TUsbDeviceDescriptor = (   bLength: sizeof(TUsbDeviceDescriptor);   bDescriptorType: USB_DESC_TYPE_Device;   bcdUsb: $0200;   bDeviceClass: 0;   bDeviceSubClass: 0;   bDeviceProtocol: 0;   bMaxPacketSize: CDC_EP0_SIZE;   idVendor: $0483;   idProduct: $5740;   bcdDevice: $100;   iManufacturer: 1;   iProduct: 2;   iSerialNumber: 3;   bNumConfigurations: 1 ---------------------------------------------------------------------- Laksen · 2021-02-08 15:37 Try to check that it's not stuck in the UsbSend function Can you show what transfers it's transmitting? ---------------------------------------------------------------------- petex · 2021-02-08 15:39 success, I have program looping back received data. Characters typed on terminal on windows are looped back ok. The code is compiled with the MBR compiler toolset and incorporates the MBR framework for the setup and timer. The Laksen units are unchanged. The unit "stm32f103fw" has been altered to fit with the MBR framework. I have also altered the main program to change the configuration packets and to simplify somewhat. ---------------------------------------------------------------------- Laksen · 2021-02-08 15:49 Good to hear, what did you change to fix it? ---------------------------------------------------------------------- petex · 2021-02-08 16:18 I was getting RX to work but not TX. I had different endpoint addresses for the RX and TX endpoints. I set them to $01 and $81 i,e, address 1 and i started to get TX request events and transmission of data started. ---------------------------------------------------------------------- MiR · 2021-02-09 10:16 Like it! I am a USB-noob myself, would you mind sharing your code? I'd love to put an example in MBF. Modern USB Stacks (tinyusb) do not need a vendor specific driver for windows, any idea what they do different? Michael ---------------------------------------------------------------------- PascalDragon · 2021-02-09 11:56 Quote from: MiR on February 09, 2021, 11:16:58 amI am a USB-noob myself, would you mind sharing your code? I'd love to put an example in MBF. Laksen's USB stack is available here. Quote from: MiR on February 09, 2021, 11:16:58 amModern USB Stacks (tinyusb) do not need a vendor specific driver for windows, any idea what they do different? They probably report vendor/device IDs that Windows supports out of the box. ---------------------------------------------------------------------- Laksen · 2021-02-09 16:18 Quote from: PascalDragon on February 09, 2021, 12:56:51 pmQuote from: MiR on February 09, 2021, 11:16:58 amI am a USB-noob myself, would you mind sharing your code? I'd love to put an example in MBF. Laksen's USB stack is available here. In case anyone's interested I have a big redesign on the feature_simpleusb branch that makes creating compound devices, and in general adding USB capability to a design a lot simpler: https://github.com/Laksen/fp- usb/blob/feature_simpleusb/example_cdc/test.lpr#L205 ---------------------------------------------------------------------- MiR · 2021-02-09 17:13 Have you ever tried how portable your stack is between stm* devices? Currently my thinking was that if I ever need usb it is way easier to integrate something like tinyusb which is available for all major stm32 chips (and also atmel d21/51 and esp32) but your code looks pretty slim..... Michael ---------------------------------------------------------------------- petex · 2021-02-09 17:37 QuoteI am a USB-noob myself, would you mind sharing your code? I'd love to put an example in MBF. I shall get a release together of what is currently working. I still have a problem with it hanging when I try to do some heavy lifting. i.e. I have a simple request/response protocol going between the STM32 and PC test application. It works OK for a while and then hangs waiting for a response back from the STM32. When I monitor the USB it looks active with tx requests so it looks like a tx back to pc has failed. I shall try and base an example on some very recent changes to simpleUsb and see if that works any better. ---------------------------------------------------------------------- avra · 2021-02-10 07:05 Quote from: petex on February 09, 2021, 06:37:49 pmIt works OK for a while and then hangs waiting for a response back from the STM32.Do you have a watchdog and brown out protection? Or at least a flashing led as an indicator that STM32 is not hanged? ---------------------------------------------------------------------- petex · 2021-02-10 10:00 QuoteDo you have a watchdog and brown out protection? Or at least a flashing led as an indicator that STM32 is not hanged? Early stages my friend !! The program should not hang as it is and there is some bug that I need to identify. I am starting at the start and getting bits to work stage by stage. ---------------------------------------------------------------------- Laksen · 2021-02-10 11:40 The old code did have some bugs that are fixed in the simpleUSB code. Primarily that it could lose bulk tx transactions and write too much to the endpoint overflowing the host controller probably leading to a disconnect or bus reset ---------------------------------------------------------------------- petex · 2021-02-10 12:31 hello, I have discovered how to load the Windows generic serial driver. Microsoft  have a designated class and sub class codes to select the "usbser.sys" driver. So I don't need the STM micro one, i was using.... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   DataIntf: (      bLength: sizeof(TUsbInterfaceDescriptor);      bDescriptorType: USB_DESC_TYPE_Interface;      bInterfaceNumber: 0;      bAlternateSetting: 0;      bNumEndpoints: 2;      bInterfaceClass: 2; // WIN GENERIC codes      bInterfaceSubClass: 2;      bInterfaceProtocol: 255;      iInterface: 2;    );     I merged in your changes to the UsbHal unit from the simple usb project. I am still getting the hang problem. The request/response transactions stop after the 50 - 250 point. I don't think the bug is in my PC program as I have it working normally using the PC uart com port and using the FTDI usb card. When it hangs, the PC is battering the STM32 with Tx requests and these trigger in the USbHal unit... The program on the STM32 is active and I can debug it ok, Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     reg := @USB.EPR[endpoint];    if (reg^ and USB_EP_CTR_TX) <> 0 then  At this point no data  receive events are triggered on the STM32 although it is polling for it. When I close and open the port, some setup packets are sent by the PC and these trigger the receive events .... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       reg^ := reg^ and (USB_EP_MASK xor USB_EP_CTR_RX);      if (reg^ and USB_EP_SETUP) <> 0 then        event := TDriverEvent.deSetup   // <<<<<<<<<<<<<<<<< THIS ONE TRIGGERS      else        event := TDriverEvent.deRx; ---------------------------------------------------------------------- Laksen · 2021-02-10 12:52 The old code would trigger zero length bulk TX writes all the time which would make the OS hammer the device. The requests coming when you open the port are also expected But I would not recommend wasting time with the old code. It had an unknown number of bugs in it and will be deleted soon ---------------------------------------------------------------------- petex · 2021-02-10 14:30 that's exactly it. Which module has the bug ? - not wishing to abandon work so far...... I copied your latest usbhal module. ---------------------------------------------------------------------- petex · 2021-02-10 17:47 I am getting a problem getting your code to compile in simpleusb_cdc Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   fConfigCallback:=fDevice^.AddConfigCallback(ueConfigured, @ DoConfigure); Quotesimpleusb.pas(751,27) Hint: Found declaration: AddConfigCallback(TUSBConfigEvent;const TSimpleUSBConfigCallback):; simpleusb_cdc.pas(198,80) Error: Incompatible type for arg no. 2: Got ";StdCall>", expected " of object;StdCall>" ---------------------------------------------------------------------- Laksen · 2021-02-10 23:51 I remember having that issue but I can't remember how I fixed it.. How old a compiler are you using? ---------------------------------------------------------------------- petex · 2021-02-11 09:25 its quite recent, the one from the MBF repository. Is it a compiler switch/option needed ? ---------------------------------------------------------------------- Laksen · 2021-02-11 10:42 It should be fine as is with the directives in the top. Did you modify the source? The line numbers don't seem to match exactly Also, can you try with newest trunk? ---------------------------------------------------------------------- petex · 2021-02-11 12:04 Quotesimpleusb_cdc.pas(195,73) Error: Incompatible type for arg no. 2: Got "", expected "" Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   fConfigCallback:=fDevice^.AddConfigCallback(ueConfigured, @DoConfigure);   Same problem with updated files. The basic fp examples for delegation work ok with this compiler. You seem to be using some esoteric features here and the compiler is not understanding it. How am i going to use more basic functionality to achieve the same goal ? I don't really care about super encapsulation here. I just want to get something working here so I can see if it is worth sticking with, otherwise I need to look around for another solution. I have spent a lot of time with the original code. Modifying the source is a red herring as I played around with some bits of code to investigate the problem. ---------------------------------------------------------------------- PascalDragon · 2021-02-11 13:31 Quote from: petex on February 11, 2021, 01:04:32 pmQuotesimpleusb_cdc.pas(195,73) Error: Incompatible type for arg no. 2: Got "", expected "" Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   fConfigCallback:=fDevice^.AddConfigCallback(ueConfigured, @DoConfigure);   Same problem with updated files. The basic fp examples for delegation work ok with this compiler. You seem to be using some esoteric features here and the compiler is not understanding it. How am i going to use more basic functionality to achieve the same goal ? I don't really care about super encapsulation here. Do you use a FPC trunk (aka 3.3.1) from at most 7 weeks ago? If not, then there is your problem, cause that's only supported since then. ---------------------------------------------------------------------- Laksen · 2021-02-11 13:41 Quote from: PascalDragon on February 11, 2021, 02:31:50 pmQuote from: petex on February 11, 2021, 01:04:32 pmQuotesimpleusb_cdc.pas(195,73) Error: Incompatible type for arg no. 2: Got "", expected "" Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   fConfigCallback:=fDevice^.AddConfigCallback(ueConfigured, @DoConfigure);   Same problem with updated files. The basic fp examples for delegation work ok with this compiler. You seem to be using some esoteric features here and the compiler is not understanding it. How am i going to use more basic functionality to achieve the same goal ? I don't really care about super encapsulation here. Do you use a FPC trunk (aka 3.3.1) from at most 7 weeks ago? If not, then there is your problem, cause that's only supported since then. Thanks for confirming Sven I was frantically looking through my local changes to see if I had forgotten to commit a fix for something ---------------------------------------------------------------------- MiR · 2021-02-11 13:59 Trunk version that I used for building mbf binaries could very well be a little older. I will see if I can update it to a fresher version of trunk, only problem is that currently building trunk inside of fpcupdeluxe is broken on Mac (which is currently a big issue for me), so I will have to see if I can catch a version that is young enough and still keeps fpcupdeluxe happy.. (Or find a fix for fpcupdeluxe)... Error when building trunk is: error: /Library/Developer/CommandLineTools/usr/bin/codesign_allocate: can't create output file: /usr/bin/codesign.cstemp (Operation not permitted) perhaps that rings a bell for anybody, when I compile trunk in a unix shell things work just fine. ---------------------------------------------------------------------- MiR · 2021-02-11 14:30 @Petex: Can you please try this version: http://temp.michael-ring.org/fpc-arm-embedded-3.3.1-win64-20210207.zip simply extract it where your current binaries are, this is trunk from a week or so.... @Laksen: Do you by chance happen to own a Segger J-Link? ---------------------------------------------------------------------- Laksen · 2021-02-11 14:59 Quote from: MiR on February 11, 2021, 03:30:19 pm@Laksen: Do you by chance happen to own a Segger J-Link? Not to my knowledge. Never been a huge segger fan I use a Busblaster v3 for all my jtag needs. Luckily haven't had a need for SWD yet ---------------------------------------------------------------------- petex · 2021-02-11 16:43 Quote@Petex: Can you please try this version: Ok thanks MiR. That compile error has gone and its all built ok. So now its a hard slog getting the USB to work!!. I'll keep you posted. ---------------------------------------------------------------------- Laksen · 2021-02-11 16:49 Good to hear it compiled at last Just to avoid wasting time, the MSD class driver is pretty broken so you should remove that from the code for now. I accidentally left it in the cdc design. But I've had the CDC running for hours without it breaking (on linux) ---------------------------------------------------------------------- petex · 2021-02-11 16:55 hello, I already left that out. I can report that windows has installed it using the generic usbser.sys device driver and the basic loop back test to terminal works. I now have to adapt smpleusb to my acid test program and see if it performs any better than the original. ---------------------------------------------------------------------- petex · 2021-02-11 19:06 Definitely works better than the old code. Looking quite reliable with my test PC program talking to the STM32. Nice one Laksen and MiR ---------------------------------------------------------------------- petex · 2021-02-12 16:12 I have been writing some test code and the USB services are hanging..... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  function TCDCDevice.Write(const AData; ASize: SizeInt): SizeInt;var  ptr: pbyte;  left: SizeInt;begin  result:=0;  ptr:=@AData;   while ASize>0 do  begin    if fTXPos>=fTXBufferSize then // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< HANGING    begin      if fBlocking then        fDevice^.Poll      else        break;    end       I am doing a succession of transmits which is different to the request/response protocol on the previous test. The request sizes of the transmits can exceed the TXBuffer size. The CDC Write procedure is meant to issue several TX buffer transmits until all the application data is sent and blocks until this is done. I can get it to hang where it is always repeating as shown in the above code excerpt. The write procedure does not return to the application. fTXPos = 64 and fTXBufferSize = 64 and fBlocking = true ---------------------------------------------------------------------- Laksen · 2021-02-12 17:04 Can you consistently reproduce this? What's the value of fTxDone when it hangs? ---------------------------------------------------------------------- petex · 2021-02-13 10:00 hello, I have changed my app somewhat and the problem manifests itself in a different way. This time it is in the receiver: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TCDCDevice.Read(var ABuffer; ASize: SizeInt): SizeInt;var  left: SizeInt;  ptr: pbyte;begin  Result:=0;   ptr:=@ABuffer;   while ASize>0 do  begin    if fRXPos<=0 then    begin      if fBlocking then        fDevice^.Poll      else        break;  // <<<<<<<<<<<<<< NEVER EXITS    end  I am requesting 1 byte but the receiver does not return and sits polling the USB. RXPos=0 fBlocking = true TXpos=0 TXDone=true The comms is request/response THe request is 4 bytes This works fine when the response is small ~ 8-16 bytes When I increase the response size (probably over the TX buffer size of 64 bytes), there is a point when it hangs. Is the problem due to the operation of "fBlocking", I have not looked at the code in any detail so i am guessing here. edit: I can normally plug and unplug the usb when the STM32 app is running with no problem. In the hang situation, when i plug it in Windows registers an error handling the USB interface. ---------------------------------------------------------------------- Laksen · 2021-02-16 12:50 I found a way to reproduce this bug. It seems to be related to how the hardware is driven in high throughput cases. The bulk out endpoint can get stuck in a case where it's not sending but all bits indicate that it should send. Might be a timing or bus issue