cancel
Showing results for 
Search instead for 
Did you mean: 

In the STM32H503 USB device mode, SOF interrupts are periodically lost

lugama
Associate II

In STM32H503 USB device mode, I found that SOF interrupts are periodically lost, SOF interrupts trigger normally in about 300ms,then SOF interrupts does not trigger in the next 300ms,and so on, if ESOF interrupt are enabled, ESOF interrupt will trigger periodcally, I have checkd usb bus with logic analyzer, and the SOF signal always appers within 1ms ,there is no SUSPEND or RESET signal, What's wrong?

1 ACCEPTED SOLUTION

Accepted Solutions
FBL
ST Employee

Hi @lugama 

>The code was ported from the USB package of STM3210E.

Could you reproduce with USB classic stack STMicroelectronics/stm32h5-classic-coremw-apps: Provide a set of applications for STM32H5xx series based on the STM32 Classic Core Middleware libraries. (github.com)

I am suspecting the porting since it's a different product, we should stick to library dedicated for this controller.

I found a similar erratum for an old revision which is not exactly the same issue: ESOF interrupt timing desynchronized after resume signaling.
Upon signaling resume, the device is expected to allow full 3ms of time to the host or hub for sending the initial SOF (start of frame) packet, without triggering SUSP interrupt. However, the device only allows two full
milliseconds and unduly triggers SUSP interrupt if it receives the initial packet within the third millisecond.

Workaround: When the device initiates resume (remote wakeup), mask the SUSP interrupt by setting the SUSPM bit for 3 ms, then unmask it by clearing SUSPM.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

3 REPLIES 3
FBL
ST Employee

Hi @lugama 

 

Do you mean your device is experiencing periodic ESOF interrupts without corresponding SOF losses? Could you share the capture? Could you reproduce on nucleo board? This may point to a synchronization issue to process the incoming SOF packets.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

lugama
Associate II

Hi, FBL

Thank you for your reply. Yes, my board entered the ESOF interrupt without losing any SOF. What I mean is that from the USB BUS waveform, there was no loss of SOF, but from the MCU, the SOF interrupt was periodically lost, with a period of about 300ms. Therefore, I suspect that the MCU did not detect SOF, which caused the ESOF interrupt. I don't know why the MCU intermittently did not detect SOF. I used the STM32H5 Nucleo-64 board (MB1814), and I have reproduced this issue on different computers. The code was ported from the USB package of STM3210E.

The following are the interrupt handling codes for SOF and ESOF in the USB interrupt function. In the code, I used the variable esof_resetcount to limit the number of times the device initiates USB RESET during ESOF, otherwise the device will continuously initiate USB RESET

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SOF)
if (wIstr & ISTR_SOF & wInterrupt_Mask)
{
  _SetISTR((uint16_t)CLR_SOF);
  bIntPackSOF++;
  printf("*");
#ifdef SOF_CALLBACK
  SOF_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
if (wIstr & ISTR_ESOF & wInterrupt_Mask)
{
  uint32_t fnr = GetFNR();
  /* clear ESOF flag in ISTR */
  _SetISTR((uint16_t)CLR_ESOF);
  printf("e");
  if ((fnr&FNR_RXDP)!=0 && ++esof_resetcount < 1000)
  {
    // esof_resetcount = 0;
    /* increment ESOF counter */
    esof_counter ++;
    // /* test if we enter in ESOF more than 3 times with FSUSP =0 and RXDP =1=>> possible missing SUSP flag*/
    if ((esof_counter >3)&&((_GetCNTR()&CNTR_FSUSP)==0))
    {
      // /* this a sequence to apply a force RESET*/
      /*Store CNTR value */
      wCNTR = _GetCNTR();

      /*Store endpoints registers status */
      for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i);

      /*apply FRES */
      wCNTR|=CNTR_FRES;
      _SetCNTR(wCNTR);

      /*clear FRES*/
      wCNTR&=~CNTR_FRES;
      _SetCNTR(wCNTR);

      /*poll for RESET flag in ISTR*/
      while((_GetISTR()&ISTR_RESET) == 0);

      /* clear RESET flag in ISTR */
      _SetISTR((uint16_t)CLR_RESET);

      /*restore Enpoints*/
      for (i=0;i<8;i++)
        _SetENDPOINT(i, EP[i]);
      printf("r");
      esof_counter = 0;
    }
  }
  else
  {
    esof_counter = 0;
  }

  /* resume handling timing is made with ESOFs */
  Resume(RESUME_ESOF); /* request without change of the machine state */
  #ifdef ESOF_CALLBACK
  ESOF_Callback();
#endif
}

 

FBL
ST Employee

Hi @lugama 

>The code was ported from the USB package of STM3210E.

Could you reproduce with USB classic stack STMicroelectronics/stm32h5-classic-coremw-apps: Provide a set of applications for STM32H5xx series based on the STM32 Classic Core Middleware libraries. (github.com)

I am suspecting the porting since it's a different product, we should stick to library dedicated for this controller.

I found a similar erratum for an old revision which is not exactly the same issue: ESOF interrupt timing desynchronized after resume signaling.
Upon signaling resume, the device is expected to allow full 3ms of time to the host or hub for sending the initial SOF (start of frame) packet, without triggering SUSP interrupt. However, the device only allows two full
milliseconds and unduly triggers SUSP interrupt if it receives the initial packet within the third millisecond.

Workaround: When the device initiates resume (remote wakeup), mask the SUSP interrupt by setting the SUSPM bit for 3 ms, then unmask it by clearing SUSPM.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.