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
  • Hi Lutz,

    > still I have some questions, or let me express it the other way: I need a more detailed
    > documentation of the API to the middleware.
    Only available documents regarding custom device/class handling are here:
    www.keil.com/.../group__usbd__class_functions.html
    www.keil.com/.../group__usbd__core_functions__api.html
    www.keil.com/.../group__usbd__class_functions__api.html

    > Let me explain how far I can follow the examples shown here:
    >
    > For a CTRL OUT transfer, i.e. the host sends not only a setup packet but additional data to
    > the device ('data stage').
    >
    > --> 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 can set an
    > optional flag and has to return usbdRequestOK, user has to provide a buffer for the data
    > stage to be received

    *buf = myBuffer;
    

    > The parameter len has to be set to what? My understanding is that len has to be set to
    > buffer size or to setup_packet->wLength, whichever is lower. Please advise.
    As a matter of fact is should be setup_packet->wLength or at least that, not less as Host
    knows how many bytes it wants to send and if you provide a smaller buffer than this might fail.

    *len = sizeof(myBuffer);
    if(*len > setup_packet->wLength) *len = setup_packet->wLength;
    


    No. myBuffer should be at least as maximum data stage request.

    > --> A few 100us later the Middleware will call
    When it receives all expected OUT data.

    USBD_Device0_Endpoint0_OutDataReceived(int32_t len)
    

    > Middleware meanwhile has copied (written) the data from the data stage to the given buffer.
    > Correct?
    It has actually received it directly there from the driver, and it is available there.

    > Now user (me) can read and process the data, the amount of data I can use is given in
    > parameter len. Correct?
    Yes.

    > When I use the data I shall return usbdRequestOK. Correct?
    Yes.

    > Under what circumstances shall I return usbdRequestNotProcessed, usbdRequestOK,
    > usbdRequestStall, usbdRequestNAK?
    This is written in the documentation and it says:
    - usbdRequestNotProcessed:request was not processed; processing will be done by USB library
    -> meaning: if you handle it in setup stage then you will probably not return this
    - usbdRequestOK: request was processed successfully (send Zero-Length Packet)
    -> meaning: you will do that to tell the library to send status stage ZLP
    - usbdRequestStall: request was processed but is not supported (stall Endpoint 0)
    -> meaning: you will do that to stall the status stage
    - usbdRequestNAK: request was processed but the device is busy (return NAK)
    -> meaning: you will do that to NAK the status stage
    So each of status stage responses signals different thing to Host.
    But it seems that usbdRequestNotProcessed on data stage is meaningless as if you handle the request then you need to say you handled it OK, you did not manage to handle it with NAK or you do not understand the request by returning STALL.

    > In my code it seemed to be of no meaning whether I returned usbdRequestNotProcessed or
    > usbdRequestOK.
    Yes, they behave the same on the data stage, as mentioned usbdRequestNotProcessed is meaningless here.

Reply
  • Hi Lutz,

    > still I have some questions, or let me express it the other way: I need a more detailed
    > documentation of the API to the middleware.
    Only available documents regarding custom device/class handling are here:
    www.keil.com/.../group__usbd__class_functions.html
    www.keil.com/.../group__usbd__core_functions__api.html
    www.keil.com/.../group__usbd__class_functions__api.html

    > Let me explain how far I can follow the examples shown here:
    >
    > For a CTRL OUT transfer, i.e. the host sends not only a setup packet but additional data to
    > the device ('data stage').
    >
    > --> 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 can set an
    > optional flag and has to return usbdRequestOK, user has to provide a buffer for the data
    > stage to be received

    *buf = myBuffer;
    

    > The parameter len has to be set to what? My understanding is that len has to be set to
    > buffer size or to setup_packet->wLength, whichever is lower. Please advise.
    As a matter of fact is should be setup_packet->wLength or at least that, not less as Host
    knows how many bytes it wants to send and if you provide a smaller buffer than this might fail.

    *len = sizeof(myBuffer);
    if(*len > setup_packet->wLength) *len = setup_packet->wLength;
    


    No. myBuffer should be at least as maximum data stage request.

    > --> A few 100us later the Middleware will call
    When it receives all expected OUT data.

    USBD_Device0_Endpoint0_OutDataReceived(int32_t len)
    

    > Middleware meanwhile has copied (written) the data from the data stage to the given buffer.
    > Correct?
    It has actually received it directly there from the driver, and it is available there.

    > Now user (me) can read and process the data, the amount of data I can use is given in
    > parameter len. Correct?
    Yes.

    > When I use the data I shall return usbdRequestOK. Correct?
    Yes.

    > Under what circumstances shall I return usbdRequestNotProcessed, usbdRequestOK,
    > usbdRequestStall, usbdRequestNAK?
    This is written in the documentation and it says:
    - usbdRequestNotProcessed:request was not processed; processing will be done by USB library
    -> meaning: if you handle it in setup stage then you will probably not return this
    - usbdRequestOK: request was processed successfully (send Zero-Length Packet)
    -> meaning: you will do that to tell the library to send status stage ZLP
    - usbdRequestStall: request was processed but is not supported (stall Endpoint 0)
    -> meaning: you will do that to stall the status stage
    - usbdRequestNAK: request was processed but the device is busy (return NAK)
    -> meaning: you will do that to NAK the status stage
    So each of status stage responses signals different thing to Host.
    But it seems that usbdRequestNotProcessed on data stage is meaningless as if you handle the request then you need to say you handled it OK, you did not manage to handle it with NAK or you do not understand the request by returning STALL.

    > In my code it seemed to be of no meaning whether I returned usbdRequestNotProcessed or
    > usbdRequestOK.
    Yes, they behave the same on the data stage, as mentioned usbdRequestNotProcessed is meaningless here.

Children
No data