EmbDev.net

Forum: ARM programming with GCC/GNU tools USB Bulk-Tranfer: Datarate very low (Sam7SE)


Author: Christian W. (bluejac)
Posted on:

Rate this post
0 useful
not useful
Hi,
just posted this also at the at91.com forum but hopefully anybody can
help me here
I set up a little USB Bulk-Transfer program to have a simple connection
to my PC. On the PC-side I use libUSB for sending and receiving data. I
uses the Thesycon application to check up the correct
installation/enumaration of the usb-connection, too.

I want to have a datarate about 6-12 MBit/sec but get 0,18 MBit/sec
(180kBit/sec). The Sam7SE(512) is capable theoretically to support 12
MBit/s and I don't know why the rate is so slow.

The code for the same with using the usb.h from Atmel:
int main()
{
  unsigned char tmp[] =
"123456789012345678901234567890123456789012345678901234567890123";
    unsigned char bStatus;

    // Initialize the serial driver
    BULK_Init(&sBulk, &sUsb);

    // Wait for the device to be powered before connecting it
    while (!ISSET(USB_GetState(&sUsb), USB_STATE_POWERED));

    USB_Connect(&sUsb);

  while (1)
  {

    // Send data to USB host
    do {
      bStatus = USB_Write(
            sBulk.pUsb, //Pointer to a S_usb instance
            0x01,  //Number of the endpoint through which to send the
data
            tmp, //databuffer to send
            sizeof(tmp),     //Size of the databuffer
            0,   //Callback function to invoke
                       //when the transfer finishes
            0);  //Optional parameter to pass to
                       //the callback function

    } while (bStatus != USB_STATUS_SUCCESS);
    }
}

My discriptor-settings:
const S_usb_device_descriptor sDevice = {

    sizeof(S_usb_device_descriptor),
    USB_DEVICE_DESCRIPTOR,           // DEVICE Descriptor Type
    USB2_00,                         // USB 2.0 specification
    USB_CLASS_DEVICE,              // USB Communication class code
USB_CLASS_DEVICE = 0x00
    0x00,                            // No device subclass code
    0x00,                            // No device protocol code
    USB_ENDPOINT0_MAXPACKETSIZE,     // Maximum packet size for endpoint
zero
    USB_VENDOR,                      // Vendor ID
    PRODUCT_ID,                      // Product ID
    0x0001,                          // Device release number 0.01
    0x01,                            // Index of manufacturer
description
    0x02,                            // Index of product description
    0x03,                            // Index of serial number
description
    0x01                             // One possible configuration
};

//! \brief  Device configuration descriptor
//! \see    S_bulk_configuration_descriptor
const S_bulk_configuration_descriptor sConfiguration = {

    // Standard configuration descriptor
    {
        sizeof(S_usb_configuration_descriptor),
        USB_CONFIGURATION_DESCRIPTOR,        // CONFIGURATION descriptor
type
        sizeof(S_bulk_configuration_descriptor),
        0x01,    // 1 interfaces is used by this configuration
        0x01,    // 0x01 is used to select this configuration
        0x00,    // No string to describe this configuration
        USB_CONFIG_SELF_WAKEUP,  // Device is self-powered and
                      // does not support remote wakeup
        USB_POWER_MA(100)  // Maximum power consumption of the
                      // device is 100mA
    },
    // Data class interface descriptor
    {
        sizeof(S_usb_interface_descriptor),
        USB_INTERFACE_DESCRIPTOR,        //  = 0x04
        0x00,        // Interface
        0x00,        // No alternate settings
        0x02,        // Two endpoints used
        0xFF,        // Data class code
        0x00,        // No subclass code
        0x00,        // No protocol code
        0x00         // No description string
    },
    // Bulk-OUT endpoint descriptor
    {
        sizeof(S_usb_endpoint_descriptor),
        USB_ENDPOINT_DESCRIPTOR,      // ENDPOINT descriptor type
        0x01,       // OUT endpoint, address 1
        0x05,       // Bulk endpoint
        64,         // Endpoint size is 64 bytes
        0x00        // Must be 0x00 for full-speed bulk endpoints
    },
    // Bulk-IN endpoint descriptor
    {
        sizeof(S_usb_endpoint_descriptor),
        USB_ENDPOINT_DESCRIPTOR,      // ENDPOINT descriptor type
        0x82,               // IN endpoint, address 2
        ENDPOINT_TYPE_BULK, // Bulk endpoint
        64,                 // Endpoint size is 64 bytes
        0x00                // Must be 0x00 for full-speed bulk
endpoints
    },

I hope anybody have the solution for my problem.

Thanks and regards,
Christian

Author: Michael Wolf (mictronics)
Posted on:

Rate this post
0 useful
not useful
I discovered the same problem when I implemented USB MSD on
AT91SAM7S128.

I found at least two reason which slow down USB.

1.
The 64Byte Endpoint size is a problem if you want to tranfer large data
blocks, ie. 512Byte sectors of SD card. You can only transfer 64Byte
blocks, ever block needs protocol handshake between host and device, and
this creates a lot of overhead on the transfer - slowing down the
connection.

2.
My UDP driver in AT91 works with interrupts, but the MSD and Bulk
handler uses polling.
I discovered that any disturbance of the UDP code flow will slow down
transfer speed as well.
ie. A hardware timer with interrupt, setup to provide a system tick will
badly influence the transfer speed.

In an MP3 player project where my USB MSD is running, and when USB is
active, then I disable all things which might disturb the USB handler.

But even then I get no more then 2.1MBits/s when I use the USB MSD
class.

/Michael

Author: Christian W. (bluejac)
Posted on:

Rate this post
0 useful
not useful
Thank you for the answer.

I cannot imagine that the SAM7 provide this bad USB-connectivity. Such a
often used microcontroller...

Today I realised that my program only to the  correct work in case
adding the code-line

"TRACE_INIT();"

after the variable initialization. I don't understand what this function
do and why this is necessary. Maybee this is the reason for my bad
connection. Anybody who knows more?

Christian

Author: Michael Wolf (mictronics)
Posted on:

Rate this post
0 useful
not useful
TRACE_INIT() is a macro in file ..\core\trace.h

If you use tracing then the debug unit will be initialized by this
macro.

#if !defined(NOTRACES)
    #define TRACE_INIT()    AT91F_DBGU_Init(AT91C_MASTER_CLOCK,
DBGU_BAUDRATE)
#else
    #define TRACE_INIT(...)
