• AVR Freaks

Receive Vendor-Specific control commands on 18F4550

Author
JawadMax
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2012/02/05 12:38:32
  • Location: 0
  • Status: offline
2012/02/05 13:23:29 (permalink)
0

Receive Vendor-Specific control commands on 18F4550

Hello everyone;

  I have a host device that sends vendor-specific control transfers and I want my PIC to be able to receive and process them in a specific way. 
  My problem is I don't know how to receive such transfers. So, what's the best way to receive them? I haven't actually found any mentioning to vendor-specific control commands in the whole framework. Can anyone please address me to the method or the changes that I have to make in order to be able to receive those kinds of transfers. 

btw, I have set up the descriptors correctly to identify my PIC as vendor-specific class because I actually have a device that is able to receive the commands (but I don't have its source code) so I tried to replicate it's descriptor and configure the whole project to use the descriptor correctly. Most of the transfers (bulk / interrupt transfers) worked fine except the vendor specific control transfers. 



Thanks
Max
post edited by JawadMax - 2012/02/05 13:29:06
#1

9 Replies Related Threads

    newfound
    Super Member
    • Total Posts : 1830
    • Reward points : 0
    • Joined: 2003/11/07 12:35:49
    • Status: online
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/05 14:22:12 (permalink)
    0

    Vendor class requests can be hooked in this function in main.c

    void USBCBCheckOtherReq(void)
    {
       USBCheckVendorRequests();  // <- Add this
    }//end


    void USBCheckVendorRequests(void)
    {
        if(SetupPkt.Recipient != USB_SETUP_TYPE_VENDOR_BITFIELD) return;

    // Process vedor requests here

    }

    As I do not use the microchip USB stack myself and nor have I ever used vendor class requests in any of my stacks I have limited knowledge to assist you with but however hopefully this is at least a start for you to build on.
    #2
    JawadMax
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2012/02/05 12:38:32
    • Location: 0
    • Status: offline
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/06 11:12:21 (permalink)
    0
    Thank you very much newfound for the reply;

    I tried your method and it worked with little modification. Now I'm receiving a vendor-specific command of bmRequestType=0xC1, bRequest=0x81, wValue=0x17, wIndex=0x03, wLength=0x1D. That means it has data associated with it, right?

    Now I'm wondering how can I get access to the data with that control transfer? The info I mentioned above were from the SetupPkt.xxxx, but I didn't find way to access the data that's associated with the packet.

    oh, another little question. Does wIndex have a standard purpose or does it's purpose vary from vendor-specific application to another?


    Thanks
    Max 
    post edited by JawadMax - 2012/02/06 11:17:41
    #3
    Pacer
    Super Member
    • Total Posts : 1171
    • Reward points : 0
    • Joined: 2004/12/01 09:29:20
    • Status: offline
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/06 11:49:11 (permalink)
    0
     Well, as that is a request for the device to supply data then it is up to you to provide it. It sounds like you need to capture a typical session between a host and this device, whatever it is, with an analyser, and then at least you will have some typical replies to send when asked. Reverse engineering can be quite difficult.
    #4
    JawadMax
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2012/02/05 12:38:32
    • Location: 0
    • Status: offline
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/06 12:46:26 (permalink)
    0
    Thank you Pacer for the quick reply;

      I actually know what data to send, I sniffed the device response. But what I'm struggling with now is how to read the data associated with the control transfer. At this point I can read the control message and from that message I know that it contains some data (wLength=0x1D) that I also have to receive from the host. but I don't know how to get access that data :( 

    Thanks
    post edited by JawadMax - 2012/02/06 15:52:39
    #5
    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/06 22:21:34 (permalink)
    0

    I know that it contains some data (wLength=0x1D) that I also have to receive from the host.

    As the MSbit of bmRequestType (0xC1) is '1', the direction of this request is IN (device --> host). Your firmware has to send the data to host.

    A typical implementation looks like,

    void USBCBCheckOtherReq(void) 

       USBCheckVendorRequests();  // <- Add this 
    }//end 


    #define VENDOR_REPLY_SIZE   0x1D

    BYTE vendor_reply[ VENDOR_REPLY_SIZE ];

    void USBCheckVendorRequests(void) 

        if ( (SetupPkt.bmRequestType == 0xC1)
          && (SetupPkt.bRequest      == 0x81)
          && (SetupPkt.wValue        == 0x17)
          && (SetupPkt.wIndex        == 0x03)
          && (SetupPkt.wLength       == VENDOR_REPLY_SIZE)
           ) {
              //
              // fill vendor_reply[] array with your reply, here.
              //
              USBEP0SendRAMPtr( vendor_reply, VENDOR_REPLY_SIZE, USB_EP0_NO_OPTIONS );
        }
    }


    Does wIndex have a standard purpose or does it's purpose vary from vendor-specific application to another?

    In good USB practice, wIndex indicates recipient interface number, when the Recipient field of bmRequestType is Interface (for Vendor request, bmRequestType = 0xC1 or 0x41).

    But implementation doesn't always follow this USB practice.

    Tsuneo
    #6
    JawadMax
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2012/02/05 12:38:32
    • Location: 0
    • Status: offline
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/06 22:28:19 (permalink)
    0
    Thank you Tsuneo for the response, you're solver for every problem!

    I noticed that the data has to be sent to the host, and after sending the same control command to the device I wanted to clone, I received data! and after some digging I was able to send it back successfully.

      My problem now is that I got control transfer with bmRequestType = 0x41 and wLength=0x0022! and I would like to access the data associated with it. I don't even know how many bytes are sent (except my knowing about them from the command itself). I checked outPipes[0].wCount.Val and it's obviously 0 because of USBCtrlTrfRxService(). So what's the best way to get the data from that control command and where it's stored in?  


    Thank you very much
    Max
    post edited by JawadMax - 2012/02/06 22:36:50
    #7
    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/06 23:53:22 (permalink)
    0

    Above snippet is modified as follows, for your new request wink


    void USBCheckVendorRequests( void );        // prototypes
    void USBVendorReceiveComplete( void );

    void USBCBCheckOtherReq(void) 

       USBCheckVendorRequests();  // <- Add this 
    }//end 


    #define VENDOR_REPLY_SIZE   0x1D
    #define VENDOR_OUT_SIZE     0x22

    BYTE vendor_buffer[ VENDOR_OUT_SIZE ];     // common working buffer for Vendor request

    void USBCheckVendorRequests(void) 

        if ( (SetupPkt.bmRequestType == 0xC1)
          && (SetupPkt.bRequest      == 0x81)
          && (SetupPkt.wValue        == 0x17)
          && (SetupPkt.wIndex        == 0x03)
          && (SetupPkt.wLength       == VENDOR_REPLY_SIZE)
           ) {
              //
              // fill vendor_buffer[] array with your reply (0x1D), here.
              //
              USBEP0SendRAMPtr( vendor_buffer, VENDOR_REPLY_SIZE, USB_EP0_NO_OPTIONS );
        }

        if ( (SetupPkt.bmRequestType == 0x41)
          && (SetupPkt.bRequest      == ???)  // replace ??? with actual value
          && (SetupPkt.wValue        == ???)
          && (SetupPkt.wIndex        == ???)
          && (SetupPkt.wLength       == VENDOR_OUT_SIZE)
           ) {
                              // register a receive buffer and a completion callback to the stack
              USBEP0Receive( vendor_buffer, VENDOR_OUT_SIZE, USBVendorReceiveComplete );
        }
    }

    void USBVendorReceiveComplete( void )
    {
        //
        // When this callback is called from the stack,
        // vendor_buffer[] holds received data (size = 0x22) from host
        // Process the data, here
        //
    }


    Tsuneo
    #8
    bytencoder
    Super Member
    • Total Posts : 363
    • Reward points : 0
    • Joined: 2009/06/25 12:30:07
    • Location: 0
    • Status: offline
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/07 06:03:37 (permalink)
    0
    JawadMax
    ... I got control transfer with bmRequestType = 0x41 and wLength=0x0022! and I would like to access the data associated with it. I don't even know how many bytes are sent ....


    For host-to-device requests the data length is precisely the value in wLength.
    #9
    JawadMax
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2012/02/05 12:38:32
    • Location: 0
    • Status: offline
    Re:Receive Vendor-Specific control commands on 18F4550 2012/02/16 11:26:33 (permalink)
    0
    chinzei

    Above snippet is modified as follows, for your new request wink


    void USBCheckVendorRequests( void );        // prototypes
    void USBVendorReceiveComplete( void );

    void USBCBCheckOtherReq(void) 

     USBCheckVendorRequests();  // <- Add this 
    }//end 


    #define VENDOR_REPLY_SIZE   0x1D
    #define VENDOR_OUT_SIZE     0x22

    BYTE vendor_buffer[ VENDOR_OUT_SIZE ];     // common working buffer for Vendor request

    void USBCheckVendorRequests(void) 

      if ( (SetupPkt.bmRequestType == 0xC1)
        && (SetupPkt.bRequest      == 0x81)
        && (SetupPkt.wValue        == 0x17)
        && (SetupPkt.wIndex        == 0x03)
        && (SetupPkt.wLength       == VENDOR_REPLY_SIZE)
         ) {
            //
            // fill vendor_buffer[] array with your reply (0x1D), here.
            //
            USBEP0SendRAMPtr( vendor_buffer, VENDOR_REPLY_SIZE, USB_EP0_NO_OPTIONS );
      }

      if ( (SetupPkt.bmRequestType == 0x41)
        && (SetupPkt.bRequest      == ???)  // replace ??? with actual value
        && (SetupPkt.wValue        == ???)
        && (SetupPkt.wIndex        == ???)
        && (SetupPkt.wLength       == VENDOR_OUT_SIZE)
         ) {
                            // register a receive buffer and a completion callback to the stack
            USBEP0Receive( vendor_buffer, VENDOR_OUT_SIZE, USBVendorReceiveComplete );
      }
    }

    void USBVendorReceiveComplete( void )
    {
      //
      // When this callback is called from the stack,
      // vendor_buffer[] holds received data (size = 0x22) from host
      // Process the data, here
      //
    }


    Tsuneo


    for(int i=0;i>=0;i++){
     printf("Thank you very much !\n");
    }

    After you're finished with that infinite loop of thank-you's I wanted to thank you again for your help. without it, I would've been stuck at that problem forever. Every problem I faced before and someone asked it before me, I found that you answered and provided an awesome code just like the one you provided.

    I also want to thank newfound, Pacer, and bytencoder; thanks guys for the help, I really appreciate it.

    Once again I really wanted to thank you Master  Tsuneo for all your help for me and the other members here. 
    I hope you enjoy your time and have an infinitely happy life :)

    Max
    post edited by JawadMax - 2012/02/16 11:31:36
    #10
    Jump to:
    © 2019 APG vNext Commercial Version 4.5