Serial over USB problem

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

alexblack
Posts: 277
Joined: Mon Sep 24, 2012 3:52 pm
Been thanked: 33 times

Re: Serial over USB problem

Post 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?
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial over USB problem

Post 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
alexblack
Posts: 277
Joined: Mon Sep 24, 2012 3:52 pm
Been thanked: 33 times

Re: Serial over USB problem

Post 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.
hackerfoo
Posts: 7
Joined: Thu May 09, 2013 9:42 pm

Re: Serial over USB problem

Post 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.
alexblack
Posts: 277
Joined: Mon Sep 24, 2012 3:52 pm
Been thanked: 33 times

Re: Serial over USB problem

Post 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?
chi0722
Posts: 1
Joined: Mon Jan 19, 2015 3:44 am

Re: Serial over USB problem

Post 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
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial over USB problem

Post by Giovanni »

Hi,

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

Giovanni
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial over USB problem

Post by Giovanni »

Hi,

I committed your fix, thanks again.

Giovanni
bxm
Posts: 6
Joined: Fri Jun 08, 2012 11:26 am

Re: Serial over USB problem

Post 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.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial over USB problem

Post by Giovanni »

Thanks for confirming, it is very stable now.

Giovanni
Post Reply