• AVR Freaks

USB transfer of SD card data using CDC -> putsUSBUSART function. Better way?

Super Member
  • Total Posts : 769
  • Reward points : 0
  • Joined: 2006/12/03 10:20:52
  • Location: UK
  • Status: offline
2011/04/28 03:47:40 (permalink)

USB transfer of SD card data using CDC -> putsUSBUSART function. Better way?

I've got some sector-by-sector written data (no MDD / FAT / FS) on an SD card and I'm going to be using proprietary reads coupled with the putUSBUSART(data, length) function to get the data from the card to a PC over a virtual com port.

the documentation says:

This is function putUSBUSART.

So errrm, cheers. I know that much. I know also that I can specify the length of data I have and point it there, and it will be transferred over the VCP.

is the maximum size of data transferable only 256 Bytes though?

The prototype suggests so:

  void putUSBUSART(     char * data,      BYTE Length ); 

But, is this due to an inbuilt hardware limitation (to do with endpoints / buffer size etc) as to how much data can be transferred at a time? Obviously I don't want to disrupt interrupts. (I'm using interrupts, not polling.) To cut to the chase then, is there a better way to transfer ~10-100MB of data from an SD card, short of sticking it in a card reader *on* the PC? I heard there wasn't much in it between CDC and MSD classes in terms of speed. If I just have to chop each 512byte block in half then I'll do that. I'm just using CDC as I've used it before. I know 100MB is a lot of data to copy this way, but I can specify up to 921600baud in the terminal emulator I use, which is approx 115KB per second. ~10seconds a megabyte I can live with I suppose. Ideas / suggestions welcome :)

1 Reply Related Threads

    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    Re:USB transfer of SD card data using CDC -> putsUSBUSART function. Better way? 2011/04/29 14:34:29 (permalink)
    The bulk IN/OUT endpoints of CDC can carry ANY size of data block, even MBytes, by splitting it into packets of the endpoint size (wMaxPacketSize, usually 64 bytes).

    Here is a snippet of block transfer of large buffer over bulk endpoints using endpoint interrupt.

    This snippet is written for WinUSB example, but it's applied to CDC bulk IN/OUT endpoints, too.
    In CDC example context, the outline of the code is the same, but you have to replace WinUSB specific macros into CDC ones.

    WINUSB_BULK_EP          ---> CDC_DATA_EP

    USBWinUsbBulkInHandle   ---> extern CDCDataInHandle;
    USBWinUsbBulkOutHandle  ---> extern CDCDataOutHandle;

    USBGenWrite             ---> USBTxOnePacket
    USBGenRead              ---> USBRxOnePacket

    For block write over CDC bulk IN endpoint, you need an extra code line to send ZLP (Zero-Length Packet), when the transfer size is just the multiple of 64 bytes.

    Start_Block_Write( ... );
    while ( bulk_in_occupied );                                // wait until block transfer finishes
                                                               // just for demonstration.
                                                               // usually, state machine is applied to run other tasks,
                                                               // instead of this local loop.
    CDCDataInHandle = USBTxOnePacket( CDC_DATA_EP, NULL, 0 );  // send ZLP

    The snippet says "no-ping pong" - It means that this code doesn't effectively use ping-pong, even when enabled.
    Full ping-pong setting is still fine on usb_config.h


    On your PC app, increase RX buffer size on the class driver using SetupComm()

    Jump to:
    © 2019 APG vNext Commercial Version 4.5