PORTS Forum

Ports and Interfaces => USB => Topic started by: selvaoscura on October 21, 2013, 11:17:14 am

Title: Transfer Complete Interrupt is not generated
Post by: selvaoscura on October 21, 2013, 11:17:14 am
Hello everybody,

I'm sending a simple 1 byte report (2 bytes with the Report ID) to my HID device that defines a Custom Usage.
My HID client on Windows uses a standard Win function 'WriteFile' to send reports to the HID device (my board). Windows says the report is sent OK (2 bytes written). I also can see (using debugger) the board receiving the packet. However the XFER complete interrupt is never generated, so my board shows no action (LED is off).
To add to my frustration, I had a success with the transaction at some point, but then without apparent reason the board stopped generating the XFER complete.
To summarize:
The board is enumerated OK
The report is sent and Success is returned by OS (Windows 8)
The Device receives the transaction and copies a packet from system FIFO buffer into Endpoint buffer.
The XFER complete interrupt is Not generated i.e. MCU doesn't detect a Transfer complete pattern.

I'm using stm32f4Discovery board with modified firmware. My Windows HID client is a modified WDK sample 'hclient' (C code).

Any advice is greatly appreciated.
Title: Re: Transfer Complete Interrupt is not generated
Post by: Jan Axelson on October 21, 2013, 12:23:28 pm
What is the "Transfer complete pattern" that triggers the interrupt?
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on October 21, 2013, 12:55:06 pm
According to

RM0090 Reference manual for STM32F40x, STM32F41x, STM32F42x, STM32F43x advanced ARM-based 32-bit MCUs

==================
The OUT data transfer completed pattern for an OUT endpoint is written to the receive FIFO on one of the following conditions:
– The transfer size is 0 and the packet count is 0 (that's because the count gets decremented on each packet read - My Note)
– The last OUT data packet written to the receive FIFO is a short packet (0 ≤ packet size < maximum packet size)
==================

The problem is I cannot say exactly what's the content of the packets. I'm using OpenOCD debugger coupled with Zylin embedded GDB plugin on Eclipse. The Debug GUI in Eclipse doesn't give a very readable info (in my opinion). It's difficult to figure out the content of the registers for example, or what exactly is the system buffer content. I probably need to try the command line
Title: Re: Transfer Complete Interrupt is not generated
Post by: Barry Twycross on October 21, 2013, 01:49:53 pm
Could you be having data toggle issues. The symptom of a data toggle issue is the data being successfully transferred on the bus, then being ignored. The behaviour is actually correct, the receiver and sender are differing on what data toggle to send. Which sounds like what you have.
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on October 21, 2013, 02:47:22 pm
My task at this point is to just ensure the USB connection works. The firmware reacts only to USB transfer per se, i.e. doesn't matter the report data (it is completely ignored). As long as the transfer is completed the application toggles a LED. So, I cannot see how Host and the device could possibly disagree here. Besides, as I mentioned before, the transfer is indeed 'incomplete', which is unambiguously seen using the debugger. The system signals the received packet and allows the application to read it, but never signals the completed transfer (although just one data packet of 8 bits has been sent to OUT Endpoint).

Anyways, I appreciate every advice given. I realize it's difficult to help here without physical access the whole setup.
Title: Re: Transfer Complete Interrupt is not generated
Post by: Tsuneo on October 21, 2013, 04:32:07 pm
Quote
selvaoscura:
I'm using stm32f4Discovery board with modified firmware.
Which firmware did you modify?
STM32_USB-Host-Device_Lib_V2.1.0 (STSW-STM32046)?
- \Project\USB_Device_Examples\HID?

And how did you modify it?
- Added an interrupt OUT EP, rewrote the report descriptor?

Because of Synopsis' "efficient" USB hardware design on STM32, and ST's rambling document, firmware programmers get hard time. To receive just single-packet transfer, we have to deal with twice RXFLVL interrupts (Data OUT packet pattern, Data transfer completed pattern), and XFER (XFRC) interrupt (endpoint transfer complete).

Tsuneo
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on October 21, 2013, 05:59:53 pm
I modified the Demonstration firmware coming with stm32f4discovery board ( STM32F4-Discovery_FW_V1.1.0\Project\Demonstration ).
The main modification is to "STM32F4-Discovery_FW_V1.1.0\Project\Demonstration\usbd_desc.c" for the Configuration descriptor (OUT endpoint added), and the Report descriptor (I replaced the original Mouse function with Custom function/usage for both IN/OUT).

Please, see attached 2 files:
1. usbd_desc.c (main points: 'USBD_HID_CfgDesc', 'hid_report_desc', 'USBD_HID_cb')
2. usblyzer_props_view.txt ( usblyzer's view of the descriptors)

Seems I cannot upload the attachments. Getting error:
"The attachments upload directory is not writable. Your attachment or avatar cannot be saved. "

Is there an email I can use to send them directly until I figure out how to post my files online for easy viewing?
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on October 21, 2013, 06:25:44 pm
In my case

Always happens:
OTG_FS_GINTSTS.RXFLVL      USB_OTG_GINTSTS_TypeDef.rxstsqlvl      RxFIFO non-empty i.e. indicates that there is at least one packet pending to be read from the RxFIFO.

Never happens (Transfer complete):
OTG_FS_GINTSTS.OEPINT      USB_OTG_GINTSTS_TypeDef.outepintr      Indicates an interrupt pending on one of the OUT endpoints of the core (in device mode).
Title: Re: Transfer Complete Interrupt is not generated
Post by: Tsuneo on October 22, 2013, 08:09:18 am
Umm,
The USB device stack in STM32F4-Discovery_FW_V1.1.0 is unstable.
I tested Demonstration example on my F4-Discovery board.
Just with a little change on the descriptor ( reset boot protocol, add an OUT endpoint ), the device engine drops into forced Suspend-Reset, around 10 seconds after the first bus reset. I have an impression that the stack expects SetFeature( REMOTE_WAKEUP ) to initialize its Suspend logic.

I recommend you to move to STM32_USB-Host-Device_Lib_V2.1.0 (STSW-STM32046)
http://www.st.com/web/en/catalog/tools/PF257882

In this version, many bugs in the USB stack (USB-Host-Device_Lib_V2.0.0) of STM32F4-Discovery_FW_V1.1.0 have been fixed, including above Suspend logic.
(though still minor bugs are there, like
https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex%5fmx%5fstm32%2fFlooded%20empty%20FIFO%20interrupts%20still%20make%20USB%20devices%20crawl
)

Tsuneo
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on October 22, 2013, 11:22:12 am
Tsuneo, Thank you very much for the information. I'll try your recommendation and let know the results.
Title: Re: Transfer Complete Interrupt is not generated
Post by: Tsuneo on October 22, 2013, 11:58:07 am
To port STM32_USB-Host-Device_Lib_V2.1.0 examples into F4-Discovery board,

1) Start with STM324xG-EVAL option

2) Crystal frequency (25 MHz --> 8 MHz)
Code: [Select]
system_stm32f4xx.c

