3 Replies Latest reply on Sep 26, 2018 2:11 AM by SrinathS_16

    Bulk Endpoint Transfer Hangs on Win7 but not Win10

    JuCh_3556216

      Hi everyone,

       

      I'm running into an odd issue between Windows 7 and Windows 10 bulk transfers on a EZ-USB FX3 evaluation board. On a Windows 10 machine, the bulk endpoint (set up as a manual DMA channel) properly receives data, sends data out to the SPI bus on the FX3, and buffers the response to subsequently be read back to the PC. In Windows 7, the USB driver hangs when reading data from the PC into the FX3 and renders anything connected to the USB hub the FX3 is connected to inoperable until the PC is rebooted. In both cases, same firmware, software, driver version, etc. is used. The following is the function call in the FX3 firmware that causes the issue.

       

      CyU3PReturnStatus_t BulkByteTransfer(uint16_t numBytes, uint16_t bytesPerCapture)
      {
          CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
          uint16_t loopCounter = 0;
          uint8_t buffValue;
          uint8_t *bufPntr;
          uint8_t TxBuffer[2];
          uint32_t transferStatus = 0;
          PinWaitType waitType = LowToHigh;
      
          //Transfer in data via ChannelFromPC
          ManualDMABuffer.buffer = BulkBuffer;
          ManualDMABuffer.size = 12288;
          ManualDMABuffer.count = numBytes;
          //ManualDMABuffer.status = 0;
      
          status = CyU3PDmaChannelSetupRecvBuffer(&ChannelFromPC, &ManualDMABuffer);
      
          //Wait for the DMA channel to finish (20ms timeout)
          while(transferStatus != CY_U3P_DMA_CB_RECV_CPLT && loopCounter < 4)
          {
              CyU3PEventGet(&(ChannelFromPC.flags), CY_U3P_DMA_CB_RECV_CPLT,  CYU3P_EVENT_OR, &transferStatus, 5);
              loopCounter++;
          }
      
          //Reset the DMA channel
          CyU3PDmaChannelReset(&ChannelFromPC);
      
          //Set the bytesPerCapture depending on DrActive
          if(!DrActive)
          {
              bytesPerCapture = numBytes;
          }
          else
          {
              //Set the transition type depending on the DrPolarity
              if(DrPolarity)
              {
                  waitType = LowToHigh;
              }
              else
              {
                  waitType = HighToLow;
              }
          }
      
          //Loop through rest of the transfers
          bufPntr = BulkBuffer;
          loopCounter = 0;
          while(loopCounter < numBytes)
          {
              //Wait for data ready if needed and run through one set of registers
              if(DrActive)
              {
                  WaitForPin(dataReadyPin, waitType);
              }
              //For first transfer don't read back
              if(BulkBuffer[loopCounter] & 0x80)
              {
                  //Case of a SPI write
                  TxBuffer[0] = BulkBuffer[loopCounter];
                  TxBuffer[1] = BulkBuffer[loopCounter + 1];
                  CyU3PSpiTransmitWords(TxBuffer, 2);
                  BulkBuffer[loopCounter] = 0;
                  BulkBuffer[loopCounter + 1] = 0;
              }
              else
              {
                  //Case of a SPI read
                  TxBuffer[0] = BulkBuffer[loopCounter];
                  TxBuffer[1] = 0;
                  CyU3PSpiTransmitWords(TxBuffer, 2);
              }
              loopCounter+=2;
              WaitForTimerTicks(stallTime);
      
              //Loop through rest of the reads
              while(loopCounter < bytesPerCapture)
              {
                  //Get the value out of the bulk buffer
                  buffValue = BulkBuffer[loopCounter];
      
                  if(buffValue & 0x80)
                  {
                      //If its a write command, perform write
                      //perform SPI write
                      TxBuffer[0] = buffValue;
                      TxBuffer[1] = BulkBuffer[loopCounter + 1];
                      CyU3PSpiTransmitWords(TxBuffer, 2);
                      //Store 0 in the Bulk Buffer
                      BulkBuffer[loopCounter] = 0;
                      BulkBuffer[loopCounter + 1] = 0;
                  }
                  else
                  {
                      //If it's a read command, perform SPI read and write and store value in bulk buffer
                      TxBuffer[0] = buffValue;
                      TxBuffer[1] = 0;
                      CyU3PSpiTransferWords(TxBuffer, 2, bufPntr, 2);
                  }
                  bufPntr += 2;
                  loopCounter += 2;
                  WaitForTimerTicks(stallTime);
              }
              //Receive the last two bytes
              if(buffValue & 0x80)
              {
                  BulkBuffer[loopCounter] = 0;
                  BulkBuffer[loopCounter + 1] = 0;
              }
              else
              {
                  CyU3PSpiReceiveWords(bufPntr, 2);
              }
              //Increment loop counter
              loopCounter += 2;
          }
      
          //Send the data back over ChannelToPC
          status = CyU3PDmaChannelSetupSendBuffer(&ChannelToPC, &ManualDMABuffer);
      
          return status;
      }
      
      

       

      I've attempted to disable USB SS mode since the Windows 7 PC's we've used for testing all don't have 3.0 capability, but haven't noticed a difference. Has anyone run into an issue like this? We're also noticing that on certain machines, even though they're running Windows 7, if they have a USB 3.0 controller present in Device Manager the code shown above will work correctly.

       

      Thanks!