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.

Poor USB documentation

The BIOSUSB 01.10.01(USB stack) for the C674x DSP is supplied by TI as binaries libraries with partial C (source code) headers.

The binary stack also comes with two FD class devices source code examples (HID and Mass storage).

 

The problem is that if you would like to have your own USB device scheme ("vendor" class), for example - single BULK type pipe (which is a very common USB scheme), you have a big problem with the TI's offering. The external documentation is poor, and the internal is simply non-exist.

 

I searched the e2e forums, and found out that I'm not alone with this problem.... and no one seems to find/get a solution to this problem.

Any idea what can be done?

 

Uri

  • I could not agree more. In general, dealing with C6745/7 supporting packages and documentation is rather frustrating.

  • Uri,

    Pl. refer to the DCD API documentation on how to create you own custom class application over BIOSUSB stack.  The underlying platform related port have already been taken care of for the end customer by TI so that the customer can focus on their end applications.

    On some instances customers wanted to create their own usb stack and have had difficulties with the documentation.  In your case as I see it you are looking to develop a custom app and you very well can do so (and many customers have done so).

    TI has packaged MSC, HID class applications as standard set of offering as part of BIOSUSB.  If your product need is different from the packaged stacks then you would have to develope your own custom class.

    On the other hand you would want a certified stack (other than HID, MSC) then you could buy an of the shelf stack from Jungo (www.jungo.com).

    We are working on improving the documentation but it will take time to stabilize.  Appreciate your feedback.

    regards

    swami

  • Swami,

     

    I already read the DCD chapter. Actually I read the entire usb_device_stack.pdf document and all other documents which are included in the package.

    The problem is that there no adequate documentation how to initialize the USB stack, which arguments should be set (and in which order) and how (in order to modify the device, configuration, interface and any other descriptors) which tasks and other system resources should be deployed and so on...

    Several documents which are mentioned in the above document are not to be found (example: two "Porting Guide")

     

    The bottom line is that even if you are familiar with USB (and I am...) and with TI's DSPs, you don't have enough information to begin with. You can try to back-engineering the class devices examples, but this is not a really good practice, and some obstacles can not be overcome by this method.

     

    Uri

  • Uri,

    Since you are looking to develop a custom class application you would have to refer the FD portions of the usb_device_stack.pdf documentation.

    Pl. refer to the USBHID device example project provided to understand the initialization sequence.  In particular hid_init.c file for the information on how to initialize the stack with your own custom FD application.  In your custom class app you would have to call for the core_register_fd () call to register with the stack.  Beyond that pl. follow the steps in fd_hid_khd.c for the initialization of the FD application.

    regards

    swami

  • Hi,

     

    I built my own FD driver (Scheme: Single pipe, Bulk IN) based on the HID device example last week. Until now, I failed to run it.

    While the nominal execution (checked and verify with the HID example) calls jstart_stack(), which calls in turn to jslave_init(), the code I wrote never reaches jslave_init().

    (after jstart_stack() it reaches UTL_halt(), but since its binaries libraries, I can not debug it easily .)

     

    The code is quite simple, can you have a look at it?

     

    Best regard,

    Uri

     

    ( initialization execute dsp_bios_entry(NULL), as done in the HID example)

    /** \file     usb_fd_p1.c
    */
     
    ////////////////////////////////////////////////////////////////////////////////
    // Include files
    #include <jos.h>
    #include "uw_debug.h"
    #include "uw_args.h"
    #include "jusb_core_fd.h"
    #include "jslave_init.h"
    #include "jusb_chp9.h"

    ////////////////////////////////////////////////////////////////////////////////
    // Definitions

    /* Memory managment */
    #ifdef CONFIG_MEMPOOL
    #ifndef CONFIG_MEMPOOL_SIZE
    #define CONFIG_MEMPOOL_SIZE (200 * 1024UL)
    #endif
    #ifdef CONFIG_MEMPOOL_EXTERN

    extern uint8_t _mempool[CONFIG_MEMPOOL_SIZE];
    #elif defined (CONFIG_MEMPOOL_ADDRESS)
        #define _mempool CONFIG_MEMPOOL_ADDRESS
    #else

    static uint8_t _mempool[CONFIG_MEMPOOL_SIZE];
    #endif
    #else
        #define CONFIG_MEMPOOL_SIZE 0
        #define _mempool NULL
    #endif
    #ifdef CONFIG_POOL_DMA
    #if defined(CONFIG_POOL_DMA_PADDRESS) && \
         defined(CONFIG_POOL_DMA_VADDRESS) && \
         defined(CONFIG_POOL_DMA_SIZE)
    #define _pdma_pool CONFIG_POOL_DMA_PADDRESS
    #define _vdma_pool CONFIG_POOL_DMA_VADDRESS
    #define _dma_pool_size CONFIG_POOL_DMA_SIZE
    #elif defined(CONFIG_POOL_DMA_PADDRESS) || \
         defined(CONFIG_POOL_DMA_VADDRESS) || \
         defined(CONFIG_POOL_DMA_SIZE)
    #error "Please define CONFIG_POOL_DMA_PADDRESS, " \
             "CONFIG_POOL_DMA_VADDRESS and CONFIG_POOL_DMA_SIZE"
    #else
    #define _pdma_pool NULL
    #define _vdma_pool NULL
    #define _dma_pool_size 0
    #endif
    #endif



    ////////////////////////////////////////////////////////////////////////////////
    // Local functions prototype

    /* Call back for usb_core */
    static result_t control_msg(void *context, void *buffer, uint8_t ep0_req_tag);

    /* Function driver initialization function */
    result_t fd_dsmp_init(void *ctx);

    ////////////////////////////////////////////////////////////////////////////////
    // Local structures

    /* Function driver */
    static fd_instance_t fd_instances[] = {
        { DEVICE_TYPE_VENDOR, 1, fd_dsmp_init },
        { DEVICE_TYPE_NONE, 0, NULL }
    };

    /* Device information (device descriptor) */
    static dev_info_t dev_info = {
        /* self_powered */         1,
    #ifdef CONFIG_REMOTE_WAKEUP_TIMEOUT
        /* remote_wakeup */        1,
    #else
        /* remote_wakeup */        0,
    #endif
    #ifdef CONFIG_JOTG
        /* srp_support */          1,
        /* hnp_support */          1,
    #endif
        /* max_power */            50,
        /* vendor */               0x3333,
        /* product */              0x3333,
        /* release */              0x0001,
        /* dev_class */            0,
        /* dev_sub_class */        0,
        /* dev_protocol */         0,
        /* product_name */         "TEST",
        /* product_manufacturer */ "IAM",
        /* product_serial */       "21011969"
    };

    static device_params_t dev_params = {
        /* controller_idx */      0,
    #ifdef CONFIG_SKIP_DEVICE_AUTO_ENABLE
        /* auto_enable */         0,
    #else
        /* auto_enable */         1,
    #endif
    #ifndef CONFIG_FULL_SPEED_ONLY
        /* full_speed_only */     0,
    #endif
        /* dev_info */            &dev_info,
        /* num_of_fd_instances */ sizeof(fd_instances) / sizeof(fd_instance_t) - 1,
        /* fd_instances */        fd_instances
    };

    /* Stack initialization arguments */
    /*static*/ uw_args_t uw_args = {
        #ifdef CONFIG_MEMPOOL
           (void*)_mempool,
           CONFIG_MEMPOOL_SIZE,
        #endif
        #ifdef CONFIG_POOL_DMA
           (void*)_vdma_pool, (void*)_pdma_pool, _dma_pool_size,
        #endif
        #ifdef CONFIG_POOL_DMA_CACHABLE
           NULL, NULL, 0,
        #endif
           UW_INIT_DEVICE,
           1,
           &dev_params
        };

    /* Pipes */
    static pipe_desc_t pipe_desc_array[] = {
        {
            /* max_pkt_size_high            */ 512,
            /* max_pkt_size_full            */ 64,
            /* type                         */ PIPE_BULK,
            /* direction                    */ DIRECTION_IN,
            /* sync_type                    */ 0,
            /* usage_type                   */ 0,
            /* address                      */ 0, /* Filled by Core */
            /* transaction_per_microframe   */ 0,
            /* nak_rate                     */ { 10 },
            /* dma_option                   */ DCD_NO_DMA,
            /* extra_descriptor_size        */ 0,
            /* extra_descriptor             */ NULL,
            /* poll_intrval_high            */ 0,
            /* fd_handle                    */ NULL,
            /* dcd_handle                   */ NULL,
            /* max_pkt_size                 */ 0,
            /* status                       */ PIPE_UNKNOWN,
            /* req_queue                    */ NULL
        }
    };

    static alt_interface_desc_t alt_desc_array[] = {
        {
            /* pipe_count                   */ 1,
            /* pipes                        */ pipe_desc_array,
            /* extra_descriptor             */ NULL,
            /* extra_descriptor_size        */ 0
        }
    };

    static interface_desc_t if_desc_array[] = {
        {
            /* control_msg                  */ control_msg,
            /* alt_ifs                      */ alt_desc_array,
            /* alt_if_num                   */ 1,
            /* alt_if_curr                  */ 0,
            /* extra_descriptor             */ NULL,
            /* extra_descriptor_size        */ 0,
            /* number                       */ 0, /* Filled by Core */
            /* if_class                     */ USB_CLASS_VENDOR_SPEC,
            /* if_subclass                  */ USB_CLASS_VENDOR_SPEC,
            /* if_protocol                  */ USB_CLASS_VENDOR_SPEC,
            /* if_string                    */ 0 /* filled during initiallization*/
        }
    };

    static fd_desc_t fd_desc = {
        /* speed            */ SPEED_HIGH,
        /* current speed    */ SPEED_UNKNOWN,
        /* interface_count  */ 1,
        /* interfaces       */ if_desc_array,
        /* iad              */ NULL
    };

    typedef struct _fd_dsmp_dev {
        interface_desc_t *if_desc;
    } fd_dsmp_dev_t;

    static fd_dsmp_dev_t dsmp_dev_desc = {
        /* if_desc  */ if_desc_array
    };

    /*The functions and callbacks requiered from hardware.*/
    typedef struct {
        result_t (*hw_enable)(void *context);
        result_t (*hw_disable)(void *context);
        void (*hw_uninit)(void *context);
    } hw_dsmp_callbacks_t;

    typedef struct
    {
        fd_dsmp_dev_t *dsmp;
        fd_desc_t *fd_desc;
        hw_dsmp_callbacks_t app_cb;
        context_t app_ctx;
        context_t core_ctx;
    } fd_dsmp_ops_t;

    static char device_name[] = "DSMP USB";
       


    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

    /**
     *    \brief    this function returns the uw_args argument,
     *            called by jstart_stack()
     *
     *    \param    None
     *
     *    \return    uw_args
     */
    uw_args_t *get_uw_args(void) {
        dev_info.product = 0;
        return &uw_args;
    }

    /**
     *    \brief    Get the configuration
     *
     *    \param    None
     *
     *    \return    configuration descriptor
     */
    static fd_desc_t *get_pipe_config(context_t context)
    {  
        fd_dsmp_ops_t *dsmp_dev = (fd_dsmp_ops_t *) context;

        DBG_X(DJOS_DRIVER,("usb_fd_dsmp.c: get_pipe_config.\n"));
        return dsmp_dev->fd_desc;
    }

    /**
     *    \brief    Enable callback
     *
     *    \param    Callback context
     *
     *    \return    Success indication
     */
    static result_t enable(context_t context)
    {
        result_t rt = UWE_OK;
        fd_dsmp_ops_t *dsmp_dev = (fd_dsmp_ops_t *) context;
        hw_dsmp_callbacks_t *app_cb = &dsmp_dev->app_cb;

        DBG_X(DJOS_DRIVER,("usb_fd_dsmp.c: enable.\n"));
        if (app_cb->hw_enable)
            rt = app_cb->hw_enable(dsmp_dev->app_ctx);
       
        return rt;
    }

    /**
     *    \brief    Disable callback
     *
     *    \param    Callback context
     *
     *    \return    Success indication
     */
    static void disable(context_t context)
    {
        result_t rt = UWE_OK;
        fd_dsmp_ops_t *hw_dsmp = (fd_dsmp_ops_t *)context;
        hw_dsmp_callbacks_t *app_cb = &hw_dsmp->app_cb;

        DBG_X(DJOS_DRIVER,("usb_fd_dsmp.c: disable.\n"));

        if (app_cb->hw_disable)
        {
            rt = app_cb->hw_disable(hw_dsmp->app_ctx);
            if (rt)
                DBG_E(DJOS_DRIVER, ("disable failed %s\n", uwe_str(rt)));
        }
    }

    /**
     *    \brief    Suspend callback
     *
     *    \param    Callback context
     *
     *    \return    Success indication
     */
    static result_t suspend(context_t context)
    {
    //    fd_dsmp_ops_t *hw_dsmp = (fd_dsmp_ops_t *)context;

        DBG_X(DJOS_DRIVER,("usb_fd_dsmp.c: suspend.\n"));

        return UWE_OK;
    }

    /**
     *    \brief    Resume callback
     *
     *    \param    Callback context
     *
     *    \return    Success indication
     */
    static result_t resume(context_t context)
    {
    //    fd_dsmp_ops_t *hw_dsmp = (fd_dsmp_ops_t *)context;

        DBG_X(DJOS_DRIVER,("usb_fd_dsmp.c: resume.\n"));

        return UWE_OK;
    }

    /**
     *    \brief    Uninit
     *
     *    \param    Callback
     *
     *    \return    Success indication
     */
    static result_t uninit(context_t context)
    {
        fd_dsmp_ops_t *hw_dsmp = (fd_dsmp_ops_t *)context;
        hw_dsmp_callbacks_t *app_cb = &hw_dsmp->app_cb;

        DBG_X(DJOS_DRIVER,("usb_fd_dsmp.c: uninit.\n"));

        if (app_cb->hw_uninit)
            app_cb->hw_uninit(hw_dsmp->app_ctx);

        jfree(hw_dsmp);

        return UWE_OK;
    }

    ////////////////////////////////////////////////////////////////////////////////
    static fd_ops_t fd_dsmp_ops = {
    /*  get_pipe_config     */ get_pipe_config,
    /*  enable              */ enable,
    /*  disable             */ disable,     
    /*  suspend                */ suspend,
    /*  resume              */ resume,
    /*  uninit              */ uninit
    };
    ////////////////////////////////////////////////////////////////////////////////
    /**
     *    \brief    DSMP USB FD initialization
     *
     *    \param    context
     *
     *    \return    Success indication
     */

    result_t fd_dsmp_init(void *ctx)
    {
        result_t rt = UWE_NOMEM;
        fd_dsmp_ops_t *dsmp_dev = NULL;
       
        dsmp_dev_desc.if_desc[0].if_string = core_add_string_descriptor(ctx,
            device_name);

        DBG_X(DJOS_DRIVER,("usb_fd_dsmp.c: init.%d \n",
            keyboard.if_desc[0].if_string));

        dsmp_dev = (fd_dsmp_ops_t *)jmalloc(sizeof(fd_dsmp_ops_t), M_ZERO);
        if (!dsmp_dev)
        {
            DBG_E(DJOS_DRIVER,("usb_fd_dsmp.c: Out of memory.\n"));
            goto Exit;
        }

        dsmp_dev->core_ctx = ctx;
        dsmp_dev->dsmp = &dsmp_dev_desc;
        dsmp_dev->fd_desc = &fd_desc;
           
    //    rt = hw_dsmp_init(dsmp_dev, &fd_hid_app_ops, &dsmp_dev->app_cb,
    //        &dsmp_dev->app_ctx);
    //    if (rt)
    //        goto Exit;
           
        rt = core_register_fd(dsmp_dev->core_ctx, &fd_dsmp_ops, (context_t)dsmp_dev);
       
    Exit:
        if (rt)
        {
            if (dsmp_dev)
            {
                jfree(dsmp_dev);
            }
        }
        return rt;
    }

    static result_t control_msg(void *context, void *buffer, uint8_t ep0_req_tag)
    {
    //    fd_dsmp_ops_t *hw_dsmp = (fd_dsmp_ops_t *)context;

        DBG_X(DJOS_DRIVER,("usb_fd_dsmp.c: control_msg.\n"));

        return UWE_OK;
    }



     

  • I just want to jump in and add my voice to the fact that the USB stack provided is pretty much unusable IF the use is beyond the HID or MSC class provided. There is absolutely no documentation that would help anyone develop their own stack on top of the core. In some ways this is WORSE than provided nothing, as it lulls the customer into thinking there is a clean solution available, and it takes a little bit of work to realize there is no source code to use as example and the documentation is non existent.

    All it would have taken is one custom interface example for us to build from (in light of the fact that there is no documentation).

    I am a little stunned.

  • Edmund

    I understand your concern. At present user can use existing class support available as part of package. I understand dificulty for developing the custom class driver developer on top of stack.  We already working out to provide the example class driver (host mode) to help user to create their own class driver. I will inform you the availability of this release.   

    Acknowledge you for sharing and we care your concerns.

    Regards

    Ravi B

     

     

     

  • Ravi B said:

    Edmund

    I understand your concern. At present user can use existing class support available as part of package. I understand dificulty for developing the custom class driver developer on top of stack.  We already working out to provide the example class driver (host mode) to help user to create their own class driver. I will inform you the availability of this release.   

    Acknowledge you for sharing and we care your concerns.

    Regards

    Ravi B

    That is a good solution for the long run. But for a lot of us time is critical and we can not wait for this to be done in a few months. There obviously must exist documentation for the lower layers as they are used to develop the provided class driver. Could you please release documentation for these NOW so we can write our own custom drivers?

    The availability of rich drivers and libraries was one of the primary reasons some of us selected this family. We simply can not try to "guess" at code and without the documentation I for one will have to go all the way back to the hardware level to insure a robust and maintainable product. And that alone would make me reconsider my selection.

    There really is no technical reason not let us write our own drivers now. Please help asap. Thanks.

  • All,

    While we're venting, l'd like to add my two-cents.  I specifically chose the c6747 because I know nothing about USB.  I was naively under the impression that since the USB is integrated into the part and TI claimed to provide drivers that it wouldn't be an issue.  The part is advertised as suitable for medical instrumentation, test and measurement, industrial monitoring, etc.  One would think that most such applications would involve getting some data from the part onto a PC!  I would have been better off chosing a different DSP and using a separate USB chip that is properly supported.  It still may come to that.

    Regards,

    Lori

  • It has been almost a month without a reply. Could you please PLEASE get us documentation or post some kind of reply so we can plan what we are doing?

     

    Thanks.

  • Edmund,

    For information on the IP and reference implementation pl. refer to the spru documentation and the Linux USB drivers source available under "drivers/usb/musb" directory.

    The documentation that has been released with BIOSUSB package is what can be provided to customers.  Licensing of the stack with Jungo does not permit TI to share source code.

    Regret the inconvinience caused.  If you need further assistance pl. contact your local FAE.

    regards

    swami

  • Hello,

      Fellows,I'd like to share some views of mine.As far as I know,TI really did a bad job on USB stack of DSP C674X or OMAPL13X.Hope no offend to TI~

    I had been trying to develop the usb stack all by myself,including the Firmware,the Function Driver and the App.I really bothered me cause all I got is a datasheet!!!

    I fisrt read the Datasheet "OMAPL137 USB UG" for several times,and got something out of it.Considering the solution is so huge and I turn to Jungo's USBBIOS stack,

    which is provided as a third-party Software by Jungo Inc.I give myself a relief at first before reallizing that all the package of USBBIOS is no stuff.Just some PDFs with

    meaning that no consumer would like to read and the example of HID and MSD is not so good a framework.I mean it is not so easy to develop our own Class(Vendor-Specific).Now we use Cypress 68013A to be a USB port of DSP and do the data transfer,it seems ok so far.

    Some ways to work the usb stack of single dsp out:

    1 read the datasheet"USB UG",and do it as it says.Parse Command and executate.

    First got Device Enumeration Ready and then Do data Transfer

    2 Develop under BIOSUSB,which is not my style^

    Good luck

    regards

    Calm