Arduino Forum

Products => Arduino Due => Topic started by: sined23 on Apr 05, 2016, 10:58 pm

Title: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 05, 2016, 10:58 pm
Hi guys! Does anybody know fast SerialUSB library for Arduino DUE?
Current SerialUSB read data at 1Mbit/s but can be at 10Mbit/s easily.
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 06, 2016, 11:08 pm
I DO get about 10mbit.... over 1MB per second......

It is down to what payload you transfer.

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 07, 2016, 12:26 am
Hi Graham! I used in PC the following python script:


import serial
import sys

ser = serial.Serial(
   port = '/dev/ttyACM0',
   baudrate = 115200,
   parity = serial.PARITY_NONE,
   stopbits = serial.STOPBITS_ONE,
   bytesize = serial.EIGHTBITS
)

if ser.isOpen() == False :
   ser.open()
   if ser.isOpen() == False :
      print "Can't open serial port"
      sys.exit(1)


for i in range(100000) :
      ser.write('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')



In Arduino Due:

char buffer[48];

void setup() {
        SerialUSB.begin(115200);
}
 
void loop() {
   if (SerialUSB.available() > 0) {
              SerialUSB.readBytes(buffer, 48);
   }
}



Speed of read is around 1Mbit/s

How to make 10Mbit/s ? What's wrong may be in my scripts?
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 07, 2016, 02:05 am
Try lifting your read buffer to 256....

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 07, 2016, 08:06 am
I did test. This is my results:

buffer 48:  121kByte/s=0,95Mbit/s
buffer 256: 129kByte/s=1Mbit/s


So, reading speed of SerialUSB is not very good.

You can look at comparing test results from the Internet:

(https://www.pjrc.com/teensy/benchmark_usb_serial_receive_1.png)

It's very terrible that Arduino Due has so powerful hardware and so not optimal libraries.
Guys, let's fix it pls.

I found one solution here http://forum.arduino.cc/index.php?topic=339067.0
But I haven't so deeply knowledge to change libraries and provide it for all.
Can anybody from Arduino's experts optimize SerialUSB for fast reading?
Thanks in advance!
Title: Re: fast SerialUSB for Arduino DUE
Post by: RayLivingston on Apr 07, 2016, 04:52 pm
The data rate is determined FAR more by the HOST device than the target device....

Regards,
Ray L.
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 08, 2016, 11:23 am
it's 100% arduino's problem. I connected USB-RS485 adapter to PC and used the same python script. Speed was 2,5Mbit/s (and can be higher I think).
With arduino - max 1Mbit/s.

Can anybody pls help to optimize SerialUSB.read?
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 08, 2016, 06:57 pm
Sorry sined23 for misleading you, my write speed is >10mb, my read speed is comparable with yours (133174 bytes/second). :(

I will see if I can make sense of the link you gave.

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 08, 2016, 09:27 pm
Graham, thank you! I will wait :)

Actually I also got write speed >10Mbit, even 40Mbit. But read speed is low :(
Title: Re: fast SerialUSB for Arduino DUE
Post by: westfw on Apr 09, 2016, 01:51 am
Quote
I connected USB-RS485 adapter to PC and used the same python script. Speed was 2,5Mbit/s (and can be higher I think).
Same Driver?  I believe the Due uses Windows built-in CDC driver, which is reported to be "not that great."  If your USB/RS485 driver has an FTDI or other chip that has its own driver, direct comparisons could be invalid.

Could be fun to poke at the Due code and see what changes have any effects...
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 09, 2016, 05:46 pm
@westfw,

You have previously mentioned the thesycon driver, have you personally tried it?

@sined123,

The link you sent with those changes to USBcore etc, I tried what he suggested, and the difference is amazing, BUT it makes the received data unreliable....  Not suitable if your data is critical.

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 09, 2016, 06:53 pm
Graham, but is it possible to increase read speed without bit error?
I think it must be some way.
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 09, 2016, 07:04 pm
Hi sined,

Yes it should be, but I am thinking this is over my head too..... Take a look at this document (http://www.atmel.com/Images/Atmel-42337-USB-Device-Interface-UDI-for-Communication-Class-Device-CDC_ApplicationNote_AT09332.pdf) from Atmel, I think the problem is a poorly implemented USB/CDC core by the Arduino gang.... I am just reading it now to see if I can make head or tail of it...  :o

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 09, 2016, 09:16 pm
Graham, oh, it would very cool if you can deal with it

BTW: I found author of the usb libraries. It's Peter Barrett.
Also there are contributors:

(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=162499)
(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=162501)
(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=162503)

Do you know somebody from them? May be they can join us?
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 13, 2016, 11:34 am
Perhaps my knowledge was enough :)
I increased USB read speed up to 8Mbit/s.
Speed can be increased more, but need optimize libraries more.

Pls, help to test it.

unzip fast_usbread.zip into hardware/sam/1.6.7/cores/arduino

after that you can use SerialUSB.readBlock(buffer, length) with high read speed

P.S. fast_usbread.zip is updated again
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 13, 2016, 04:54 pm
Read speed is increased up to 12Mbit/s !!!  (using buffer 500 Bytes in SerialUSB.readBlock)
Use updated fast_usbread.zip
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 14, 2016, 01:21 pm
Hi Sined,

I have been quite busy with my own stuff(UTFT_GHL) but I am very interested to test your improvements to DUE read speed, however, what changes have you made to stream and uartclass? I understand the need for changes to usbcore, usbapi and cdc.... A little more info would be good.

Also I am using 1.6.5 as I had issues with both 1.6.7 and 1.6.8, so unsure if I can just overwrite these files....

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 14, 2016, 02:28 pm
Hi Graham! Arduino Due has CDC buffer 512 bytes (it's configurable).
When data comes from PC, Arduino Due runs accept function from CDC.cpp.
Accept get only one byte and write it into the buffer.
You can see CDC.cpp (Serial_::accept):

Code: [Select]
c = USBD_Recv(CDC_RX);
buffer->buffer[buffer->head] = c;



And when you run USBSerial.readBytes(array, len), Arduino Due fill in array from CDC buffer only one by one byte.
You can see Streem.cpp (Stream::readBytes):

Code: [Select]
int c = timedRead();
if (c < 0) break;
*buffer++ = (char)c;


timedRead runs read() function, only it uses timeout feature.

Becouse of it read speed is slow.
I decided to write bytes into CDC buffer as many as possible () and get from CDC buffer full length of array.
I wanted to change readBytes function but decided to create new one and called readBlock.
Actually it's possible to modify only readBytes and don't create readBlock.

So, I added new function readBlock in Stream.cpp and Stream.h
readBlock can't use read() from Streem.cpp becouse read() get only one byte.
So, I created readb in CDC. int Serial_::readb(char *c, size_t length)
readb should be declared in several places.
In UARTClass as well. But it will not work in UART :) Becouse it's specially for USB.
In UARTClass.cpp I just added

Code: [Select]
int UARTClass::readb(char *c, size_t length)
{
return 0;
}


Now about readb in CDC.cpp:

Code: [Select]
unsigned int d = min((buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE, length); // know how many bytes we can get from CDC buffer
 
unsigned int i;
for (i = 0; i < d; i++) *c++ = buffer->buffer[(buffer->tail + i) % CDC_SERIAL_BUFFER_SIZE]; // get bytes
buffer->tail = (unsigned int)(buffer->tail + d) % CDC_SERIAL_BUFFER_SIZE; // change tail as tail+d



About accept in CDC.cpp:

Code: [Select]
uint8_t c[CDC_SERIAL_BUFFER_SIZE]; // create temp array
uint32_t k = USBD_Recv(CDC_RX, &c, (buffer->tail - i) % CDC_SERIAL_BUFFER_SIZE); // recieve bytes as many as possible into temp array c. k - count of recorded bytes
uint32_t j;
for (j=0;j<k;j++) buffer->buffer[(buffer->head + j) % CDC_SERIAL_BUFFER_SIZE] = c[j]; // write k bytes into CDC buffer

buffer->head = (buffer->head + k) % CDC_SERIAL_BUFFER_SIZE; // change head as head+k



Actually it's hard to explain all. I spend 2,5 days to get it :)
If you have some questions pls ask.
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 14, 2016, 02:41 pm
One more thing. I changed USBD_Recv in USBCore.cpp

before it used:

Code: [Select]
while (n--)
                *dst++ = UDD_Recv8(ep & 0xF);


to get data from USB.

But now it uses:

Code: [Select]
UDD_Recv(ep & 0xF, dst, len);

It really increases read speed as well.

You can backup your files and copy mine.
About changes you can use compare tools to find exact changes.

When you finish your tests pls tell me results. It's interesting for me :)
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 14, 2016, 05:06 pm

Quote
Total Time taken to transfer 20971520 bytes =15335852(us)

Bytes per second =1367483.2
MB per second =1.3041337
:) 8)


Well done!!


Regards,


Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 14, 2016, 05:16 pm
:) 8)


Well done!!


Regards,


Graham
Thank you! :):):)
Do you know who can update libraries in new version?
I think arduino's RnD should check it and perhaps modify a little and include in official release.
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 14, 2016, 05:28 pm
BTW Now Arduino Due with my improvement has the best results.
So, this picture is not right already :)

(https://www.pjrc.com/teensy/benchmark_usb_serial_receive_1.png)
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 14, 2016, 08:22 pm
Hi sined,

First let me just say your files are incompatible with 1.6.5, so I upgraded to 1.6.7, which oddly enough is working properly for me this time. The first thing I noticed is that 1.6.7 is slightly faster at reading. I am not talking about absolute fastest possible attainable speed, but an actual sketch that does real work.

UTFT_GHL is my flag-ship TFT Font IC package... (Shameless plug ;)) which communicates directly over USB rather than SD as is more usual. To demonstrate the impact of your modifications I made minimal changes to take advantage and was very pleased with the improvements!