#endif

Author: Christian W. (bluejac)
Posted on:

Rate this post
0 useful
not useful
Thanks, but why doesn't start my USB connection without this macro?

With the macro USB connection starts but is very slow.

Author: Michael Wolf (mictronics)
Posted on:

Rate this post
0 useful
not useful
Christian W. wrote:
> Thanks, but why doesn't start my USB connection without this macro?
>
> With the macro USB connection starts but is very slow.

The reason for slowing down the connection is simple:
With TRACE_INIT you create a lot of debugging output on the DBGU, since
it's a serial connection things will be slowed down.

But I can't tell why it doesn't start without.

When you compile the code without TRACE_INIT, are there warnings created
by the compiler?

Author: Christian W. (bluejac)
Posted on:

Rate this post
0 useful
not useful
I guess something like that.

No, I get no warning and no error. I notice the wrong functionality by
connecting the microcontroller to the PC. Vendor ID and Product ID are
not recognized from the USB host. Once again, here the main code I
programmed. If I comment the line marked with "<--" (line 3), the
program won't start correctly.

------------------------------------------------------------
int main()
{
  // sendbuffer, size 64 Byte
  unsigned char tmp[] =
"123456789012345678901234567890123456789012345678901234567890123";

    unsigned char bStatus;

    TRACE_INIT(); // <--

    // Initialize the serial driver
    BULK_Init(&sBulk, &sUsb);

    // Wait for the device to be powered before connecting it
    while (!ISSET(USB_GetState(&sUsb), USB_STATE_POWERED));

    USB_Connect(&sUsb);

    // LEDs init
    //configure_leds();

  while (1)
  {
    // Send data to USB host
    do {
      bStatus = USB_Write(
      sBulk.pUsb, //Pointer to a S_usb instance
      BULK_EPT_DATA_IN,  //Number of the endpoint through which to send
the data
      tmp, //Pointer to a buffer containing the data to send
      sizeof(tmp), //Size of the data buffer
      0, //Callback function to invoke when the transfer finishes
      0); //Optional parameter to pass to the callback function
    } while (bStatus != USB_STATUS_SUCCESS);



    }
}

Author: Michael Wolf (mictronics)
Posted on:

Rate this post
0 useful
not useful
Go to the ../core/ folder of your framework code, there you can find the
file trace.h

Inside you find the function:

extern inline void AT91F_DBGU_Init(unsigned int dMCK,
unsigned int dBaudrate)
{
    // Clock DBGU and configure its pins
    AT91F_DBGU_CfgPMC();
    AT91F_DBGU_CfgPIO();

    AT91F_US_Configure((AT91PS_USART) AT91C_BASE_DBGU,
                       dMCK,
                       AT91C_US_ASYNC_MODE,
                       dBaudrate,
                       0);

    // Enable Transmitter & Receiver
    AT91F_US_EnableTx((AT91PS_USART) AT91C_BASE_DBGU);
    AT91F_US_EnableRx((AT91PS_USART) AT91C_BASE_DBGU);
}

