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

Bulk transfer of Data via USB (Host side)

Hi everyone,

I am using a LM3S5951 controllers for one of my projects in which I need to implement a host side driver for Dot Matrix printer .

I am done with enumeration of the printer, but now I would like to know how can I send data to printers using bulk transfers. I am using the Stellaries USB Library for the same where I found some host side codes for keyboard and pendrive. I would like to know, how to go about this.

Regards

Dhanush

Parents
  • > I have one IN endpoint for the printer.

    The bulk IN endpoint of the printer interface is optional.
    It’s role is specific to each printer model.
    Unfortunately, Epson doesn’t open the information of the role (protocol) over the bulk IN.
    You may get some printer status, or nothing.
    Try it.

    ulBytes = USBHCDPipeRead( g_USBHPRNDevice.ulBulkInPipe, pBuffer, sizeof(pBuffer) );
    





    > I would also like to check whether the printer is busy or not like it has been checked using the 25 pin centronics using LPT.

    NAK on the bulk OUT endpoint corresponds to the BUSY signal of Centronics.

    While the endpoint is NAKing, USBHCDPipeWrite() (and USBHCDPipeRead()) blocks the caller thread. I believe this is the reason why you need "BUSY" signal.

    Instead of these blocking calls, you may apply non-blocking USBHCDPipeSchedule() to start transfer over the bulk IN or OUT endpoint.

    USBHCDPipeSchedule( g_USBHPRNDevice.ulBulkOutPipe, pBuffer, sizeof(pBuffer) );
    or
    USBHCDPipeSchedule( g_USBHPRNDevice.ulBulkInPipe, pBuffer, sizeof(pBuffer) );
    

    When the transfer finishes, callback is called for each endpoint.
    This callback is registered at USBHCDPipeAllocSize() in your USBHPRNOpen()

    static void PRNEndpointCallback(uint32_t ui32Pipe, uint32_t ui32Event);
    
    static void *
    USBHPRNOpen(tUSBHostDevice *pDevice)
    {
        ...
        ...
                    g_sUSBHMSCDevice.ui32BulkInPipe =
                        USBHCDPipeAllocSize(0, USBHCD_PIPE_BULK_IN_DMA,
                                            psDevice,
                                            psEndpointDescriptor->wMaxPacketSize,
                                            PRNEndpointCallback);    // <-------
        ...
        ...
                    g_sUSBHMSCDevice.ui32BulkOutPipe =
                        USBHCDPipeAllocSize(0, USBHCD_PIPE_BULK_OUT_DMA,
                                            psDevice,
                                            psEndpointDescriptor->wMaxPacketSize,
                                            PRNEndpointCallback);    // <-------
    

    In the callback,

    static void
    PRNEndpointCallback(uint32_t ui32Pipe, uint32_t ui32Event)
    {
      switch ( ui32Event ) {
        case USB_EVENT_TX_COMPLETE:   // transfer on OUT endpoint finishes
          //
          // notify to the main thread by a flag, or start another transfer
          //
          break;
    
        case USB_EVENT_RX_AVAILABLE:  // transfer on IN endpoint finishes
          // read out data into a buffer
          USBHCDPipeReadNonBlocking( g_USBHPRNDevice.ulBulkInPipe, pBuffer, sizeof(pBuffer) );
          break;
        default: break;
      }
    }
    

    Tsuneo

Reply
  • > I have one IN endpoint for the printer.

    The bulk IN endpoint of the printer interface is optional.
    It’s role is specific to each printer model.
    Unfortunately, Epson doesn’t open the information of the role (protocol) over the bulk IN.
    You may get some printer status, or nothing.
    Try it.

    ulBytes = USBHCDPipeRead( g_USBHPRNDevice.ulBulkInPipe, pBuffer, sizeof(pBuffer) );
    





    > I would also like to check whether the printer is busy or not like it has been checked using the 25 pin centronics using LPT.

    NAK on the bulk OUT endpoint corresponds to the BUSY signal of Centronics.

    While the endpoint is NAKing, USBHCDPipeWrite() (and USBHCDPipeRead()) blocks the caller thread. I believe this is the reason why you need "BUSY" signal.

    Instead of these blocking calls, you may apply non-blocking USBHCDPipeSchedule() to start transfer over the bulk IN or OUT endpoint.

    USBHCDPipeSchedule( g_USBHPRNDevice.ulBulkOutPipe, pBuffer, sizeof(pBuffer) );
    or
    USBHCDPipeSchedule( g_USBHPRNDevice.ulBulkInPipe, pBuffer, sizeof(pBuffer) );
    

    When the transfer finishes, callback is called for each endpoint.
    This callback is registered at USBHCDPipeAllocSize() in your USBHPRNOpen()

    static void PRNEndpointCallback(uint32_t ui32Pipe, uint32_t ui32Event);
    
    static void *
    USBHPRNOpen(tUSBHostDevice *pDevice)
    {
        ...
        ...
                    g_sUSBHMSCDevice.ui32BulkInPipe =
                        USBHCDPipeAllocSize(0, USBHCD_PIPE_BULK_IN_DMA,
                                            psDevice,
                                            psEndpointDescriptor->wMaxPacketSize,
                                            PRNEndpointCallback);    // <-------
        ...
        ...
                    g_sUSBHMSCDevice.ui32BulkOutPipe =
                        USBHCDPipeAllocSize(0, USBHCD_PIPE_BULK_OUT_DMA,
                                            psDevice,
                                            psEndpointDescriptor->wMaxPacketSize,
                                            PRNEndpointCallback);    // <-------
    

    In the callback,

    static void
    PRNEndpointCallback(uint32_t ui32Pipe, uint32_t ui32Event)
    {
      switch ( ui32Event ) {
        case USB_EVENT_TX_COMPLETE:   // transfer on OUT endpoint finishes
          //
          // notify to the main thread by a flag, or start another transfer
          //
          break;
    
        case USB_EVENT_RX_AVAILABLE:  // transfer on IN endpoint finishes
          // read out data into a buffer
          USBHCDPipeReadNonBlocking( g_USBHPRNDevice.ulBulkInPipe, pBuffer, sizeof(pBuffer) );
          break;
        default: break;
      }
    }
    

    Tsuneo

Children
  • Hi Tsuneo ,

    I wish to interface a Laser printer (high USB speed device) to my ARM controller.But TIVA supports only low speed and full-speed devices . Is there any solution .Is there any interfacing circuitry ???

    Regards,
    Sanket

  • > But TIVA supports only low speed and full-speed devices .

    Surely USB host on Tiva TM4C123x supports just low-/full-speed.
    But TM4C129x does high-speed, too, with an external ULPI PHY chip.
    Unfortunately, TivaWare doesn't implement external PHY chip, yet.

    > I wish to interface a Laser printer (high USB speed device) to my ARM controller.

    You may consider on other MCUs.

    a) STM32F2/F4 with an external ULPI PHY chip
    The low-cost pair, STM32F4 Discovery board and "USB3300 USB HS Board", is handy to play high-speed USB.
    www.wvshare.com/.../USB3300-USB-HS-Board.htm

    ST's STM32_USB-Host-Device_Lib_V2.1.0 doesn't have printer host.
    But you may write it, based on Mass-Storage host example
    In this link, we discussed on modification for CDC/RNDIS host.
    Similar modification is applied to printer host.
    my.st.com/.../DispForm.aspx

    b) LPC18xx/LPC43xx (with on-chip high-speed PHY)
    - USB host library in LPCOpen supports printer host, but no example.
    You may write it fairly easily, based on HID keyboard host example.
    www.lpcware.com/.../lpcopen-software-development-platform-lpc18xx-packages-0

    c) Raspberry PI and BeagleBone Black
    Raspbian / Angstrom Linux supports printer host.

    Tsuneo