The general gist is, a collection of items on the host PC are compiled into suitable format and uploaded to a SPI Flash IC over USB, works with Mega/Arduino programming or Due native port.

Using IDE 1.6.5 and Due Native port, I typically got 98220 Bytes per second.
Using IDE 1.6.7 and Due Native port, I now get 105606 Bytes per second.
Using IDE 1.6.7 and Due Native port, I now get 167210 Bytes per second - without modifications to the sketch, but with your replacement files in place.
Using IDE 1.6.7 and Due Native port, I now get 250816 Bytes per second - with modifications to the sketch.

It seems to me, there are significant gains to be had, good luck with getting the core modified officially!

Regards,

Graham

PS +1 by the way :D
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 14, 2016, 09:23 pm
Graham, I am glad that helped you :)
Pls pay attention that max length in readBlock(array, length) is 512 now.
I did it for test.
If it's needed I can make unlimited length. It's easy, just add while loop in readBlock or readb function.


About official modification - I absolutly don't know who develop arduino soft.
I hope they will read the topic :)
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 14, 2016, 09:29 pm
Hi sined,

Try putting a post on this board... you can link to my benchmarks...

https://forum.arduino.cc/index.php?board=23.0 (https://forum.arduino.cc/index.php?board=23.0)

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 14, 2016, 10:04 pm
I've added here https://groups.google.com/a/arduino.cc/forum/?fromgroups#!forum/developers
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 15, 2016, 04:02 pm
Sadly I have had to return to IDE 1.6.5 as it appears the sdfat library has issues with IDE 1.6.7 :(.

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: Okio on Apr 15, 2016, 07:10 pm
I wexperienced this also but resolved it by changing "#ifdef ARDUINO_FILE_USES_STREAM" to "#ifndef ARDUINO_FILE_USES_STREAM" in "SdFat\utility\ArduinoFiles.h"
In other words: SdFat works just fine with 1.6.7 for me :)

Wire library is the same but this time I resolved this by adding "virtual int readb (char *c, size_t length);" to Wire.h and "int TwoWire::readb (char *c, size_t length){return 0;}" to Wire.cpp.

Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 16, 2016, 04:28 pm
@okio, thanks for that, it works, however, I am still returning to 1.6.5 for other reasons, (like it doesn't suck).

IDE 1.6.6, 1.6.7 and 1.6.8 have problems for me, I have many sketches written over the years that use UTFT and assorted add-on libraries, and there are problems under versions of IDE > 1.6.5. I can compile a sketch ONCE, make no changes, and try to compile again, the compile will fail with miscellaneous errors. If I change target board from ARM to AVR, compile, then return to ARM, again I can compile ONCE.... Too much trouble for me when I am doing development work and making changes regularly, I need to know the errors are because of something I have done, not because the IDE is having an off-life.....

@sined, any chance you could make your changes to Sam Core 1.6.5 please?

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 16, 2016, 06:19 pm
@sined, I made the changes to Core 1.6.5, the difference is startling!! Same sketches and hardware as before, the only difference is IDE 1.6.5 and Sam core 1.6.5 and with your improvements, the fastest I have seen is about half that of IDE 1.6.7 with your improvements!! approx 125KB/s.... which is rather disappointing.

I hope they fix whatever the issues are with 1.6.7 and 1.6.8 SOON...

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 16, 2016, 08:26 pm
Hi Graham! Try to copy all files from cores/arduino from 1.6.7 to 1.6.5.

Speed 125KB/s can be becouse of not optimized other lib (not SerialUSB read) which make program slowly.
Try to mesure max speed of only SerialUSB.readBlock in 1.6.5 without other commands/lib in sketch
Title: Re: fast SerialUSB for Arduino DUE
Post by: GaM3r2Xtreme on Apr 20, 2016, 06:34 pm
Hi sined,

Great work with the serial communications mate. I will have to check your edited code myself and see how well communications are for me. I've been trying to figure out how to obtain faster speeds to send 6kB chunks of data to refresh some of those adafruit rgb led matrices, and I think this might be the answer. Any luck getting this code into the official library?
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 20, 2016, 06:44 pm
About as much luck as I have getting an answer out of them for something else.

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: AdderD on Apr 20, 2016, 07:14 pm
Has anyone considered adding DMA support to the Due USB code? I'm really wondering why such a thing wouldn't have been done from the start. The SAM3X has support for direct transfer of data to and from USB right to RAM without the core processor having to be involved. That should *drastically* increase the maximum read/write speed while also freeing up processor time. It's a little more complicated but might be worth doing. Though, since I'm writing this post and not doing it myself I guess it isn't worth *that* much to me. ;)

But, if you're in the code anyway, give it a try. Once it's all spiffy and fast I'll try to help get it pushed into the mainline code.
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 20, 2016, 10:26 pm
Hi Sined,

Here are the results of my tests, as you can see, the sketch doesn't get much more basic....

IDE 1.6.5 ReadBytes

(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=164072)

IDE 1.6.8 ReadBytes

(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=164074)

IDE 1.6.5 ReadBlock

(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=164076)

IDE 1.6.8 ReadBlock

(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=164078)

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: GaM3r2Xtreme on Apr 21, 2016, 03:08 am
I would have some use for that DMA if it were implemented. This would be a great idea to work on making serial communication even faster. Collin, would you happen to have any idea where the information on the DMA controller is located within the SAM3X8E datasheet? I'd like to look into it a little more to see what I can make out of it, but that datasheet can be a little tricky finding something. I did see a small mention about DMA on the Due in this thread:
http://community.atmel.com/forum/synchronous-serial-controller-ssc-or-i2s-using-dma-controller-sam3x8e-incomplete-data-transfer (http://community.atmel.com/forum/synchronous-serial-controller-ssc-or-i2s-using-dma-controller-sam3x8e-incomplete-data-transfer)

The code sin has worked on, this is based on the async peripheral, correct? Just the basic communications as seen in the Serial library?
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 21, 2016, 03:55 am
The code sin has worked on, this is based on the async peripheral, correct? Just the basic communications as seen in the Serial library?
Correct.

Regards,


Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 21, 2016, 10:36 am
Hi sined,

Great work with the serial communications mate. I will have to check your edited code myself and see how well communications are for me. I've been trying to figure out how to obtain faster speeds to send 6kB chunks of data to refresh some of those adafruit rgb led matrices, and I think this might be the answer. Any luck getting this code into the official library?
Hi GaM3r2Xtreme! I changed code in github of Arduino.

https://github.com/arduino/Arduino/pull/4871

If admins will approve my changes it will be officially put into new version.
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 21, 2016, 01:24 pm
Hi Graham! I installed IDE 1.6.5 for test and got speed 10-12 Mbit/s

I used this simple sketch:

Code: [Select]
char buf[500];

void setup() {
  SerialUSB.begin(250000);

}

void loop() {
  if (SerialUSB.available() > 0) {
     SerialUSB.readBlock(buf, 500);
  }
}



I prepared fast_usbread for IDE 1.6.5. You can use it.
BTW length in readBytes now can be any :)
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 21, 2016, 01:50 pm
Hi Sined,

