Go Down

Topic: fast SerialUSB for Arduino DUE (Read 10535 times) previous topic - next topic

sined23

#15
Apr 13, 2016, 04:54 pm Last Edit: Apr 13, 2016, 05:07 pm by sined23
Read speed is increased up to 12Mbit/s !!!  (using buffer 500 Bytes in SerialUSB.readBlock)
Use updated fast_usbread.zip

ghlawrence2000

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
UTFT_SdRaw now included in library manager!! ;) High speed image drawing from SD card to UTFT displays for Mega & DUE.
UTFT_GHL - a VASTLY upgraded version of UTFT_CTE. Coming soon to a TFT near you! 8) Shipping April 1 2016!

sined23

#17
Apr 14, 2016, 02:28 pm Last Edit: Apr 14, 2016, 03:21 pm by sined23
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.

sined23

#18
Apr 14, 2016, 02:41 pm Last Edit: Apr 14, 2016, 03:54 pm by sined23
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 :)

ghlawrence2000


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
UTFT_SdRaw now included in library manager!! ;) High speed image drawing from SD card to UTFT displays for Mega & DUE.
UTFT_GHL - a VASTLY upgraded version of UTFT_CTE. Coming soon to a TFT near you! 8) Shipping April 1 2016!

sined23

:) 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.

sined23

BTW Now Arduino Due with my improvement has the best results.
So, this picture is not right already :)


ghlawrence2000

#22
Apr 14, 2016, 08:22 pm Last Edit: Apr 14, 2016, 08:26 pm by ghlawrence2000
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
UTFT_SdRaw now included in library manager!! ;) High speed image drawing from SD card to UTFT displays for Mega & DUE.
UTFT_GHL - a VASTLY upgraded version of UTFT_CTE. Coming soon to a TFT near you! 8) Shipping April 1 2016!

sined23

#23
Apr 14, 2016, 09:23 pm Last Edit: Apr 14, 2016, 10:18 pm by sined23
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 :)

ghlawrence2000

#24
Apr 14, 2016, 09:29 pm Last Edit: Apr 14, 2016, 09:30 pm by ghlawrence2000
Hi sined,

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

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

Regards,

Graham
UTFT_SdRaw now included in library manager!! ;) High speed image drawing from SD card to UTFT displays for Mega & DUE.
UTFT_GHL - a VASTLY upgraded version of UTFT_CTE. Coming soon to a TFT near you! 8) Shipping April 1 2016!

sined23

#25
Apr 14, 2016, 10:04 pm Last Edit: Apr 14, 2016, 10:10 pm by sined23
I've added here https://groups.google.com/a/arduino.cc/forum/?fromgroups#!forum/developers

ghlawrence2000

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
UTFT_SdRaw now included in library manager!! ;) High speed image drawing from SD card to UTFT displays for Mega & DUE.
UTFT_GHL - a VASTLY upgraded version of UTFT_CTE. Coming soon to a TFT near you! 8) Shipping April 1 2016!

Okio

#27
Apr 15, 2016, 07:10 pm Last Edit: Apr 15, 2016, 07:25 pm by Okio
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.


ghlawrence2000

@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
UTFT_SdRaw now included in library manager!! ;) High speed image drawing from SD card to UTFT displays for Mega & DUE.
UTFT_GHL - a VASTLY upgraded version of UTFT_CTE. Coming soon to a TFT near you! 8) Shipping April 1 2016!

ghlawrence2000

@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
UTFT_SdRaw now included in library manager!! ;) High speed image drawing from SD card to UTFT displays for Mega & DUE.
UTFT_GHL - a VASTLY upgraded version of UTFT_CTE. Coming soon to a TFT near you! 8) Shipping April 1 2016!

Go Up