Ethernet SPI (like Wiznet 820 module) with Teensy 3 DMA - anyone tried this?

Status
Not open for further replies.

stevech

Well-known member
Ethernet interfaced via SPI (like Wiznet 820 module) with Teensy 3 DMA - anyone tried this?

Towards a goal of higher speeds, less CPU load.
 
I successfully use dma spi for a display. The trick is not to use any special spi features (i.e. The upper half of PUSHR) and modifying transfer attributes in a callback instead. I have posted my current code somewhere here but I'm too lazy to link to it now because I only have a phone in my hands.

Regards

Christoph
 
There are many challenges with using DMA for SPI. This thread has the best info.

http://forum.pjrc.com/threads/23253-teensy-3-0-SPI-with-DMA-nice-try

DMA probably offers little or no advantage for the SPI as used with the Ethernet library and WIZ820. In fact, it would very likely end up slower, because there's overhead to set up the DMA transfer. For things like audio or the OctoWS2811 LEDs where you transmit the same buffer over and over again, without any changes in settings each time, and where you want to do other work while it's moving data, the DMA is extremely efficient.

The Ethernet library involves reading and writing registers and memory in the W5200 chip. For that type of work, each transfer tends to be unique. What the library does next depends on the data just read. There are a LOT of small accesses made to the W5200. The library already has pretty well optimized code that can keep the data moving as fast as the SPI is capable of running. It does this with minimal overhead. Switching to DMA would achieve about the same speed, but the extra overhead to set up different transfers each time would probably be a net loss.
 
There are many challenges with using DMA for SPI. This thread has the best info.

The library already has pretty well optimized code that can keep the data moving as fast as the SPI is capable of running. It does this with minimal overhead.

That is, I believe since Paul added some changes into the Ethernet library in Teesnyduino 1.17 .
  • Working with the WIZ820IO does not require changing the #defines anymore to switch to a W5200 chip, but auto detects which chip is connected. Works beautifully.
  • Also some buffers were increased for added speed and in order to achieve that the number of ports was reduced to from 8 o 4.
The one thing I have not been able to figure out yet is how to change the SPI bus frequency to what the WIZ820io allows. But I have not really looked too hard either.
 
The one thing I have not been able to figure out yet is how to change the SPI bus frequency to what the WIZ820io allows.

Uncomment this line in w5100.cpp

Code:
  } else if (isW5200()) {
#ifdef USE_SPIFIFO
    //SPIFIFO.begin(W5200_SS_PIN, SPI_CLOCK_24MHz);  // W5200 is 33 MHz max
#endif

To get the best speed, use UDP and read the entire packet with one read(buffer, size) call.
 
From prior work, I recall the high overhead to transfer the packet data (send/receive) that is often 1000+ bytes.
 
Using DMA SPI for small transfers indeed comes with some overhead, but you can mix and match with "manual" SPI transfers. This needs some management, but might end up with a better overall speed if you also have large transfers.
 
wouldn't a good strategy be to use programmed I/O (non-DMA) to write the non-data items such as when opening a socket with a given protocol and setting the destination address, then for transferring a large (say, more than 100 bytes) amount of data to go into the transmitted packet (IP case), use DMA. Conversely, when a packet arrives, there's an interrupt and one can decide on use DMA yes/no based on how much data is in the on-chip buffer?

In the FreeRTOS driver I did for the 5100 chip, I had no option for DMA. I had a tricky time doing the loop to SPI-transfer of 1000+ bytes in or out, with interrupts enabled because data can arrive on a different socket and cause an interrupt while the non-interrupt level loop was running.
 
Conversely, when a packet arrives, there's an interrupt .....

The Arduino Ethernet library isn't structured like that at all. It doesn't use any interrupts. These chips have an interrupt output, but it's not even connected on any of the boards people use, because the library never uses it.
 
So does the application program have to call a library routine frequently to "poll" to see if new packets have arrived (or have been sent and if TCP, ACKd)?

For a byte-stream on a TCP connection (like a web/HTTP server's multi-packet response to a GET), the app would/could poll the address pointers in the chip to see if any unread data is present, and not be concerned with packet arrival events. But for non-byte-stream TCP connections, or UDP, it's different.
 
Last edited:
Status
Not open for further replies.
Back
Top