I didn't look at your code yet, but that did the trick :D.

(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=164157)

Regards,

Graham

Edit: And with a readblock size of 1000 !!!  ;) :D 8)

(http://forum.arduino.cc/index.php?action=dlattach;topic=391757.0;attach=164159)
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 21, 2016, 02:02 pm
Great!
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 21, 2016, 02:09 pm
Well done Sined!! 

I really hope this gets into the next release of the IDE!!

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 21, 2016, 04:22 pm
Hi Sined,


:smiley-roll-blue: Now you have USB2 Full speed working, when are you planning to work on High speed implementation ? :P ;)


What am I missing? Why didn't arduino team use the UOTGHS interface to implement CDC? This is where all the DMA goodies are hidden for USB, section 39 of the Sam Data sheet, if SOMEBODY (not me) clever can figure that out we should have serious speed transfer capabilites.


Regards,


Graham

Edit: I stumbled across another Atmel application note for High Speed CDC.... http://www.atmel.com/Images/Atmel-42338-USB-Host-Interface-UHI-for-Communication-Class-Device-CDC_ApplicationNote_AT09333.pdf (http://www.atmel.com/Images/Atmel-42338-USB-Host-Interface-UHI-for-Communication-Class-Device-CDC_ApplicationNote_AT09333.pdf)  and also a very detailed article on setting up a USB connection.... Between those two articles, there should be enough information to figure it out for somebody REALLY clever.... http://www.codeproject.com/Articles/893727/Getting-video-stream-from-USB-web-camera-on-Ardu (http://www.codeproject.com/Articles/893727/Getting-video-stream-from-USB-web-camera-on-Ardu)
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on Apr 21, 2016, 07:34 pm
Hi Graham! I think this is task for Arduino's developers. I am not a developer, just an engineer :)
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 21, 2016, 07:39 pm
Hi sined,

I agree with you, I wasn't being serious... It looks incredibly complicated...

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: GaM3r2Xtreme on Apr 21, 2016, 11:20 pm
I am curious to see if DMA is possible with the due. Thanks for telling us where to look in the datasheet Graham. I plan to read though it to see if I can make any sense out of it. That datasheet is over 1400 pages of a weird world to me, haha. Do you guys think its possible to code an implementation? I don't think its a hardware layout that's an issue. Looks like DMA is built into the chip. Maybe a 3rd party library can be created?
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 21, 2016, 11:36 pm
I am absolutely certain a DMA HS implementation can be made, the Atmel application note gives the basic layout and requirements for ASF/Atmel Studio. But how to join it in with Arduino I have no clue.

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: GaM3r2Xtreme on Apr 22, 2016, 06:14 pm
I checked out the Atmel application notes you mentioned for the SAM3X8E and did a quick ctrl+f for the term "DMA" and these are the links that popped up for anyone curious to read up on the examples.