In this function comment one line after another and check which line
cause your code to fail.

Seems you forgot something to configure or setup the right way, and this
function does it for you. So without, your code fails.

Author: Christian W. (bluejac)
Posted on:

Rate this post
0 useful
not useful
Ok, done.

Setting the last line in comment is the only action I could do. I looked
for the code related to "AT91F_US_EnableTx((AT91PS_USART)
AT91C_BASE_DBGU);" and found this in my lib_AT91SAM7SE512.h file:

__inline void AT91F_US_EnableTx (
  AT91PS_USART pUSART)     // \arg pointer to a USART controller
{
    //* Enable  transmitter
    pUSART->US_CR = AT91C_US_TXEN;
}

AT91C_US_TXEN is defined to enable the DBGU transmitter in the related
SAM7-File. In my case "AT91SAM7SE512.h":

#define AT91C_US_TXEN         ((unsigned int) 0x1 <<  6) // (DBGU)
Transmitter Enable

But I have no idea why thr transmitter has to be enabled for a
functioning USB connection. I don't use this port in any way...

Anybody else has an idea?

Regards, Christian

Author: Christian W. (bluejac)
Posted on:

Rate this post
0 useful
not useful
Ok, found the reason, why I can't connect via USB with my
Microcontroller without TRACE_INIT(). In the usb.h and udp.c are
trace-functions added by ATMEL and when I try to send information via
DGBU-Port without any UART-Clock the programm pauses at this point.
I didn't see this because I haven't a Debug-Modus. My PC crashes by
starting the Debug-Mode :-(

After removing the trace-functions I get 4,1 MBit/s with my
Bulk-Settings. It is not bad, but shouldn't be the speed up to 8-10
MBit/s?

Author: Mrmz Mrmz (mrmz)
Posted on:

Rate this post
0 useful
not useful
Hi everyone,

Christian W. wrote:

> After removing the trace-functions I get 4,1 MBit/s with my
> Bulk-Settings. It is not bad, but shouldn't be the speed up to 8-10
> MBit/s?
i am interested where have you got source code for your msd from?is is
Amtel's?
with what code you commmunicate with SDcard? I'm using Michael Wolf's
programme from http://www.mictronics.de/?page=arm_examples,i turned off
all the TRACE's (using macros) by i got transfer rate about
60kbytes/s(when i copy to my sd).
Christian i wonder if you could give me your programme so i could see
what are the diffrances?

i'm using at91sam7x i visited few sites and i collected some info,
if you want to make your msd work faster you must:
- use dma(to spi)
- use dualbank for endpoints
- use multi sector read command for sd card
i consider using bigger endpoints but i read that for msd
fullspeed(12MB/s)endpoint can not be bigger than 64

Author: Thibaut Viard (aethaniel)
Posted on:

Rate this post
0 useful
not useful
Christian W. wrote:
> Ok, found the reason, why I can't connect via USB with my
> Microcontroller without TRACE_INIT(). In the usb.h and udp.c are
> trace-functions added by ATMEL and when I try to send information via
> DGBU-Port without any UART-Clock the programm pauses at this point.
> I didn't see this because I haven't a Debug-Modus. My PC crashes by
> starting the Debug-Mode :-(
>
> After removing the trace-functions I get 4,1 MBit/s with my
> Bulk-Settings. It is not bad, but shouldn't be the speed up to 8-10
> MBit/s?

Hi,

I'm very surprised by the 4.1 Mbit/s data rate!

I'm currently developing a USB MSD Key based on SAM7SE and got 600
kbit/s using standard Atmel software package 1.4 and RAM buffer, no NAND
flash nor SD card.

If you could explain how you obtain that data rates, i would be glad!!!
:-D

Futhermore, I obtained the same results using Segger embOS and emUSB
stack but using NAND flash.

Regards

Author: Thibaut Viard (aethaniel)
Posted on:

Rate this post
0 useful
not useful
Hi,

I have to apologize, I was wrong on my datarates :

It isn't 600kbits/s but 600KBYTES/s, so I'm no more surprised :-p

I'm currently trying to improve that rates to reach 800KB/s but I'm not
sure to be able to obtain that.....

See you

Author: shivakumara dymenahalli (Company: eagle photonics) (shivakumara)
Posted on:

Rate this post
0 useful
not useful
hi friends i am shiva its my project im planning to use AT91SAM7s64 arm 
controller so i want know about data transfer rate B/W usb and pc and up 
to  wat size of buffer i can use to get maximum speed by using bulk 
transfer... please give me if u have any program i can use to achieve 
maximum speed please help me friends

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.