This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BIOSUSB on C6748

Other Parts Discussed in Thread: OMAPL138

Dear all,

I have a question regarding the Jungo USB stack. I am developing a simple USB device (using a C6748 DSP) which communicates solely via control transfers. I have managed to initialise the Jungo device stack with appropriate descriptors and a custom function driver. My currently problem is that a function driver has a callback function for dealing with control transfers that is of the type (see the header jusb_core_fd.h):

typedef result_t (*if_control_msg_fn)(void *context, void *buffer, uint8_t ep0_req_tag);

My main question is: what should a function driver do in this callback function? More specifically, how can I return the required data if this control transfer is a Device-to-host transfer or how can I extract data if it is a Host-to-device transfer.

In case it helps: my current implementation of this callback function is simply this:

result_t receiveControlMessageCallback(void* context, void* buffer, uint8_t ep0_req_tag) { return UWE_UNKNOWN; }

I have verified that this function gets called whenever I send a vendor-specific control-request to the C6748 from a PC host. However, without further details on how to respond to control transfers I am not able to send data back to the host. It is not clear what buffer is, what ep0_req_tag is, where to put the data to satisfy the request or what value to return.

As pointed out in other threads, the documentation that ships with BIOSUSB is very incomplete and does not provide sufficient details for writing custom function drivers -- or adapting the existing examples for that matter. Considering that the Jungo stack is closed-source, this makes any kind of development on the Jungo stack near-impossible. Sending and responding to control transfers is one of the very basic functionalities of the USB standard and, in my view, should be relatively straight-forward to implement on a device that is said to support USB. I would be very grateful if someone could provide me with some information or examples that would enable me to develop USB device functionality on the C6748.

For info, I am using BIOSUSB 1.10.03,

Kind regards,