[PDF (http://www.atmel.com/Images/Atmel-42291-SAM3A-3U-3X-4E-DMA-Controller-DMAC_ApplicationNote_AT07892.pdf)] Atmel AT07892: SAM3A/3U/3X/4E DMA Controller (DMAC) Driver
(file size: 284KB, 28 pages, revision B, updated: 07/2015)
This application note describes how to use the ASF driver for interfacing to the Direct Memory Access Controller on SAM4E.

[PDF (http://www.atmel.com/Images/Atmel-42316-SAM3A-3N-3S-3U-3X-4E-4N-4S-G-Peripheral-DMA-Controller-PDC-Driver_ApplicationNote_AT08642.pdf)] Atmel AT08642: SAM3A/3N/3S/3U/3X/4E/4N/4S/G Peripheral DMA Controller (PDC) Driver
(file size: 246KB, 19 pages, revision B, updated: 07/2015)
This application note describes how to use the ASF driver for interfacing to the Peripheral DMA controller on SAM4.



Those are the only two that popped up for the SAM, but below are what shows up for "Atmel AVR 8-bit and 32-bit Microcontrollers". They might be irrelevant, but probably a good read for information on DMA.

[PDF (http://www.atmel.com/Images/Atmel-8046-Using-the-XMEGA-DMA-Controller_Application-Note_AVR1304.pdf) | ZIP (http://www.atmel.com/images/AVR1304.zip)] Atmel AVR1304: Using the XMEGA DMA Controller
(file size: 200KB, 11 pages, revision D, updated: 05/2013)
This application note describes the basic functionality of the XMEGA DMAC with code examples to get up and running quickly. A driver interface written in C is included as well.

[PDF (http://www.atmel.com/Images/doc8310.pdf) | ZIP (http://www.atmel.com/images/AVR1502.zip)] AVR1502: Xplain Training - Direct Memory Access Controller
(file size: 22766, 10 pages, revision A, updated: 08/2011)
This Application Note will get you started with Atmel® AVR® XMEGA® Direct Memory Access Controller (DMAC). You will learn to perform simple memory transfers almost without using CPU time, and reading and writing to peripherals with hardly any CPU intervention.

[PDF (http://www.atmel.com/Images/doc32016.pdf) | ZIP (http://www.atmel.com/images/AVR32108.zip)] AVR32108: Using the 32-bit AVR AP7 Peripheral Direct Memory Access controller
(file size: 57022, 8 pages, revision A, updated: 05/2006)
The 32-bit AVR AP7 has a dedicated Peripheral Direct Memory Controller (PDC). This application notes describes how to use it and includes an example of using the USART with the Peripheral DMA Controller (PDC) with and without interrupt control.

[PDF (http://www.atmel.com/Images/doc8313.pdf) | ZIP (http://www.atmel.com/images/AVR1504.zip)] Atmel AVR1504: XMEGA-A1 Xplained training - XMEGA Event System
(file size: 30990, 15 pages, revision A, updated: 08/2010)
This Application Note will get you started with Atmel® AVR® XMEGA™ Event System which allows inter-peripheral communication, enabling a change of state in one peripheral to automatically trigger actions in other peripherals, without any use of interrupts or CPU and DMA resources.

[PDF (http://www.atmel.com/Images/doc8319.pdf) | ZIP (http://www.atmel.com/images/AVR1510.zip)] Atmel AVR1510: XMEGA-A1 Xplained training - XMEGA USART
(file size: 26637, 10 pages, revision A, updated: 08/2010)
This Application Note will get you started with using Atmel® AVR® XMEGA™ USART (Universal Synchronous Asynchronous Receiver Transmitter) in polling mode, interrupt mode and how to use the DMA Controller to transfer data without CPU interaction.

[PDF (http://www.atmel.com/Images/doc8400.pdf) | ZIP (http://www.atmel.com/images/AVR1514.zip)] Atmel AVR1514: XMEGA-A1 Xplained Training - Direct Memory Access Controller
(file size: 26324, 10 pages, revision A, updated: 07/2011)
This application note covers the basic features of the Atmel® AVR® XMEGA® Direct Memory Access Controller (DMAC). The goal for this training is to get started with simple memory transfers almost without using CPU time, and reading / writing to peripherals with hardly any CPU intervention.

[PDF (http://www.atmel.com/Images/doc8408.pdf) | ZIP (http://www.atmel.com/images/AVR1522.zip)] Atmel AVR1522: XMEGA-A1 Xplained Training - XMEGA USART
(file size: 114259, 10 pages, revision A, updated: 07/2011)
The USART (Universal Synchronous Asynchronous Receiver Transmitter) is the key element in serial communications between computers, terminals and other devices. This training covers basic setup and use of the Atmel® AVR® XMEGA® USART and the three tasks will demonstrate how to use the USART In polling-mode, interrupt mode and how to use the DMAC (Direct Memory Access Controller) to transfer data without CPU interaction.



I've also found a good read about the USB standard and might help with understanding how everything works together here (http://www.beyondlogic.org/usbnutshell/usb1.shtml).
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 22, 2016, 06:31 pm
Quote
USB in a NutShell
Making sense of the USB standard
Starting out new with USB can be quite daunting. With the USB 2.0 specification (http://www.usb.org/developers/docs/usb_20.zip) at 650 pages one could easily be put off 
No shit!!

I thought the Atmel notes were enough! :P

I do think the DMA aspect is only part of this larger picture, how the f*** do we start to integrate it into Arduino?....

I am comfortable with libraries in general, I am moderately comfortable with C(++), what I am struggling with is the overall structure and how the arduino modules link together..... this does really need to be a Arduino team project if it is going to progress......... but since they dumped the DUE, it is unlikely to happen :( .

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: GaM3r2Xtreme on Apr 25, 2016, 06:53 pm
You mean there is no support from the Arduino team for the DUE? How is that possible when this board seems to be one of the fastest ones they have? Most due seem to migrate to either the UNO or the Mega, but I would assume the DUE has more potential.

I'm still trying to find time to read through most of that documentation as of now, but we might be able to tap into the same libraries Sin was in. I guess the first thing to do is find some method of using the DMA controller. Maybe lock the processor into constantly checking a memory block of data and change a digital pin (maybe 8 for a bytes worth) of LEDs?

If I understand correctly, the processor will not have to spend time looking into a buffer to see if anything was received and then storing that data into memory if there was something, which would then be read again to change those LEDs. The DMA controller would automatically take care of watching for data transfers and send that into memory while the processor is doing other things.
Title: Re: fast SerialUSB for Arduino DUE
Post by: AdderD on Apr 25, 2016, 09:47 pm
Kind of. DMA allows you to tell the hardware that you've got a chunk of data somewhere and it should be transferred somewhere else but you don't want to have to make the processor do it in 4 byte chunks like you'd normally have to do. In some cases this isn't a big deal. Let's say you need to transfer 256 bytes of data from one place to another. The processor can do it in 4 byte chunks (32 bit) so that's 64 transfers. You can probably get it to do a transfer and loop in like 3-4 instructions. That's 256 instruction times if it takes 4 instructions. They're all on an 84MHz clock so it takes right about 3 microseconds to do the copy. Chances are you can spare the time most of the time. Where it really shines is if things are happening at a slower rate but you want to transfer a big batch of data and not have to babysit. A classic example is analog readings. They take some time (microsecond for each reading) and so if you want to capture 256 readings you either have to periodically check back (a lot) to read one, store it, read one, store it, over and over. With DMA you can tell the ADC hardware "read these ADC channels - 1, 3, 4, 6 64 times each and store the result here with DMA" and, it'll do it like magic. At the end you get a notification that you've got 256 readings waiting for you. You didn't have to poll or constantly deal with interrupts or start ADC readings each time or any of that. You just fire and forget and get an interrupt when the job is done. It's the awesomest thing ever. Now, getting back to USB, the best use of DMA would be for streaming a lot of data out of the Due. You could say "Hey, USB hardware, here's 4096 bytes of data I need to transfer out of the USB port. Lemme know when that's done" It will then do it as quickly as the hardware and other side allows. While this is happening you are free to do anything else in the sketch. Maybe you want to work on getting the next batch of data ready while this batch is transferring. If you have two buffers you can. In fact, DMA lets you tell it the next buffer to use while it is doing the current buffer. That way you can load one, tell it the next one, and then it'll automatically go to the next one and interrupt. If you have three buffers you can have it send one, have one ready to go as the next buffer, and work in the third one. Then when the first one transfers it automatically loads the second. Hopefully you're done with the third so you then set the third as the next buffer to transfer. The first is open so you begin working in there. That way there is never a single moment where the DMA hardware does not have something to send. This way you can max out the hardware transfer rate. You might not get a full 480mbit (you pretty much cannot) but you can do as well as the Due is capable of doing. For reception it's a little more weird. DMA requires a length you want to transfer so you wouldn't know the length generally. Except that the USB hardware has a 4K buffer so things transferred to the Due end up there first. Once the USB hardware has a block of data stored in its special buffer you could use DMA to transfer it to RAM. This doesn't save a whole lot of time but it might help a bit.

Hopefully that kind of explains DMA and how it is used.
Title: Re: fast SerialUSB for Arduino DUE
Post by: GaM3r2Xtreme on Apr 26, 2016, 07:13 pm
Alright I think I'm starting to understand how the DMA controller works. Thanks for the explanation Collin! I do have a few questions if you have any spare time to answer these:

When you say instructions, your talking about the assembly line variant after the compiler converts the c code we use. I can't remember the exact assembly terms or the correct syntax, but it would almost be:
- Something with a loop, BEGIN maybe?
- READ x, dma_buffer
- STORE ram_buffer, x
- Something to return back to the top, RETURN maybe?

From what I understand, we decide where in RAM we want the DMA controller to send the data to maybe through the use of some set function given by Atmel in the datasheet for the microcontroller. If we have some char array, say 8bytes long to give 8 total characters, would the interrupt be thrown once the buffer is completely filled in or read out, or could we decide to tell the controller, "HEY, I'd like you to read/write only half way up this buffer"?

I love the idea of the interrupt being thrown once complete, but what would happen if the microcontroller is already taken care of another interrupt? I know for the UNO, this new interrupt would be lost. My guess is that for the DUE, interrupts are put into a queue, since we have to clear the fired interrupt within the function call.

Would you happen to know what the hardware buffer size limit is for the DMA controller? What if we are reading/writing a big chunk of data, say 1kB worth. Would we have a possible buffer overflow?



Again, thanks for the great explanation. It does help to understand how everything is really working internally.
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 26, 2016, 07:46 pm
I have to give you points for enthusiasm! Unfortunately, as I have already stated, the DMA aspect is only a small part of this issue, the larger part is how to use the HS interface in preference to the FS interface..... and that is well beyond my capabilities/time available at this point. Judging by your huge over simplification of a DMA transfer, I suspect yours too. Your comment about poking around in the same area that sined modified would also lead me to the same conclusion. What we need is the Arduino team (who already know exactly how all of the modules gel together) to do something as I believe I have a better grasp of what is required than you do. It is a huge undertaking, more so if you first need to trace your way through all of the existing modules! This is not just going to be a bit of a modification to a couple of already existing modules (no offence sined)!! 

Don't let me put you off, and I would be one of the first to wish you well if you think you can do this, but honestly, it is going to be a serious project if you do.

Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: AdderD on Apr 26, 2016, 10:04 pm
When you say instructions, your talking about the assembly line variant after the compiler converts the c code we use. I can't remember the exact assembly terms or the correct syntax, but it would almost be:
- Something with a loop, BEGIN maybe?
- READ x, dma_buffer
- STORE ram_buffer, x
- Something to return back to the top, RETURN maybe?
Yes, I was talking about assembler / machine instructions. The ARM processor has a lot of neat modes that fold lots of operations into a single instruction but it still takes several instructions to build a loop that copies data from one place to another.

Quote
From what I understand, we decide where in RAM we want the DMA controller to send the data to maybe through the use of some set function given by Atmel in the datasheet for the microcontroller. If we have some char array, say 8bytes long to give 8 total characters, would the interrupt be thrown once the buffer is completely filled in or read out, or could we decide to tell the controller, "HEY, I'd like you to read/write only half way up this buffer"?
With DMA what you do is give the hardware a starting address and a size you want to transfer. Then it does that. You can optionally give it the starting address and length of a second buffer. It'll automatically load those values into the primary location and keep going if the second buffer details are filled out. Those second details are then cleared and you either have to load it again or you're done after the second buffer. The hardware doesn't care what the actual size of the array or buffer was. You can send half if it, you can go past the buffer, you can send the middle third. It doesn't matter. All it cares about is the starting address and transfer length.

Quote
I love the idea of the interrupt being thrown once complete, but what would happen if the microcontroller is already taken care of another interrupt? I know for the UNO, this new interrupt would be lost. My guess is that for the DUE, interrupts are put into a queue, since we have to clear the fired interrupt within the function call.
The DMA interrupt will wait until the current interrupt is done and then be serviced. You don't miss interrupts. You're right, if you don't clear an interrupt it can repeatedly fire forever and that's no fun.

Quote
Would you happen to know what the hardware buffer size limit is for the DMA controller? What if we are reading/writing a big chunk of data, say 1kB worth. Would we have a possible buffer overflow?

Again, thanks for the great explanation. It does help to understand how everything is really working internally.
I don't remember what the size limit is. But, the DMA controller doesn't have buffers. It transfers from one place to another. There are specific connections to the DMA controller and you can only do transfers along those connections. One such connection is from the ADC hardware to RAM. I don't know what connections the USB hardware has only that it does support DMA in some capacity. I guess I have to agree with ghlawrence2000 that this is a bigger, more complicated job than you might think. USB is terribly complicated and not that many people understand it. I'd love for the USB stack to use DMA but I'm not sure I really care to put the time in to understand the hardware well enough to make it a reality. So, it seems we could be stuck unless someone wants to really put some hard time in on this.
Title: Re: fast SerialUSB for Arduino DUE
Post by: GaM3r2Xtreme on Apr 27, 2016, 02:24 am
The USB protocol is definitely a hard one to understand. I have learned a little bit thus far, but no where near as well to recall everything about it. All those different tokens that need to be passed before any data can be send/received are all over the place! Not only that, but then the syncing, the error checking, the handshakes...

I agree with the both of you 100% that this is not an easy task by far. Ghlawrence and Collion, I have to give you guys some credit for knowing how all this works and sharing this with me. Most of what was mentioned in the thread is all new, mainly the DMA. Although, it sparks that interest and desire to learn more about it seeing as it all could be used for future projects. And heck the harder something is to learn, the more likely it is to stick around as knowledge.

From what I have grasped, we have the USB protocol sending/receiving chunks of data to/from dedicated USB hardware buffers (I believe DPRAM?), which then the DMAC will kick in to move this around where it needs to be to/from RAM as stated by the processor itself telling the DMAC what to do next. That's a start!

On an off topic, there has to be separation between UART hardware and USB hardware, right? I ask this because I did a little digging between all the different communication protocols to find which allowed for a quicker bit rate before stumbling across this topic.
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 27, 2016, 02:58 am
I am really happy you wish to learn, and seemingly are doing quite well  ;D. If you have read some of the articles I have linked to here, you would see how DMA can link with certain USB functions. This is a very complicated subject. I found another series of articles earlier, again from Atmel/ASF and it appears the Arduino team actually removed significant functionality from the Arduino core... :( I think this is going to run for some time...... Never the less, all input and ideas are welcome!! Keep up the good work!


Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on Apr 27, 2016, 03:02 pm
Just an interesting factoid to give you some inspiration as if you needed any! ;) I read somewhere yesterday during my browsings on the subject, that although 480mbps is the limit, approx 38MB/s is achievable on a DUE..... But there was no information to substantiate the claim nor any software to do so!

One thing I am not sure of, and I have not been able to find an answer, even if we (us/you/arduino team) can produce something workable, will the Windows usbser.sys driver work in HS mode? That has got to be a good start point, as I would have NO IDEA how to start to write a Windows driver....

 Regards,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: AdderD on Apr 27, 2016, 03:11 pm
As far as I know it already is working in HS mode. The electrical hook up on a Due is specifically done to allow for HS mode. The pipe buffer size is set to a larger size than you can do in non-HS mode, and I've tried to use a due compatible board through an USB isolator that doesn't support HS mode and it kills the connection and locks up the board. I'm pretty sure I saw somewhere deep in the bowels of the USB code a call to enable HS mode and disable low speed mode.

So, as far as I know it's already in HS mode if at all possible (obviously if you hook a due up to a USB1.1 port it would not be in HS mode).

38MB/s is about 304mbs so that's a little lower than the USB maximum but not by too much. It should be obvious to pretty much everyone that an 84MHz processor is unlikely to be able to sustain 38MB/s unless you use DMA or spend every single processor cycle moving data to the USB buffers.
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on May 11, 2016, 05:10 am
Just a little info.

Despite SOME updates to USBCore.cpp in V1.6.8 of the SAM Core, which yield minor improvement, none of Sined's modifications have been implemented.  :(


Regards,


Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: GaM3r2Xtreme on May 11, 2016, 05:18 pm
That's a shame... But it did look like there was a good bit of backlog of pull requests for the Due, which may take some time to get through.

It should be obvious to pretty much everyone that an 84MHz processor is unlikely to be able to sustain 38MB/s unless you use DMA or spend every single processor cycle moving data to the USB buffers.
The processor itself for sure wouldn't be able to handle HS, but the hardware seems to be capable. After reading a few pages on the USB hardware built into the processor, it operates on a 480Mhz Phase Lock Loop (PLL), which makes sense in order to handle the HS stream of data. I haven't been able to figure out if the DMA operates on the same PLL though. If it does, I can't see any bottlenecks for HS.

Also, I grabbed this off of the USB wiki page, "Due to bus access constraints, the effective throughput of the High Speed signaling rate is limited to 280 Mbit/s or 35 MB/s.[26]". I wonder if this applies to the Due as well. It might be the reason why 38MB/s is seen.
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on May 16, 2016, 01:50 pm
Sined,

Take a look at the bottom of this page (http://www.utftghl.com/downloads.html), do you have any objections?

Thanks,

Graham
Title: Re: fast SerialUSB for Arduino DUE
Post by: sined23 on May 16, 2016, 10:28 pm
Hi Graham! Use this patch for 1.6.7/1.6.8. It uses readBlock with any size like I did it for 1.6.5.
Title: Re: fast SerialUSB for Arduino DUE
Post by: ghlawrence2000 on May 17, 2016, 01:14 pm
Hi Sined,

Thanks for that.

Regards,

Graham