This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to process OUT Vendor Request with data stage

Hello, dear experts.
I have a problem with the USB component ver 6.5 of MDK-Professional Middleware.
I'm developing vendor specific device and I use USB0 of the microcontroller LPC4337JBD144. I use USB component ver 6.5.
After sending OUT Vendor Request with data stage it's impossible to process any IN Vendor Request. It looks as if it's processed successfully in my firmware program (it continues to work), but my PC application just freezes and waits for a response of a driver untill I detach my device or reset it using debugger.
I added a file "USBD_User_Device_0.c" to my project and modified it in order to process Vendor specific Requests. I changed a callback function the next way

usbdRequestStatus USBD_Device0_Endpoint0_SetupPacketReceived (const USB_SETUP_PACKET *setup_packet, uint8_t **buf, int32_t *len)
{
  switch (setup_packet->bmRequestType.Type) {
    ...
    case USB_REQUEST_VENDOR:
      switch (setup_packet->bmRequestType.Recipient){
        case USB_REQUEST_TO_DEVICE:
          switch (setup_packet->bRequest){
            ... // some code
            case USB_VEND_REQ_LONG_COMM:   // bRequest = 4
              CommStruct.CommLength = setup_packet->wLength;
              CommStruct.RespLength = setup_packet->wIndex;
              // When I call this function, the problem appears. Without calling it everything works properly
              usbReadStat = USBD_EndpointRead(0,       USB_ENDPOINT_OUT(0), CommStruct.CommBuff, 64/*CommStruct.CommLength*/);
              // Here you can see that I tried different ways to solve the problem. I waited, aborted transition, but nothing helped me.
              //while (USBD_EndpointReadGetResult(0, 0x00) != CommStruct.CommLength);
              //USBD_EndpointAbort(0, USB_ENDPOINT_OUT(0));
              ... // some code
              break;
          }
      }
      break;
  }
}

I have to add, that OUT Vendor Requests without data stage are processed successfully even after OUT Vendor Requests with data stage.
I use the toolchain MDK-ARM Professional version 5.14.0.0 and Windows 7 64-bit.
Thank you for any help.

Parents
  • Continuation of previous post as it was too long ...

    > For a CTRL IN transfer, i.e. the host sends a setup packet and requests data to be sent from
    > the device to the host.
    >
    > --> Middleware calls

    USBD_Device0_Endpoint0_SetupPacketReceived (const USB_SETUP_PACKET *setup_packet, uint8_t
    **buf, int32_t *len)
    

    > --> User (me) has to check if the request is for the user (me) If yes, user (me) has to
    > provide the data in a buffer and point **buf to this buffer, the return value for len has to
    > be set to the buffer size or the size of setup_packet->wLength, whichever is lower. Please
    > advise.
    Yes. If you handle more requests you need to store that information in setup stage so that on
    data stage you know for which request that data is for.

    > An optional flag can be set from the user for the user for later use in

    USBD_Device0_Endpoint0_InDataSent(int32_t len)
    


    Yes, as mentioned to determine which request is being handled.

    > --> A few 100us later the Middleware will call
    When the data was actually sent.

    USBD_Device0_Endpoint0_InDataSent(int32_t len)
    


    Yes.

    > Now user (me) knows that the data is read from the buffer and sent over the USB so that user
    > can reuse the buffer again. Correct?
    Yes.

    > The parameter len provides information on how much bytes were sent this time? Please advise.
    > What do I do when len is smaller than the buffer I wanted to send?
    This should not happen as Host will poll for all the data it expects to get unless transfer is terminated with short packet, ZLP or STALL, and it should get all the data you provided in your buffer. This situation only is produced by Windows when it first requests Device descriptor and if max packet size of device is less than 18 bytes which is size of device descriptor then it terminates that request by OUT ZLP and resets the device.

    > There is nothing else to do at this moment from the point of view of the middleware. Correct?
    Yes.

    > The return value shall be usbdRequestOK. Correct? Again the question: Under what
    > circumstances shall I return usbdRequestNotProcessed, usbdRequestOK, usbdRequestStall,
    > usbdRequestNAK?
    Same as in case of before-mentioned OUT callback to provide response for the status stage.

    > Please point out what is the idea behind the concept of the middleware, a simple function
    > reference without having an idea how an when to use the functions with what parameters and
    > what return values is not enough, at least for me.
    The idea is to allow users to tailor and implement any kind of device and answer any requests coming to device, with hiding the complexity of generating descriptors handling standard requests and interacting with low level driver that is standardized (by CMSIS) so interchangeable.
    Unfortunately, custom class implementation requires deep understanding of the USB itself and is generally meant to be used in rare occasions.

    Best regards, Milorad

Reply
  • Continuation of previous post as it was too long ...

    > For a CTRL IN transfer, i.e. the host sends a setup packet and requests data to be sent from
    > the device to the host.
    >
    > --> Middleware calls

    USBD_Device0_Endpoint0_SetupPacketReceived (const USB_SETUP_PACKET *setup_packet, uint8_t
    **buf, int32_t *len)
    

    > --> User (me) has to check if the request is for the user (me) If yes, user (me) has to
    > provide the data in a buffer and point **buf to this buffer, the return value for len has to
    > be set to the buffer size or the size of setup_packet->wLength, whichever is lower. Please
    > advise.
    Yes. If you handle more requests you need to store that information in setup stage so that on
    data stage you know for which request that data is for.

    > An optional flag can be set from the user for the user for later use in

    USBD_Device0_Endpoint0_InDataSent(int32_t len)
    


    Yes, as mentioned to determine which request is being handled.

    > --> A few 100us later the Middleware will call
    When the data was actually sent.

    USBD_Device0_Endpoint0_InDataSent(int32_t len)
    


    Yes.

    > Now user (me) knows that the data is read from the buffer and sent over the USB so that user
    > can reuse the buffer again. Correct?
    Yes.

    > The parameter len provides information on how much bytes were sent this time? Please advise.
    > What do I do when len is smaller than the buffer I wanted to send?
    This should not happen as Host will poll for all the data it expects to get unless transfer is terminated with short packet, ZLP or STALL, and it should get all the data you provided in your buffer. This situation only is produced by Windows when it first requests Device descriptor and if max packet size of device is less than 18 bytes which is size of device descriptor then it terminates that request by OUT ZLP and resets the device.

    > There is nothing else to do at this moment from the point of view of the middleware. Correct?
    Yes.

    > The return value shall be usbdRequestOK. Correct? Again the question: Under what
    > circumstances shall I return usbdRequestNotProcessed, usbdRequestOK, usbdRequestStall,
    > usbdRequestNAK?
    Same as in case of before-mentioned OUT callback to provide response for the status stage.

    > Please point out what is the idea behind the concept of the middleware, a simple function
    > reference without having an idea how an when to use the functions with what parameters and
    > what return values is not enough, at least for me.
    The idea is to allow users to tailor and implement any kind of device and answer any requests coming to device, with hiding the complexity of generating descriptors handling standard requests and interacting with low level driver that is standardized (by CMSIS) so interchangeable.
    Unfortunately, custom class implementation requires deep understanding of the USB itself and is generally meant to be used in rare occasions.

    Best regards, Milorad

Children
No data