Mark

  • Dear all,

    I have a question regarding the Jungo USB stack. I am developing a simple USB device (using a C6748 DSP) which communicates solely via control transfers. I have managed to initialise the Jungo device stack with appropriate descriptors and a custom function driver. My currently problem is that a function driver has a callback function for dealing with control transfers that is of the type (see the header jusb_core_fd.h):


    typedef result_t (*if_control_msg_fn)(void *context, void *buffer, uint8_t ep0_req_tag);

    My main question is: what should a function driver do in this callback function? More specifically, how can I return the required data if this control transfer is a Device-to-host transfer or how can I extract data if it is a Host-to-device transfer.

    I am assuming that callback is called only when the request is vendor specific, not a standard USB command. 

    In case it helps: my current implementation of this callback function is simply this:

    result_t receiveControlMessageCallback(void* context, void* buffer, uint8_t ep0_req_tag) { return UWE_UNKNOWN; }

    I have verified that this function gets called whenever I send a vendor-specific control-request to the C6748 from a PC host. However, without further details on how to respond to control transfers I am not able to send data back to the host. It is not clear what buffer is, what ep0_req_tag is, where to put the data to satisfy the request or what value to return.

     "buffer" variable  is the control request ( custom request in case of vendor specific ).

    As  mentioned above that, you are getting callback only in the case of vendor specific request, so

    1. Host -> Device : map the buffer to "struct usb_ctrlrequest * "  ( from jusb_chap9.h ) to figure out the command type  and command , use core_read_data to read the data from the host.. 

    2. Device -> host : with every request associated with context which is "core_t" structure from "jusb_core.h" ( it is passed by application at the time of core_register_fd function call )  , there is a fd_buffer in the request which is used to write back the data and send using "core_send_data" function " jusb_core_fd.h ".



    As pointed out in other threads, the documentation that ships with BIOSUSB is very incomplete and does not provide sufficient details for writing custom function drivers -- or adapting the existing examples for that matter. Considering that the Jungo stack is closed-source, this makes any kind of development on the Jungo stack near-impossible. Sending and responding to control transfers is one of the very basic functionalities of the USB standard and, in my view, should be relatively straight-forward to implement on a device that is said to support USB. I would be very grateful if someone could provide me with some information or examples that would enable me to develop USB device functionality on the C6748.

    I haven't gone through the complete problem. I am still looking at the code and APIs available. I will try to reply more as soon as possible. Please let us know, if this solution helps you or not. 

    For info, I am using BIOSUSB 1.10.03,

    Kind regards,

    Mark

     

    Pankaj Anand

  • Thank you for responding to my message. It helps a little in the sense that I now know which functions I should be looking at; of course it is very much appreciated but I still have many, many questions!

    For example, you say that for a vendor-specific control transfer (in which data is sent from a PC host to a C6748 device) I should call core_read_data within the callback method to obtain the data sent by the host. From the documents provided with BIOSUSB the only available information on this function is its prototype:

    result_t core_read_data(void* ctx, pipe_desc_t* pipe, request_t* request); 

    It does not specify where to get the pipe descriptor from (in this case I guess it should be a descriptor for the control pipe which, if I understand correctly, was not previously defined by my application --- how should it be defined?). Moreover it doesn't specify whether I need to allocate the request_t structure with core_request_alloc or not, and, if so, how I should go about doing this. Again, for core_request_alloc, the only information available for this function is its prototype and this time this includes parameters of types such as mem_desc_t that go completely undocumented in either the header files or the PDF files that come with BIOSUSB.

    I just wish to stress that my questions could easily be resolved by TI providing more complete and more detailed documentation with the BIOSUSB library. In the absence of such documentation and without the actual source code I have no choice but to guess how I should be using the USB stack. This makes USB-related developement for the C6748 very unproductive and this, in my view, is a very unsatisfactory situation. I'd be grateful if TI could comment on this.

    Kind regards,

    Mark

  • Mark,

     I have been trying to look at how to provide the Pipe structure. Try to pass NULL for Pipe.. 

    it should look some thing like this " core_send_data(core, NULL, core->request); " . 

    Regarding the core_request_alloc, I guess you should not need to alloc it separately , as it is already done by the underlying driver itself, all you need to do is to use this structure. 

    I understand your concern regarding the documentation on BIOSUSB, we are trying to do better documentation and put some more sample code for Usb driver. 

     

    Kind regards, 

    Pankaj 

     

  • Dear Pankaj,

    Thank you for your answer. The remaining question is of course: how do I extract the data send by the host? I had a look at the request_t structure I obtain with core_read_data but cannot find my data there. Note also that the REQUEST_GET_BUFFER macro in jusb_core_fd.h does not do this (it does not currently compile as a request_t does not have a member called buffer)!

    It would be very helpful if someone could explain the following:

    1. What should be done in all the callback functions defined in fd_opt_t (i.e. the functions in 6.1 in usb_device_stack.pdf). More specifically, in what circumstances are they called, what return values should be given in which circumstances, and which core functions (i.e. the functions in 6.2 in usb_device_stack.pdf) would one call under which circumstances?
    2. What precisely do the core functions do (i.e. the functions in 6.2 in usb_device_stack.pdf). When should they be called and how should their arguments be initialised?

    The document itself (usb_device_stack.pdf) essentially just gives the types of the parameters and the return values of these functions but very little context.

    Kind regards,

    Mark

  • Pankaj Anand said:
    t should look some thing like this " core_send_data(core, NULL, core->request); " . 

    By the way, what type is this "core" variable and how to you obtain it? In my code the first argument is the "context", i.e. a void pointer (not a pointer to a specified type) that should only be interpreted by BIOSUSB and not by the application that uses BIOSUSB.

    Kind regards,

    Mark

  • Mark, 

     It seems there are some pieces missing for building a custom device driver, I am not able to understand what approach are you using for writing custom device driver as FD. It would be great if you can share some code or explain in details what are you doing exactly?. 

    Other than that, I would like to know the custom control message  you are using, in control message there can be 3 phases: 

    1. Setup phase

    2. Read phase 

    3. write phase

    Generally, the implementation, in the setup phase it is tried to identify what sort of phase it is , for example in setup phase if the command is found to be USB_REQ_GET_DESCRIPTOR , it means that it is a IN request  and FD need to write the data and it will call "core_send_data()" . For such an case, it is already defined in function driver with JUNGO, but as you are writing  custom driver you need to do this same thing in your control message processing. 

    First you need to check whether the length of data, mentioned in the setup packet is correctly read or not..

     

    struct usb_ctrlrequest {

        uint8_t bRequestType;

        uint8_t bRequest;

        uint16_t wValue;

        uint16_t wIndex;

        uint16_t wLength;

    };

    struct usb_ctrlrequest *ctrl_req = (struct usb_ctrlrequest*)buffer;

    here wLength represents the length that needs to be read/ write in the next phase. 

     

     

    By the way, what type is this "core" variable and how to you obtain it? In my code the first argument is the "context", i.e. a void pointer (not a pointer to a specified type) that should only be interpreted by BIOSUSB and not by the application that uses BIOSUSB. 

    Regarding the above question, I would request to go through the samples (usbdevhid) provided with the BIOSUSB_01_10_03

    If you have installed this package at the default location in that case it should be in "C:\Program Files\Texas Instruments\biosusb_01_10_03\packages\ti\biosusb\examples\usbdevhid" location. 

    This example explains how to obtain the "core", once the access to the "core" structure has made, it is easier to send and receive data. 

     

    Pankaj Anand

     

     

     

  • Pankaj Anand said:
    It seems there are some pieces missing for building a custom device driver, I am not able to understand what approach are you using for writing custom device driver as FD. It would be great if you can share some code or explain in details what are you doing exactly?. 

    There are indeed pieces missing! As for what I am doing... I am at the very early stages of writing a function driver. It simply registers with the USB Stack as the simplest device possible: a device with a single configuration and a single interface without any pipes (besides the mandatory control pipe). I am at the stage where this initialisation is successful and I have to implement the callback functions for enable, disable, control transfers, etc. I got this far by looking at the example you suggested (usbdevhid), but this example is not helping me get any further.

    I understand that there are various phases to the control transfer. I am interested in both sending data and receiving data via control transfers. I can detect which phase a transfer is from by casting the buffer to a usb_ctrlrequest and reading the bRequest value. For the purpose of this discussion lets focus on sending data from the Host to the Device. With regards to how I should respond to such a control transfer should the example (usbdevhid) is not at all helpful. How, using core_read_data or otherwise, do I get hold of the data send by the host? Data does not seem to be stored in request_t instances. This is all stuff that, in the usbdevhid example, is taken care of by the HID function driver which, to my knowledge, is closed source (at least in part).

    As for my question on what type "core" is. I now gather that the void* given during the initialisation callback for a function driver (i.e. the "context") is actually of type core_t* but, to my knowlegde, this is not something that is documented in BIOSUSB. I suppose the real question is therefore: how did you figure out it is a core_t*? I ask purely in case there is a source of information (documentation/examples/otherwise) that is available to you that is not available to me and that could help me with my development.

    Kind regards,

    Mark

     

  • Mark, 

    if you see implementation of the "result_t hid_kbd_init(void *ctx)" in fd_hid_kbd.c , when this function is called back by driver core, "ctx" is passed as reference for core_t structure. 

    the core_t structure is defined in "jusb_core.h" header file as :

    typedef struct core_t {

    /*

    some fields here...

    */ 

    }core_t ;

     

    here you need to save the reference of core_t  into your application side. 

    hope this helps.

    I will try to put more light on how to send data, but I guess earlier i have already explained core_send_data, the only blocker was to explain how to get instance of this core_t *.

     

    Regards,

    Pankaj

  • Pankaj Anand said:
    I will try to put more light on how to send data, but I guess earlier i have already explained core_send_data, the only blocker was to explain how to get instance of this core_t *.

    I disagree with this --- this is not the blocker. I was interested in how you deduced that the context void* is in fact of type core_t* as from the documentations or examples with BIOSUSB this is not obvious. To clarify this point; to my knowledge no usages of "ctx" in "hid_kbd_init" allow me to deduce that ctx is a core_t pointer. It is used:

    • As an argument in call to core_add_string_descriptor (this takes a void*) 
    • Assignment to kbd_dev->core_ctx (this field is of type context_t, a typedef to void*)
    • As an argument in call to init_hid_lib_internal (expects a void*)
    • As an argument in call to hw_kbd_init (expects a void*)
    • As an argument in call to core_register_fd (expects a void*)

    However, I am happy to accept that it is indeed a core_t* in order to progress this discussion.

    That is, the discussion about the core_t* is distracting from my real question: how should I implement the callback function for control transfers in a function driver? Even with your suggestion to call core_read_data by passing a NULL pointer for the pipe descriptor pointer and assuming I can figure out what request_t pointer to pass to core_read_data, where do I find the data that is read? The structure request_t does not appear to have a field that obviously contains this data and by looking at the contents of its memory during debugging, none of the fields did contain the data that was sent from the host.

    Your help is very much appreciated.

    Kind regards,

    Mark

     

  •  

    Mark, 

    First of all keeping such great patience with me. 

    We will keep our discussion on core_t * or context later on :-) .

     

    I would like to answer the main agenda for core_read_data,   following is the structure of request_t . As you can see there are 2 buffers defined here, fd_buffer and dcd_buffer.

     

     

     

    typedef struct request_t  {

        /* Force a "zero length packet"  if last fame = max packet size */

        uint8_t      zero;  

        /* For use by callbacks, set by Core 0/1 - In/Out*/

        uint8_t      direction;  

        /* Should be set to 1 when a zero length data stage is required on ep0 */

        uint8_t      ep0_zlp_reply; 

     

        /* Tag to verify the reply match the right control request */

        uint8_t ep0_req_tag;

     

        /* The buffer for DCD to preform operation on */

        mem_desc_h  dcd_buffer; 

        /* The buffer for FD to preform operation on */

        mem_desc_h  fd_buffer;

     

        uint32_t    buffer_size;

     

        callback_t  cb;             /* Completion callback */

        context_t   arg;            /* For use by the complete callback */

     

        request_status_t status;    /* Request status */

     

        uint32_t    transfer_size;  /* Number of bytes to transfer */

        uint32_t    bytes_transferred; /* Number of bytes transferred */

     

        void        *dma_handle;

     

        void        *caller_private; /* Opaque for use by request initiator */

     

        STAILQ_ENTRY(request_t) next_request; 

     

        void        *dcd_private;   /* Opaque for use by the DCD */

        void        *core_private;  /* Opaque for use by the Core */

     

        uint32_t    isoc_max_payload;

     

        uint32_t    read_timeout;   /* timeout in millisecs for read requests */

     

    #ifdef CONFIG_JSLAVE_TEST_MODE

        uint16_t    test_mode;

    #endif

    } request_t;

     

     

    fd_buffer should be used to read the data. You can simply copy the data into a buffer like this : 

     

    memcpy(request->fd_buffer->vaddr, local_buffer_ptr,  request->bytes_transferred); 

    Hope this helps.

     

    Pankaj Anand

     

    If my reply answers your question please mark the thread as answered

     

     

     

     

  • Dear Pankaj,

    I tried this pretty much exactly as described but unfortunately I do not get the expected data. Upon further investigation, the memory pointed to by the vaddr pointer does not contain the data send by the host. A possible indication of a problem is that core_read_data returns UWE_PERM which, according to usb_device_stack.pdf, indicates that I am not allowed to call this function with the parameters you suggest. I will attach my code below in case I have misinterpreted your instructions:

    result_t FunctionDriver::receiveControlMessage(void* buffer, uint8_t ep0_req_tag)
    {   
        const usb_ctrlrequest* CONTROL_REQUEST_PTR = static_cast<usb_ctrlrequest*>(buffer);
        const result_t CORE_READ_DATA_RESULT = core_read_data(m_context, 0, m_core->request);
       
        if (CORE_READ_DATA_RESULT == UWE_OK)
        {  
            // this code is not reached because CORE_READ_DATA_RESULT is UWE_PERM.
           
            const request_t& REQUEST = *m_core->request;
            const size_t BYTES_RECEIVED = static_cast<size_t>(REQUEST.bytes_transferred);
                   
            unsigned char * data = static_cast<unsigned char *>(calloc(BYTES_RECEIVED, sizeof(unsigned char)));
            memcpy(data, REQUEST.fd_buffer->vaddr, BYTES_RECEIVED);
           
            // ...
        }
        // ...
       
        return UWE_UNKNOWN;
    }

    Note that m_core and m_context are pointers to the same memory address (passed when the FD is initialised) but are core_t and void pointers, respectively.

    Kind regards,

    Mark

  • Mark, 

     You need to set these variable as well ,

         m_core->request->ep0_req_tag  = ep0_req_tag;

        m_core->request->arg          = m_core;

        m_core->request->cb           = ep0_reply_complete_callback; /* callback function */

        m_core->request->transfer_size = CONTROL_REQUEST_PTR->wLength; 

     

    prototype for ep0_reply_complete_callback should be like " static void ep0_reply_complete_callback(request_t *request)"  ,

     In the call back, you can compare the actual transfer_size and bytes_transfered.. 

    But before this check the for the data is there to read of not, I mean check size of  CONTROL_REQUEST_PTR->wLength, is the amount of data that has been sent  or not ?

    Pankaj

  • Thanks Pankaj,

    I am now finally able to read some data from the host. Please let me know how you figured out how to set these fields and call these functions as you explained; we both know neither the documentation nor the examples go into this amount of detail. I'd be grateful if you could let me know (either on this forum or otherwise).

    Without further information on BIOSUSB I'd have to ask many more questions similar to the one above in order to get the final product developed; this will have an significant impact on our development time and is an unnecessary waste of both your and my time.

    Kind regards,

    Mark

  • Dear Pankaj,

    To add to my previous message --- to which I'd still like an answer! --- I can now see the right data in this ep0_reply_complete_callback function, but I am unable to successfully complete the USB transaction (the control transfer always times out as far as the host is aware). If you have any ideas I'd be very interested.

    Kind regards,

    Mark

  • Mark, 

     

     We have some expert here on USb who has worked on Jungo stack for some time. I just consulted the problem with them. 

    what you need to do now is to tell the controller that the request is completed .. which can be done in this fashion in the reply_callback function :

    core_t *core = (core_t *)request->arg;

     

    if (core->request->caller_private)

        {

            request_t *old_req;

           old_req = (request_t *)core->request->caller_private;

            core_request_free(core->request);

            core->request = old_req;

        }

     

        core->request->status = REQUEST_READY;

     

    Pankaj

  • Dear Pankaj,

    It now works slightly better in that the DSP can handle multiple control transfers without requiring a reset. However, the transfers still timeout! I have done similar transfers with other USB devices so I do not believe the problem is with the host. I will share code snippets in case I missed something: 

    // Handler for control messages
    result_t FunctionDriver::receiveControlMessage(void* buffer, uint8_t ep0_req_tag)
    {  
        const usb_ctrlrequest* CONTROL_REQUEST_PTR = static_cast<usb_ctrlrequest*>(buffer);
       
        m_core->request->ep0_req_tag   = ep0_req_tag;
        m_core->request->arg           = m_core;
        m_core->request->cb            = handleDSPMessageCallback;
        m_core->request->transfer_size = CONTROL_REQUEST_PTR->wLength;
       
        const result_t CORE_READ_DATA_RESULT = core_read_data(m_context, 0, m_core->request);
       
        return CORE_READ_DATA_RESULT;
    }

    // Function called by handleDSPMessageCallback
    void FunctionDriver::handleDSPMessage(request_t* request)
    {
        const size_t TRANSFER_SIZE = static_cast<size_t>(request->transfer_size);
        const size_t BYTES_RECEIVED = static_cast<size_t>(request->bytes_transferred);
       
        if (request->status == REQUEST_COMPLETED)
        {
            if (TRANSFER_SIZE == BYTES_RECEIVED)
            {
                unsigned char* data = static_cast<unsigned char *>(calloc(BYTES_RECEIVED, sizeof(unsigned char)));
               
                if (data != 0)
                {
                    memcpy(data, request->fd_buffer->vaddr, BYTES_RECEIVED);

                    // TODO: handle data

                    delete(data);

                    if (request->caller_private)
                    {
                        request_t *old_req = (request_t *)request->caller_private;       
                        core_request_free(request);
                        m_core->request = old_req;       
                    }
                    // else do nothing        
               
                    request->status = REQUEST_READY;           
                }
                // else do nothing
            }
            // else do nothing
        }
        // else do nothing
    }

    With regards to the expert you are consulting... if it is at all possible for him or her to share some minimal reference implementation (either on the forum or otherwise) this would be very much appreciated indeed!

    Kind regards,

    Mark

  • Mark,

     

    try this one , I have just changed the order little bit.. thats it 

     

    void FunctionDriver::handleDSPMessage(request_t* request)

    {

        const size_t TRANSFER_SIZE = static_cast<size_t>(request->transfer_size);

        const size_t BYTES_RECEIVED = static_cast<size_t>(request->bytes_transferred);

     

        if (request->status == REQUEST_COMPLETED)

        {

            if (TRANSFER_SIZE == BYTES_RECEIVED)

            {

                unsigned char* data = static_cast<unsigned char *>(calloc(BYTES_RECEIVED, sizeof(unsigned char)));

     

                if (data != 0)

                {

                    memcpy(data, request->fd_buffer->vaddr, BYTES_RECEIVED);

     

                    // TODO: handle data

     

                    delete(data);

     

                }

                // else do nothing

            }

            // else do nothing

        }

        // else do nothing

                    if (request->caller_private)

                    {

                        request_t *old_req = (request_t *)request->caller_private;        

                        core_request_free(request);

                        m_core->request = old_req;        

                    }

                    // else do nothing         

     

                    request->status = REQUEST_READY;            

    }

  • Dear Pankaj,

    Thanks for the suggestion. I have tried this just now and behaviourally it makes no difference --- the correct amount of data is sent in every use case I tried so far thus moving the if-statement has no effect in practice. I have now also tried to send the same request with a different host (different implementation and operating system) and get precisely the same behaviour: a timeout. I am guessing somehow I am not letting BIOSUSB handle the handshake stage correctly?

    Kind regards,

    Mark

  • Dear Pankaj,

    Perhaps you won't mind if I ask another question in parallel. Clearly the way I am using BIOSUSB is not one that is commonly explored by TI customers. I am not sure how much of this is due to the particular use case (sending data from the host to the device with a control transfer). I therefore would like to ask how much different your answers would be in the following use cases:

    1. If I had a data transfer from the device to the host via a vendor-specific request
    2. If I wanted to transfer some data in either direction via an isochronous/interrupt/bulk pipe?

    If either is substantially different than the code I have posted above I would like to ask how they are different.

    Kind regards,

    Mark

  • Mark, 

    If the transaction is not getting completed, then there might be 2 problem which causes such scenario :

    1. The data phase of the control transfer is not getting completed.

    How much data are you trying to send ? is it multiple of 64 bytes ?

    If it is multiple of 64 byte, try to increase it slightly to (64 X n) + (some delta) . 

    Are you able to get the complete data in your function driver ?

     

    2. After setup phase and data phase, there has to be a status phase as well. As you are handling the control transfer yourself, you might need to handle the status phase as well. One you have received the data. You may  try to send a zero size packet to the host.

     

    Pankaj Anand

     

     

     

     

  • Dear Pankaj,

    Thank you for your email. To answer the first item, I am currently sending data in the order of 5-30 bytes. Even though I intend to send more data in the future, I don't believe this is an issue now. I do get the complete data in the function driver in all cases.

    This leaves us with the second item, which is almost surely causing the problem.

    When and how do I go about sending a zero-size packet to the host? This is really the kind of thing that should have been in the BIOSUSB documentation!

    Kind regards,

    Mark

  • Mark,

     do you use some USB protocol analyzer to capture the data on bus.. ? 

    if you are using such tool, please forward the captured log. It would be really helpful to understand what is happening on the bus.

     

    Pankaj

  • Mark, 

    you can send size Zero packet  in this function of yours : 

    result_t FunctionDriver::receiveControlMessage(void* buffer, uint8_t ep0_req_tag)
    {  
        const usb_ctrlrequest* CONTROL_REQUEST_PTR = static_cast<usb_ctrlrequest*>(buffer);
       
        m_core->request->ep0_req_tag   = ep0_req_tag;
        m_core->request->arg           = m_core;
        m_core->request->cb            = handleDSPMessageCallback;
        m_core->request->transfer_size = CONTROL_REQUEST_PTR->wLength;
       
        const result_t CORE_READ_DATA_RESULT = core_read_data(m_context, 0, m_core->request);
       
        return CORE_READ_DATA_RESULT;
    }

     

    after the core_read_data, you can call the method core_send_data(core,NULL,core->request), before that you need to set the same request parameter that you set for core_read_data. Also you need to set " core->request->zero=1;" as well. 

     

    Pankaj Anand

  • Dear Pankaj,

    Are you sure it should be in this function? The nature of the callback seems to be such that core_read_data returns before handleDSPMessageCallback is called. If I modify the m_core->request data structure after the call to core_read_data then won't its value be wrong once handleDSPMessageCallback is called? Also, logically should I really be initiating the handshake stage before BIOSUSB tells me the transfer is complete?

    Kind regards,

    Mark

  • Dear Mark,


    What you are saying is completely makes sense. The status stage should be done after core notifies the data stage is complete and this is happens at when handleDSPMessageCallback is called. You can go ahead and try as you said.

     

    Pankaj Anand

  • Dear Pankaj,

    I don't suppose you know how this meshes with the core_request_free code you sent a couple of posts back? That is, is m_core->request persistent over the three phases of a control transfer (setup stage, data stage, handshake stage) or should a new m_core->request be used for every stage?

    Kind regards,

    Mark

  • Mark, 

    I believe the same request structure is being used for transfer, though I am not 100% sure about it.  In your code, does the code flow goes into branch of

    if( core->request->priviate_caller)  ?

     

    You can use the same request structure for status phase which you get in callback for completion. 

     

    Pankaj

     

  • Dear Pankaj,

    Thank you for your quick response. My code does get to the if statement but never actually goes into it (because caller_private is 0). As such, the only statement having an effect there is

    request->status = REQUEST_READY;

    So are you saying I should call core_send_data in the implementation of handleDSPMessage you proposed some posts ago? If so, would you be able to post the modified function here? I am currently trying various permutations but they generally do not function as expected and seem to stall the control pipe.

    Kind regards,

    Mark

  • Mark, 

    Sorry for late reply. 

    Which modified function you want me post here  ? could you please elaborate her. Are you talking about the function which will be used as call back for the request which is used as parameter for core_send_data ? 

    If so, that function can be written as,

     

    static void ep0_callback(request_t *request)

    {

        if (request->status != REQUEST_COMPLETED)

        {

            //Print some error 

        }

        request->status = REQUEST_READY;

    }

    Regards,

     

    Pankaj 

  • Dear USB seekers;

    Many months ago, a group of us here were trying to use the Jungo USB software for the C67xx. We struggled.  We read the documentation (what there was of it). And we peppered the TI folks with questions.  To no success.  It was a complete waste of time for everyone.  (Search the previous posts and archives......)

    I concluded then that the Jungo USB software is CR*P whose only real purpose is as an advertisement for Jungo consulting services (which will cost you!).  I'm aware of no one who has successfully used this software package (for anything other than canned example that comes with the it).   

    I recommend not wasting your time with it.  When TI has a real solution for USB, I'm sure they will prominently announce it here.  But until then -- or until you hear legitimate testimony of success from other users -- the C67xx USB port is dead in the water. I wish it were not so.

    The TI staffers here are extremely helpful, and I recommend them, but they are forbidden (by the nature of things) from being as blunt as I am now. 

    Check back occasionally to see if solutions come forth.

  • Dear USB Seekers,

    Our company too was seeking to implement a virtual COM port based upon the Jungo USB code, and we were able to do so, but consistently came up against stability problems, which we have been unable to explain and without the source code from Jungo would be unable to fix. I will also repeat that the TI support workers were great but eventually stated that TI would not support custom development on top of the BIOSUSB from this forum, but that your field application engineer maybe able to get you some other support.

    We gave up using the Jungo USB code and have written our own code, which allows us to support multiple virtual COM ports and to work around the various issues we have found when interfacing with the USB peripheral.

    We are currently looking at licensing this software should anyone want a swift, simple and heavily tested on TI's C6748 / OMAPL138 chips COM port stack.

    Peter Myerscough-Jackopson

    www.macltd.com

  • Dear Mark,

    Do you know where to download BIOSUSB? I need it but I cannot find it whatever.

    I will appreciate it if you can help me.

    Best wishes!

    Kind regards,

    Samantha

  • Hi Samantha,

    I am afraid I don't know exactly where to download it. If I recall correctly it used to be downloadable from the same place as BIOSPSP, but I guess you looked there already. You may want to enquire TI themselves to see if BIOSUSB is still recommended/supported.

    For info, we didn't end up using BIOSUSB because we were unable to adapt it to suit our needs. Perhaps things have improved since.

    Kind regards,

    Mark