#ifdef USE_F4DISCOVERY
  #define PLL_M      8
#else
  #define PLL_M      25
#endif

3) LEDs and switch
Copy these files into your project folder

\STM32F4-Discovery_FW_V1.1.0\Utilities\STM32F4-Discovery\
- stm32f4_discovery.c
- stm32f4_discovery.h

LED1 - LED4 (STM324xG-EVAL) --> LED3 - LED6 (F4-Discovery)

etc.

Tsuneo
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on October 23, 2013, 09:19:18 am
So far I tried simply building my project using libraries from STM32_USB-Host-Device_Lib_V2.1.0. Now it seems the packet is not reaching the board (OTG_FS_GINTSTS.RXFLVL not happening). Probably I'm missing some configurations.

I'll try to port the whole example as Tsuneo suggested.
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on January 12, 2014, 02:11:07 pm
Oh, that was long ago.
Just to round this one up. The reason was incorrect configuration used for the OUT transfer. The solution was eventually found in the 'RM0090 Reference manual' for 'stm32f4xx ARM-based 32 bit CPUs' on pages 1136 and 1139.

Prior receiving the data OTG_FS_DOEPTSIZ.XFRSIZ and PKTCNT have to be set by the application. This wasn't done in my case. Discovery examples only cover IN transactions, so the details of OUT setup are left to developer.

If XFRSIZ is not initialized, the transfer size on EP is set (by MCU Core) to a strange value '524224' (should be '64' normally). Because of the huge value of Transfer size, the 'Transfer complete' is never generated. On each subsequent packet sent from the HID Client the number '524224' gets decremented, but it would take 8191 of 64 bit packets to bring it to 0 and generate the 'Transfer complete'.

