4 Replies Latest reply on Mar 19, 2018 6:39 AM by samp

    Trouble on CY8C24493-24LTXI and BL_USBFS USB Bus Reset

    user_588373

      I have implemented a composite bootloadable USBFS device consisting of 2 interfaces.

       

      Interface 1 implements a HID 'boot protocol' keyboard

      Interface 2 implements a HID 'report protocol' wheel mouse and multimedia keys

       

      I have been able to successfully hot-plug the device into a working Linux or Windows OS and it works flawlessly.

       

      The same device though, when connected with some machines, will simply freeze when it is at the BIOS setup screen or the UEFI boot screen

       

      I have narrowed the problem down to the USB bus reset that does not seem to happen.  On some hosts, unplugging and re-plugging in the device seems to get it to comply.

       

      The vector _BL_USBFS_RESET_ISR never seems to trigger.  I have confirmed this by implementing visual aids on the Reset_ISR.  The aid should trigger if the ISR is triggered, else the aid should show an enumeration.  Neither of these 2 happens.

       

      The only way out of this freeze is to either hard reset the controller or recycle power.

       

      Question : Does anyone have some clue as to how to ensure that the PSOC1 does not freeze when a USB bus reset comes its way ?  Any suggestions gratefully accepted.

       

      void main(void)
      {
          M8C_EnableGInt;                      //Enable Global Interrupts
          BL_USBFS_Start(0, USB_5V_OPERATION); //Start USB Operation using device 0
          InitUsb();
          Red_Data_ADDR = 0x00;
          Intensity = 0;
          while(1)     // Main loop 
          {
              if (!UsbState)
              {
                  if (BL_USBFS_bGetConfiguration())
                  {
                      UsbState=USBENUM;
                      Tred =Intensity=2; Color=0;
                  }
              }
              else
              {
                  Task_Kbd();
              }
          }             // End While
      }
      This is a snippet of the contents of Task_Kbd
          // if the USB_KBD_ENDPOINT has been acked, send more data
          if (isbit(RptStatus,RS_Kbd))                              // there is data to send, this flag is set
          {
              if (!(UsbState & KBEP))                                    // if the EndPoint has not been written to as yet, this will be 0
              {
                  BL_USBFS_LoadInEP(USB_KBD_ENDPOINT, (BYTE *)&keyboard_report, sizeof(keyboard_report), USB_TOGGLE);
                  UsbState |= KBEP;
              }
              else
              {
                  if (BL_USBFS_bGetEPAckState(USB_KBD_ENDPOINT))           // if the endpoint is acknowledged, write to it again
                  {
                      // send KBD report on EP1
                      BL_USBFS_LoadInEP(USB_KBD_ENDPOINT, (BYTE *)&keyboard_report, sizeof(keyboard_report), USB_TOGGLE);
                      bitclr(RptStatus,RS_Kbd);                          // and clear the flag
                  }
              }
          }
          // if MM endpoint is open, send its data
          if (!(UsbState & MMEP))                                           // in case only the boot keyboard is working, this part will evaluate to 0
          {                                                                                 // it will send a packet but never get ack'ed and never send again to EP2
              BL_USBFS_LoadInEP(USB_MM_ENDPOINT, (BYTE*)&mouse_report, sizeof(mouse_report), USB_TOGGLE);
              UsbState |= MMEP;
          }
          else
          {
              // NAK, go back
              if (!BL_USBFS_bGetEPAckState(USB_MM_ENDPOINT)) return;
              
              // send mouse report
              if (isbit(RptStatus,RS_Mouse))
              {
                  BL_USBFS_LoadInEP(USB_MM_ENDPOINT, (BYTE*)&mouse_report, sizeof(mouse_report), USB_TOGGLE);
                  bitclr(RptStatus,RS_Mouse);
                  return;
              }
          }
              

      Regards

      Jerson

       

       

        • 1. Re: Trouble on CY8C24493-24LTXI and BL_USBFS USB Bus Reset
          user_588373

          Just in case you are wondering - here's some additional info

          What if I use just one interface for boot keyboard?  Does it still freeze?  -  Yes it does.

           

          Again, the reason for the freeze is a USB bus reset.  This can be confirmed by forcing a  USB reset to the device

           

          /* usbreset -- send a USB port reset to a USB device

          https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line#661

          run the following commands in terminal:

              Compile the program:

              $ cc usbreset.c -o usbreset

              Get the Bus and Device ID of the USB device you want to reset:

              $ lsusb

            Bus 002 Device 003: ID 0fe9:9010 DVICO

           

              Make our compiled program executable:

           

              $ chmod +x usbreset

           

              Execute the program with sudo privilege; make necessary substitution for <Bus> and <Device> ids as found by running the lsusb command:

           

              $ sudo ./usbreset /dev/bus/usb/002/003

          */

           

          #include <stdio.h>

          #include <unistd.h>

          #include <fcntl.h>

          #include <errno.h>

          #include <sys/ioctl.h>

           

          #include <linux/usbdevice_fs.h>

           

           

          int main(int argc, char **argv)

          {

              const char *filename;

              int fd;

              int rc;

           

              if (argc != 2) {

                  fprintf(stderr, "Usage: usbreset device-filename\n");

                  return 1;

              }

              filename = argv[1];

           

              fd = open(filename, O_WRONLY);

              if (fd < 0) {

                  perror("Error opening output file");

                  return 1;

              }

           

              printf("Resetting USB device %s\n", filename);

              rc = ioctl(fd, USBDEVFS_RESET, 0);

              if (rc < 0) {

                  perror("Error in ioctl");

                  return 1;

              }

              printf("Reset successful\n");

           

              close(fd);

              return 0;

          }

          • 2. Re: Trouble on CY8C24493-24LTXI and BL_USBFS USB Bus Reset
            user_588373

            Another important update.

             

            The precise location seems to be the call to BL_USBFS_bGetConfiguration()

             

            After a bus reset, this function does not show configured again (return value = 0)

             

            What could be the cause for this?

             

            Regards

            Jerson

            • 3. Re: Trouble on CY8C24493-24LTXI and BL_USBFS USB Bus Reset
              user_588373

              The problem was fixed by commenting out line 1510 in the std_dev.asm file

               

              Attached screenshot shows the offending line.

               

              I would say this problem is solved here, but, I need to modify the template code so that a Build (F6) does not undo the change.

               

              Regards

              Jerson

              USB_bus_reset_soln.GIF

              • 4. Re: Trouble on CY8C24493-24LTXI and BL_USBFS USB Bus Reset
                samp

                Hello Jerson,

                 

                There are two approaches.

                 

                 

                The first is to lock the User Module from the Workspace Explorer, by right clicking on the BootLdrUSBFS User Module, and then selecting "Lock". This way, PSoC Designer will not regenerate the code for this User Module.

                 

                 

                The second is to change the template code for this BootLdrUSBFS. You can find this under "Installation Folder/PSoC Designer/5.4/Common/CypressSemiDeviceEditor/Data/Stdum/BootLdrUSBFS". Usually the installation folder is "C:\Program Files\Cypress".

                 

                Sampath