Page 4 of 4

Re: Serial over USB problem

Posted: Wed May 15, 2013 2:45 pm
by alexblack
Hello.
Giovanni wrote:HI, could you try to assess the maximum size before the problem is triggered, this could be an hint for me. I am convinced that there were several minor defects in that implementation, I found two already this could be the third.
Giovanni

I concluded that the problem does not have a clear dependence on the size of the transmitted data. For example, It depends on the setting of the depth buffer 'SERIAL_USB_BUFFERS_SIZE'. Also, the repetition frequency of the error is random. But the main thing is that the work is stable when writing / reading data size is smaller than the expected device.
For example, if device wait 64 bytes of data:

Code: Select all

rd = chnReadTimeout(&SDU1, &BUFFER[0], 64, MS2ST(10));

that the work is stable if host writes from 1 to 63 bytes data, and non stable if 64 or more. And the greater the amount of data, the more likely a bug.
If I change the 'SERIAL_USB_BUFFERS_SIZE' from 64 to 256, the 64 bytes writes works long period (100'000 packets I tested), but 128 bytes writes not stable. I can't test all sizes because frequency of the errors is random. I wrote new test program for PC. It writes packets in loop with various sizes. But it can't help because errors can occur even after 100,000 cycles, and it requires a large quantity of the time.
In general there is an error, but clearly list the conditions under which it occurs failed. I am sorry.
I just can not understand one thing: this error occurs only me or anyone else just does not care about it. Has anyone else tried to reproduce this error?

Re: Serial over USB problem

Posted: Wed May 15, 2013 6:23 pm
by Giovanni
I failed to reproduce it but I haven't tried hard like you...

From your description it must be some kind of race condition.

Giovanni

Re: Serial over USB problem

Posted: Fri May 17, 2013 10:30 am
by alexblack
Hi.
hackerfoo wrote:For what it's worth, my application with rev. 5737 transfers over 100KB/s, where each high level transaction consists of a small <32B OUT request followed by a >1KB IN response.
I don't see any errors when run through a USB packet analyzer, except a few orphaned IN messages when disconnecting the device; I don't know if this means anything.

Are you using Windows host with STM Virtual Com Port Driver? And you protocol has fixed size packets or various? How many packets in continuous mode do you tested? I tested more than 1'200'000 packets with 256 bytes size for example... Can you list piece of code of MCU where you wait packets? I think the answers on this questions can help me to understand where is my problem.

Re: Serial over USB problem

Posted: Fri May 17, 2013 10:40 pm
by hackerfoo
Yes, I am using a Windows 7 64-bit host with ST's virtual com port driver. My protocol uses a variable sized packet, but for the test, the packet sizes didn't change i.e. the IN packet was always the same size and the OUT packet was the same size (much smaller than IN).

I can't post the code unfortunately. I use chSequentialStreamGet to look for an expected byte, then I use chnReadTimeout to get a fixed size header, which contains the length of the data portion. Then I use chnReadTimeout to get the data portion, and then chnReadTimeout again to get the remaining two byte CRC.

The write is performed with a chSequentialStreamPut, followed by a chSequentialStreamWrite for the header + data, and two chSequentialStreamPut's for the CRC.

I tested hundreds of MB of transferred data. I'm using a STM32F3DISCOVERY board.

Re: Serial over USB problem

Posted: Thu Jun 27, 2013 7:53 pm
by alexblack
Hi.
I tested the same board with another MCU - STM32F407 with the same code - USB works without such problems!
I think the problem is related to STM32F103 only because STM32F407 used another driver. May be this is perfomance problem?

Re: Serial over USB problem

Posted: Mon Jan 19, 2015 4:34 am
by chi0722
I've worked on this issue with exactly the same problem on STM32L151:
SDU1.config->usbp->transmitting(or receiving) bit for the endpoint is raised but STAT_TX(or STAT_RX) remains NAK, which causes the driver cannot transit hardware to VALID state anymore.

I found that if IN and OUT are mapped to the same end point (like USB_CDC example from testhal folder), EPR_CLEAR_CTR_TX()/EPR_CLEAR_CTR_RX() may accidentally eliminate the CTR flag of the other direction when data transmitting in both directions, so driver won't detect the transmission on the other direction is completed(STAT returns to NAK) and it won't handle data and clear bits in SDU1.config->usbp->receiving(or transmitting).
It's caused by the incorrect Read-Modify-Write to clear CTR_TX/CTR_RX, which is warned in the reference manual.

To correctly handle this, we should set CTR bits, which may be modified by hardware anytime, to their "invariant values" before storing back to USB_EPnR to avoid overwriting with the old values.
I made the following change in my code:

Code: Select all

#define EPR_CTR_MASK            (EPR_CTR_TX | EPR_CTR_RX)

#define EPR_SET(ep, epr)                                                     \
  STM32_USB->EPR[ep] = ((epr) & ~EPR_TOGGLE_MASK) | EPR_CTR_MASK

#define EPR_TOGGLE(ep, epr)                                                  \
  STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] ^ ((epr) & EPR_TOGGLE_MASK))      \
                       | EPR_CTR_MASK

#define EPR_SET_STAT_RX(ep, epr)                                             \
  STM32_USB->EPR[ep] = ((STM32_USB->EPR[ep] &                                \
                        ~(EPR_TOGGLE_MASK & ~EPR_STAT_RX_MASK)) ^            \
                       (epr)) | EPR_CTR_MASK

#define EPR_SET_STAT_TX(ep, epr)                                             \
  STM32_USB->EPR[ep] = ((STM32_USB->EPR[ep] &                                \
                        ~(EPR_TOGGLE_MASK & ~EPR_STAT_TX_MASK)) ^            \
                       (epr)) | EPR_CTR_MASK

#define EPR_CLEAR_CTR_RX(ep)                                                 \
  STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] & ~EPR_CTR_RX & ~EPR_TOGGLE_MASK) \
                       | EPR_CTR_TX

#define EPR_CLEAR_CTR_TX(ep)                                                 \
  STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] & ~EPR_CTR_TX & ~EPR_TOGGLE_MASK) \
                       | EPR_CTR_RX



This discussion help me a lot and hope the feedback is useful.
Thanks

Re: Serial over USB problem

Posted: Mon Jan 19, 2015 9:09 am
by Giovanni
Hi,

Thanks for the feedback, I will look into this issue.

Giovanni

Re: Serial over USB problem

Posted: Sat Jan 31, 2015 1:16 pm
by Giovanni
Hi,

I committed your fix, thanks again.

Giovanni

Re: Serial over USB problem

Posted: Sun Feb 22, 2015 9:30 am
by bxm
I've found the same condition while working with CDC on F103. Despite the heavy bidirectional traffic, the problem may not manifest itself for several days. With this fix, it keeps working flawlessly for more than a week now.

Re: Serial over USB problem

Posted: Sun Feb 22, 2015 9:53 am
by Giovanni
Thanks for confirming, it is very stable now.

Giovanni