To solve the problem use function 'DCD_EP_PrepareRx', which sets XFRSIZ and PKTCNT. After that the 'XFRC interrupt' happens as expected... and developer moves to a next problem, which is a subject of another appeal for help:-)
Title: Re: Transfer Complete Interrupt is not generated
Post by: mangodan on March 13, 2014, 08:32:04 am
This sounds very similar to a problem I am having, but with some differences. This issue exists with essentially the same application but altered slightly to cope with 2 different targets:

STM32F105
STM32F407

First off, the application works as expected provided the host port is a USB2 controller. If I try to use an USB3 host on the same PC, the following problem occurs.

The Bulk out interrupt occurs exactly once. i.e. the first bulk write works and the application handles the data. All further write cause nothing to happen. The sending / driver end is happy that the data was sent, and wireshark shows that the writes are acknowledged by the device.

Control writes continue to work as expected.

All bulk IN transfers work as expected.

Any ideas what might lead to this behaviour, remembering that if the host end is USB2 it all works. But that the problem appears to be in the device end.
Title: Re: Transfer Complete Interrupt is not generated
Post by: Jan Axelson on March 19, 2014, 01:02:30 pm
After receiving bulk OUT data, be sure the endpoint is armed to receive new data.

A protocol analyzer will show if the host is attempting to send data and if the endpoint is NAKing the attempts.
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on April 02, 2014, 10:00:51 am
My transfer works fine by now but only ONCE.
I'm stuck with the 'bit toggle' problem that was mentioned by Barry Twycross a bit prematurely. Now it's upon me.

My OUT reports have 64 bytes and are sent in Single packet each. Windows WriteFile generates DATA0 on the first write. The device ACKs the packet and generates the Transfer Complete. The following packet is sent from Windows with DATA1. The device sends NAK on DATA1 and packet is endlessly resent. I cannot find how to tell Windows API that this is a New transfer and the packet has to be with DATA0. I have to reset the HID device.
BTW is my understanding correct that a New Transfer has to always start with Data0?
Title: Re: Transfer Complete Interrupt is not generated
Post by: Jan Axelson on April 02, 2014, 11:11:33 am
No. Except for control transfers, the data toggle resets only on Set Configuration, Set Interface, and Clear Feature(Endpoint Halt).

Also, a receiver that gets data with the wrong data toggle doesn't NAK. The receiver ACKS, but ignores, the new data.

After receiving bulk OUT data, be sure the endpoint is armed to receive (ACK) new data. See your controller's data sheet for information on how to do this.
Title: Re: Transfer Complete Interrupt is not generated
Post by: Barry Twycross on April 02, 2014, 01:12:07 pm
Definitely not a data toggle problem. A packet with a bad toggle is successfully transferred, that is its ACKed, then the host never tells the driver about it (it never generates a transfer complete interrupt) because the packet is discarded (correctly).

The data toggle toggles between DATA0 and DATA1, Jan mentioned the circumstances that cause the toggle to be reset, and a new transfer is not one of them. The new transfer should start with the next toggle, which is what you say its doing, so the host is being correct, its the device which is the problem.

The packets are being NAKed, which means they are not being received. The device is refusing them. The transfer complete interrupt never happens because the transfer has not completed. The data was not discarded, it was never received in the first place. A device will usually NAK because the endpoint has not been told to receive the data. It sounds like you successfully arm the endpoint for the first packet, then do not rearm it when you do get the transfer complete interrupt. The endpoint has to have been told that it can receive more data. It must have a buffer to put it in and there is usually an enable bit. So you arming goes something like:

1. Set buffer address
2. Set buffer length
3. Set control flags to enable endpoint.

You have do that for each transfer, which sound like each packet in your case.
Title: Re: Transfer Complete Interrupt is not generated
Post by: selvaoscura on April 03, 2014, 09:30:44 pm
The bug is fixed and the whole process is finally working!

My code had already everything in place. However there was one redundant function call that screwed up the setup right after EP was prepared for next transfer.
For interested I experiment on stm32f4 Discovery. The function that arms the EP for new transfer is 'usb_dcd.c:DCD_EP_PrepareRx'. Right after this function I had a call to 'usb_dcd.c:DCD_EP_Flush', which effectively destroyed just prepared setup. Simply commented it out.

If not the advice kindly provided on this forum I would probably chase a wrong path for uncertain time.

Thanks very much Ian and Barry!