13 Replies Latest reply on May 6, 2020 8:44 AM by YatheeshK_36

    SuiteUSB using .NET API for PassMark USB 3.0 plug

    MaSy_4695346

      Dear all,

       

      My company has purchased a few PassMark USB 3.0 Loopback plugs.

      The company has an API for C++ for using this plug, but since we mostly develop in C# I asked them if they supplied their API for .NET which they don't.

      However their hardware uses Cypress hardware (they link to Cypress EZ-USB FX3 SDK) so I thought of using the Cypress SDK in conjunction with SuiteUSB 3.4.

       

      So far I've managed to establish a connection and send data back and forth, using SuiteUSB 3.4, over USB and this works fine.

       

      However, there are a few vendor specific (PassMark) commands that I would like to send to the plug.

      I've looked into how this is done in PassMarks C++ console implementation and it works fine.

       

      My idea is to mimic this behaviour using SuiteUSB3.4.

       

      For instance they perform

      double Voltage = 0;

      SendVendorCommand(CurUSBDevice, VENDOR_REQ_READ, GET_VOLTAGE, (UCHAR*)&Voltage, sizeof(Voltage));

       

      bool SendVendorCommand(CCyUSBDevice *USBDevice, USB30_VENDOR RequestType, WORD wValue, UCHAR *buf, LONG buflen)

      {

      CCyControlEndPoint *ept;

      if (USBDevice->IsOpen() == false)

      return false;

      ept = USBDevice->ControlEndPt;

      ept->Target = TGT_DEVICE;

      ept->ReqType = REQ_VENDOR;

      ept->ReqCode = 0x00;

      ept->Value = wValue;

      ept->Index = 0;

      if (RequestType == VENDOR_REQ_READ)

      ept->Read(buf, buflen);

      else

      ept->Write(buf, buflen);

      return true;

      }

       

      which is fairly straight forward for reading the voltage for the device.

       

      I want to perform the same in C#

       

       

      ReadVendorCommand(device, GET_VOLTAGE, sizeof(double));

       

              private byte[] ReadVendorCommand(CyUSBDevice device, ushort wValue, int lengthToRead)

              {

                  var controlEndPoint = device.ControlEndPt;

                  controlEndPoint.Target = TGT_DEVICE;

                  controlEndPoint.ReqType = REQ_VENDOR;

                  controlEndPoint.ReqCode = 0x00;

                  controlEndPoint.Value = wValue;

                  controlEndPoint.Index = 0;

                  controlEndPoint.Direction = 1;

       

       

                  byte[] data = new byte[lengthToRead];

                  var result = controlEndPoint.Read(ref data, ref lengthToRead);

                  if (result) return data;

                  return null;

              }

       

       

      However, the data returned is all zeros (8 of them to be exact) and the lengthToRead (which was 8 when calling controlEndPoint.Read) is now only two bytes.

       

      I've checked and the data and all patterns up to the call seem exactly the same as in the C++ code.

       

      Since SuiteUSB 3.4 has not been updated for some quite some time (9 years) I was wondering if anyone else has any leads or tip that could point me in the right direction to resolve the issue.

       

      Thanks a lot in advance,

      Magnus Sydoff

        • 1. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
          YatheeshK_36

          Hello,

           

          Please try the below in your function:

           

          CyControlEndPoint controlEndPoint = device.ControlEndPt;

          If (controlEndPoint != null)

          {

                      controlEndPoint.Target = CyConst.TGT_DEVICE;

                      controlEndPoint.ReqType = CyConst.REQ_VENDOR;

                      controlEndPoint.ReqCode = 0x00;   

                      controlEndPoint.Value = wValue;

                      controlEndPoint.Index = 0;

                      controlEndPoint.Direction = CyConst.DIR_FROM_DEVICE;

           

                      byte[] data = new byte[lengthToRead];

                      bool result = controlEndPoint.XferData(ref data, ref lengthToRead);

                      if (result) return data;

                      return null;

          }

          else

          return null;

           

           

          Best Regards,

          Yatheesh

          • 2. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
            MaSy_4695346

            Hello,

             

            Thanks for you reply!

            (I realize that I by mistake posted the line controlEndPoint.Direction = 1)

             

            If I look in the CyEndPoints.cs file (which implements the read function) it is already defined as so.

             

                    public bool Read(ref byte[] buf, ref int len)

                    {

                        Direction = CyConst.DIR_FROM_DEVICE;

                        return XferData(ref buf, ref len);

                    }

            • 3. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
              MaSy_4695346

              ..but I tried your suggestion.

               

                      private byte[] ReadVendorCommand(CyUSBDevice device, ushort wValue, int lengthToRead)

                      {

                          var controlEndPoint = device.ControlEndPt;

                          if (controlEndPoint is null) throw new Exception("Endpoint is not available");

                          controlEndPoint.Target = TGT_DEVICE;

                          controlEndPoint.ReqType = REQ_VENDOR;

                          controlEndPoint.ReqCode = 0x00;

                          controlEndPoint.Value = wValue;

                          controlEndPoint.Index = 0;

                          controlEndPoint.Direction = CyConst.DIR_FROM_DEVICE;

               

                          byte[] data = new byte[lengthToRead];

                          var result = controlEndPoint.XferData(ref data, ref lengthToRead);

                          if (result) return data;

                          return null;

                      }

               

               

               

              Unfortunately it is the same result. The data array still contains zeros and lengthToRead is now set to 2 as opposed to previous 8.

               

              Again, thank you for your reply !

               

              King regards
              Magnus

              • 4. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                MaSy_4695346

                Hello again,

                 

                One thing that I notice,  that makes me curious, is that in file CyEndPoints.cs, which implements your suggested function XferData, is that in the section

                 

                  fixed (int* lenTemp = &len)

                                {

                                    bResult = BeginDataXfer(ref tmpBuf, ref *lenTemp, ref ovLap);

                                    wResult = WaitForIO(ovLapStatus->hEvent);

                                    fResult = FinishDataXfer(ref buf, ref tmpBuf, ref *lenTemp, ref ovLap);

                                }

                 

                bResult is always false when I run it whereas wResult and fResult are true.

                Debugging this I can see that the call to PInvoke.DeviceIoControl fails, but it is not entirely clear to me why this happens or if it is a problem since calling function does not take notice of the returned false.

                 

                King regards

                Magnus

                • 5. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                  YatheeshK_36

                  Hello Magnus,

                   

                  Is the vendor command handled in the firmware properly?

                  To verify this please use the control center and do a control IN transfer with the required data filled in the fields. Please let me know if the transfer is successful in the control center.

                   

                   

                  Also, UsbdStatus member contains the error code returned from the last XferData or BeginDataXfer call.

                  Please let me know what is returned by the usbdStatus. you can refer to the CyUSB.NET.pdf document from the FX3 SDK for the API details.

                   

                  Thanks,

                  Yatheesh

                  • 6. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                    MaSy_4695346

                    Hello Yatheesh,

                     

                    Thank you again for your prompt reply !

                     

                    This is the reply from the USB Control center.

                     

                     

                    When I run the code in the C++ project that is working this is what is being sent......

                     

                     

                    ... and this is the reply I get when asking for the current USB voltage.

                     

                     

                     

                     

                    When calling BeginDataXfer the

                     

                    _lastError = (uint)Marshal.GetLastWin32Error();

                     

                    is 997

                     

                     

                    Again, thank you for helping out !

                     

                     

                    King regards

                    Magnus

                    • 7. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                      MaSy_4695346

                      ....and in hex for your convenience... 

                       

                       

                      • 8. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                        MaSy_4695346

                        From CyEndPoint.cs when running

                         

                         

                         

                         

                        • 9. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                          YatheeshK_36

                          Hello,

                           

                          Looks like there is a problem setting the configuration or in passing the arguments.

                           

                          Please use the code below without changing inside your function:

                           

                          var controlEndPoint = device.ControlEndPt;

                          CyControlEndPoint ctrlEpt = controlEndPoint as CyControlEndPoint;

                          if (ctrlEpt is null) throw new Exception("Endpoint is not available");

                          else

                          {

                          ctrlEpt .Direction = CyConst.DIR_FROM_DEVICE;

                          ctrlEpt .Target = CyConst.TGT_DEVICE;

                          ctrlEpt .ReqType = CyConst.REQ_VENDOR;

                          ctrlEpt .ReqCode = 0x00;

                          ctrlEpt .Value = 0x0007;

                          ctrlEpt .Index = 0;

                          ctrlEpt .TimeOut = 3000;

                           

                          int len = 8;

                          byte[] data = new byte[len];

                          bool result = controlEndPoint.XferData(ref data, ref len );

                          if (result)

                          return data;

                           

                          return null;

                          }

                           

                          Please let me know if this works, and the value returned by the XferData function.

                           

                          Thanks,

                          Yatheesh

                          1 of 1 people found this helpful
                          • 10. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                            MaSy_4695346

                            Hello Yatheesh,

                             

                            This looks really good !!!

                            I'm getting the voltage back now !!

                             

                            I see that the ReqType is different and you added a timeout !!

                             

                             

                             

                             

                            I realize that the PassMark console application had a different value for ReqType which is probably what threw me under the bus....

                            Currently I have no idea why that works, but you helping me along the way is great !!

                             

                             

                             

                            Anyway, I hope that this means that I can continue my development !

                             

                            Thank you very much for your support !!!

                             

                            King regards

                            Magnus

                            • 11. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                              MaSy_4695346

                              ...and it works great without the timeout (i.e. using the default) and using the Read function !!

                               

                              The problem was the ReqType all along... 

                               

                              This is my final version.

                               

                              • 12. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                                MaSy_4695346

                                Confusing as it is....

                                 

                                ReqType seems to be defined as 2 unless I don't understand C++ at all (which of course is quite possible.... )

                                 

                                • 13. Re: SuiteUSB using .NET API for PassMark USB 3.0 plug
                                  YatheeshK_36

                                  Hello Magnus,

                                   

                                  It's great to see that the application is working !!

                                  There are few differences in implementing CyAPI.lib for C++ and CyUSB.dll for C#.

                                  The Timeout can be removed as it is not necessary for control transfers.

                                  Best wishes on the development with our product and please do create threads on community in case you face any issues.

                                   

                                  Best Regards,

                                  Yatheesh