Wiznet W5500 and ioShield-A What’s old is new again!

It seems that the Wiznet W5100 Ethernet Shield has been around since the very beginning of the Arduino movement. Its integrated TCP and UDP IP stack enabling solid standardised networking since the very beginning.

The hardware implementation of BSD sockets interface abstracted the complex process of generating compliant IP and made sure that it was done correctly, and the buffering of network packets in integrated packet RAM, rather than on the host AVR micro-controller; was a great thing when you only have 1kB of RAM available as the original ATmega168 Arduino devices provided. For the current generation of Arduino devices, nothing has really changed.

Recently, I wrote about the new W5200 iteration of the Wiznet integrated IP controller, and how it is significantly better in performance and features than the older W5100 version.

Now, I have my hands on the latest version. The W5500 on an ioShield-A from Wiznet.

W5500 on ioShield-A from Wiznet

W5500 on ioShield-A from Wiznet

TL;DR. The W5500 is the latest and best iteration of hardware IP socket Ethernet devices from Wiznet, and also the easiest for hobbyists to implement. As usual, my code is here at AVRfreeRTOS.

So what are the key differences between the models, and how do they perform? I’ll try to look at three important aspects to using these devices; cost, implementation or how are they to use, and performance.


As Wiznet has iterated through the W5x00 series it has cost reduced the manufacturing significantly. The W5100 was produced in 0.18um process, as was the W5200. The new W5500 is produced in 0.13um process, with a 1.2v core, in comparison. Between the W5100 and W5200 Wiznet doubled the size of the internal packet RAM to 16kByte, but significantly reduced the number of IO pins and drivers, to make the W5200 (and W5500) SPI bus specialists.

The result of these cost reduction processes can be seen in the pricing information from Digikey. The price per 1,000 for W5100 is $4.32 each, whereas the W5500 is $2.64 each. In a commercial project, or even a significant crowd funded project, this can have a significant impact on the bill of materials.

Digikey W5100 Pricing

Digikey W5100 Pricing

Digikey W5200 Pricing

Digikey W5200 Pricing

Digikey W5500 Pricing

Digikey W5500 Pricing


The W5500 is available in 48LQFP which is aimed squarely at low tech solutions. The W5200 was only available in 48QFN which made it more difficult to use the chip in low volume applications.  While most people will purchase the W5500 on an Arduino Shield or similar platform, having the LQFP package does make it easier for the companies producing the Shields and modules for the hobbyist.

The three Wiznet W5x00 Generations

The three Wiznet W5x00 Generations

In terms of implementation differences between the W5100 and the W5200, I’ve already written on the extensive improvements to the SPI bus interface, both in terms of outright speed, and in the protocol improvements, doubling the packet RAM to 16kBytes, and doubling the number of sockets available to 8. The W5500 takes these improvements and finesses them to get an even better result.

Wiznet have prepared a summary of the differences between W5500 and W5200. The SPI protocol for the W5500 has been simplified, omitting the frame length field. The end of transmission is simply indicated by deselecting the chip with the SPI Chip Select line. This is an obvious and simple improvement.

The packet RAM on the W5500 has been made available as general storage for the host MCU. Both Tx and Rx RAM is available for use as required. This means that it is possible to augment the RAM on an Arduino Uno by 16kBytes (8kB Tx and 8kB Rx) which is 8x more than the ATmega328p has in total, and still maintain the same sized buffers available in the W5100, for example.

The Tx and Rx RAM is arranged in blocks associated with the socket, and the entire 16 bit address space is rolled out onto the configured RAM for each socket. This means that when writing or reading the W5500 Tx and Rx RAM the user doesn’t need to be concerned with masking the maximum physical RAM, and addressing roll-over is gracefully handled. This is unlike the W5100 and W5200, where RAM addressing would have to be masked against the configured physical RAM. If this sounds complicated, just check the datasheet where it is explained in a nice diagram.

For use in the Arduino IDE environment Wiznet has prepared W5500 drivers which can simply be copied into the IDE directory structure and used as needed. For general implementations, Wiznet have prepared a new generation BSD Sockets based Socket driver which is much more flexible and better written than the previous iteration.

I’ve implemented my code based on the Wiznet transition driver, which maintains the legacy BSD Socket style interface used in W5100 and in W5200. That way I can maintain one socket.h and socket.c code base as an interface, and simply use the relevant hardware driver W5x00.h and W5x00.c as required. I was pleased that in taking this path, Internet code that I’ve written previously “just worked”. This included the hardware sockets dhcp (using IPRAW), ntp, http interfaces which work with the W5500 protocol engine, and the uIP implementation that uses the MACRAW mode inherent in all three devices.

Of note is the resolution of the errata in the ARP engine, which required off device storage of the subnet mask in some situations, which affected both W5100 and W5200. With the W5500 Wiznet have put that issue behind them. I imagine that many other issues and inefficiencies in the hardware socket engine have been redesigned and resolved in the W5500 too.


The performance improvements of the W5200 over the W5100 have been documented, and the enormous throughput improvement obtained by using the streaming SPI Interface shown.

While the W5500 does implement an improvement in the SPI interface, by removing the data length selection field, there is no noticeable improvement in throughput over the W5200 using an AVR ATmega1284p Goldilocks as the platform.

One design goal for the W5500 seems to have been to make the SPI interface much more friendly for 32 bit processors, particularly Cortex M0+ MCU with limited RAM, by packing the addressing, and control information into one 32 bit (4 x 8bits) register. It is possible to imagine that there are additional performance improvements in the SPI interface if driven close to its design maximum SCK of 80MHz, rather than at the lowly SCK rate of 11.05MHz off the Goldilocks platform.

Testing W5500 SPI throughput with Saleae Logic on the Goldilocks ATmega1284p

Testing W5500 SPI throughput with Saleae Logic on the Goldilocks ATmega1284p

I compared the W5500 running uIP in MACRAW mode to the W5200 running identical (except for the driver) code and using the ping function to test how quickly the SPI interface can transfer a received packet to the host MCU, and then transfer the processed packet back to the W5x00 buffer for transmission.

The ping results were slightly slower than previously seen on the w5200. But I believe that is an external issue, possibly resulting from a change in my network. I have repeated the test with the W5200, and now get similar performance too. I believe I may have some network issues to resolve.

1300 Byte ping packet transmitted from a host to the W5500 interface running uIP in MACRAW mode.

1300 Byte ping packet transmitted from a host to the W5500 interface running uIP in MACRAW mode.

Looking at the output of the Saleae Logic and comparing the time taken to transfer the Ethernet frame into the host MCU, we can see that the time required to transfer the 1300 Byte frame is almost identical at 1.52ms.

W5500 Rx Ethernet Frame transfer to the ATmega1284p

W5500 Rx Ethernet Frame transfer to the ATmega1284p

W5200 Rx Ethernet Frame transfer to the ATmega1284p

W5200 Rx Ethernet Frame transfer to the ATmega1284p

Not surprisingly, the time to process the frame, and produce a response frame are also identical.

Ethernet Frame processing on the AVR1284p (W5500)

Ethernet Frame processing on the AVR1284p (W5500)

Ethernet Frame processing on the AVR1284p (W5200)

Ethernet Frame processing on the AVR1284p (W5200)


The W5500 chip is an improved version of the W5200, which was a greatly improved version of the W5100 device. It is a welcome new addition to a long heritage of IP protocol engines from Wiznet.

I think that the improved implementation in 48LQFP packaging and reduced supporting device count will make it easier for hobbyists and low volume manufacturers to generate great Internet tools off the Arduino and small ARM MCU platforms. We’re starting to see some implementations already.

Three generations of Wiznet Internet Protocol Devices. Goldilocks 1284p for scale.

Three generations of Wiznet Internet Protocol Devices. Goldilocks 1284p for scale.

As usual, my code is here at AVRfreeRTOS in the lib_iinchip folder.

Wiznet have made this post Treasure #14.


My SSD and eSATA caddy have arrived. So now we plug it all in and off we go.

Some testing on my amd64 Ubuntu Linux Machine, for comparison with the uSD cards used for the UDOO currently.

The SanDisk Black uSD card behaves in the amd64 machine, just as it did in the UDOO previously.

Now we test the SanDisk Extreme ii SSD, connected via USB3.0.

Quite a difference.
If we can get close to this performance in the UDOO, then it will be worth the money spent.

UDOO and SSD Preparation

The guide available on elinux describes all of the steps required for booting the UDOO from the SATA drive.

First prepare a small uSD card to be the boot drive. Format it with one ext3 partition, and install the u-boot bootloader as usual.

sudo dd if=u-boot-q.imx of=/dev/<MICROSD_DEVICE> bs=512 seek=2

This is sufficient to get the UDOO to boot.

Now prepare the SSD, by formatting it in the same way you formatted the uSD previously. I’m now adding an additional linux-swap partition about 2GB in size. Although there are warnings about using SSD for swap, if you’re using a full desktop on your UDOO, your browser won’t respect the memory limitation and you’ll create worse problems.

Although the 8MB free space is not currently used in the SATA SSD, because u-boot is contained on the uSD. My guess is that at some time soon the UDOO team will get the u-boot loadable on the SATA drive, and then this space will be needed.

Once the SSD is prepared, then the fastest way to replicate your already created environment is to copy disk to disk.

cd /media
sudo cp -rp UDOO_SDroot/* UDOO_SSDroot
sudo cp -rp UDOO_SDhome/* UDOO_SSDhome
sync; sync

One final thing is to change the references in the /etc/fstab from

/dev/mmcblk0p1 to /dev/sda1 for /
/dev/mmcblk0p2 to /dev/sda2 for /home
/dev/mmcblk0p3 to /dev/sda3 for swap

Now, plug the SSD caddy into the UDOO, and put the uSD in its slot.

First boot

When first booting the UDOO, interrupt the auto boot process and enter the commands noted in the elinux instructions.
Open a serial terminal to your PC with a baud of 115200 8n1. Reset the UDOO and press any key over serial terminal when prompted to cancel the autoboot. If you miss the prompt, you can press reset on the UDOO.

setenv bootdev "sata init; sata dev 0; ext2load sata 0"
setenv root root=/dev/sda1

And the UDOO should boot as normal, but from the eSATA drive.

Note that there can be errors with eSATA / USB3.0 casings. I initially chose one which uses the Prolific PL2773, which implements the attachment as a USB Bulk-Only Mass Storage Class. Unfortunately this storage class doesn’t have the capability to pass TRIM commands.

But, although the attachment for the SSD doesn’t have TRIM capability, the SSD reports that it does have this capability, via eSATA, and this confuses the Kernel.

Errors are caused by the Kernel calling for TRIM on the swap space during the boot process.

How to fix this? Well the simplest way is to throw away the disk casing and connect the SSD drive directly. So, this is what I did. The disk performance also increases markedly too!

UDOO SSD speed testing

The UDOO SATA port doesn’t achieve quite the same throughput as the amd64 desktop does over USB3. But the speed increase over the uSD card is significant, and is very noticeable in use. Worth doing, in any case.

After removing the SSD drive from the housing, and driving it directly, the performance increase can be seen. The average read rate has doubled to over 110MB/s and the access time has decreased by a third making it about the same speed as on the amd64 desktop.

In practice the desktop feels even smoother. Great result!
Screenshot from 2013-11-18 23:08:14

UDOO Ubuntu 12.04 Guide

Recently, my Quad core UDOO board arrived in the post. Initially, I tried the two provided uSD cards, with Ubuntu 11.10 and Android 4.2.2. I was a little disappointed that the Android version didn’t seem to work out of the box, but probably I did something wrong. What was more disappointing was that the provided Ubuntu operating system Ubuntu 11.10, is already past End of Life. Releasing a brand new device with an EOL operating system; I’m not sure what the UDOO team (or actually Freescale) are thinking.


Ok, so It is time to go my own way to get something that will remain viable for the long term. I use Ubuntu 12.04 LTS on my machines that aren’t running debian. So it is natural that I’d try the same Ubuntu Precise LTS solution, which is supported through to 2017, on my UDOO board too.

A bit of searching found Dave Cheney, who has written about installing Precise on his UDOO quad. However, Dave assumes that there is a working UDOO Linaro system from which to derive the result. I didn’t have that starting point, so I needed to find a solution from the uSD card inserted into my amd64 (Intel) machine, and build from a chroot armhf on amd64 solution. Fortunately, there are some references for how to take this path too.

Following this initial process, there are quite a few steps to get to a desktop GUI from the very simple Ubuntu core file system starting point, none of which are documented clearly. So, knowing that I’d need to take this path again (after I break something) it is time to write the steps down.

Get all the pieces of code necessary

From the UDOO Downloads page, get the latest versions of U-boot, Kernel, and Kernel Modules, relevant for your UDOO. Either the Quad versions or the Dual versions.

From the Ubuntu Core page, download the ubuntu-core-xx.xx.xx-core-armhf.tar.gz latest version that is there when you read this. At the time of writing it is 12.04.3. I’m led to believe that any recent version of Ubuntu Core would also work (see comments). There’s plenty of opportunity to experiment.

Prepare the uSD Card

Use the largest uSD card that you can find. Also, get the fastest one available at a reasonable price. I have now loaded the system on to a Sandisk Ultra uSD card, and compared the speeds to a Sandisk “Black” card. It is worth getting a “faster” uSD Card for the operating system, but perhaps not especially the “fastest”. The Black card’s performance is quite variable, and particularly the Average Access time ranges from 1.4ms up to 3ms, whereas the Ultra card’s Average Access time is consistently 0.9ms to 1.0ms after repeated testing. The other parameters seem consistently similar.

Black (Class 4 ) Minimum 19.5Mb/s Maximum 22.4Mb/s Average 21.0Mb/s Access 1.5ms
Ultra (Class 10) Minimum 19.6Mb/s Maximum 22.5Mb/s Average 21.0Mb/s Access 0.9ms

I have done some testing with a SATA SSD to compare it with these uSD Cards. If you can use a SSD as the root disk, then you’ll have a much more responsive experience.

Extreme ii SSD Minimum 81.6Mb/s Maximum 124.3Mb/s Average 110.4Mb/s Access 0.2ms

The elinux wiki has instructions for creating a bootable uSD card for UDOO. These are easy to follow, so I’ll not repeat all the details here. Using GParted I only left 8 MByte space before the start of the primary partition, and I labelled it “UDOO”. I also split the card in half, creating a secondary partition for the /home partition. This may take some time to complete, if your uSD is slow…



Before mounting the newly created filesystems, install the U-boot file into the first 8 MByte of the uSD card. Be sure to pick the descriptor for the root of the card (not the first partition). For me <MICROSD_DEVICE> is /dev/sdg.

Be very sure you’ re using the correct device; using the wrong device identifier will result in the loss of all data on the Hard Drive of the host PC used as you will overwrite the MBR.

sudo dd if=u-boot-q.imx of=/dev/&lt;MICROSD_DEVICE&gt; bs=512 seek=2

Create the Filesystem

Mount the just-created root partition on the uSD card. It will appear at /media/UDOO if you chose the same label as suggested. Then extract the tar.gz file containing the file system onto the uSD card with the following command, where <NAME_OF_TAR_FS> is the Ubuntu Core file downloaded previously.

sudo tar -xzvpf &lt;NAME_OF_TAR_FS&gt; -C /media/UDOO/

First, extract the Kernel Modules to the same current folder, and then copy the Kernel file and the Kernel Modules to the uSD.

sudo cp -p uImage /media/UDOO/boot
sudo cp -rp lib/modules/* /media/UDOO/lib/modules/

So, now the uSD card is complete, and the new Precise UDOO should boot.

But wait,… there’s more. The Ubuntu Core is absolutely the minimum required to get started. There’s not even a user defined, so if we want to log into the new system we have to do a little more to get ourselves started.

Chroot from amd64 into armhf

To be able to execute armhf commands from an amd64 platform we need to use qemu. So for that to work we need to make sure we’ve got qemu installed on the host platform. Check using dpkg.

dpkg -l qemu-user-static

Have your SD Card mounted on your Linux PC and go to your Ubuntu Core folder:

cd /media/UDOO

Copy the qemu for arm file:

sudo cp /usr/bin/qemu-arm-static usr/bin/

Make sure you have your network settings properly configured:

sudo mv etc/resolv.conf etc/resolv.conf.saved
sudo cp /etc/resolv.conf etc/resolv.conf

Then, mount sys, proc and dev:

for m in `echo 'sys dev proc'`; do sudo mount /$m ./$m -o bind; done

Finally, chroot into the target filesystem:

sudo LC_ALL=C chroot . /bin/bash

You are now in your ‘chroot’ which means you can run commands as if you were on your target ARM device.

Using the ‘chroot’

The first step is to verify the network connection is fine. You can run:

apt-get update

You are now ready to install any new package in your Ubuntu Core Filesystem using APT tools.

In the armhf ‘chroot’

Now we can do some commands to make the UDOO environment more complete.

apt-get update
apt-get install apt-utils whiptail language-pack-en-base
dpkg-reconfigure tzdata
apt-get upgrade
apt-get install sudo vim-tiny less net-tools openssh-server wpasupplicant isc-dhcp-client ntp #(and any other packages you want)

Adding a user

Out of the Ubuntu Core box, there is no user defined. so we have to add at least “SOMEUSER” to enable us to log into the system.

adduser SOMEUSER
adduser SOMEUSER adm
adduser SOMEUSER sudo

Fixing the Console

The UDOO serial port (the uUSB connector closest to the corner of the board) operates at 115200 baud, but by default the Ubuntu Core image is not configured to take over on /dev/console at the correct baud. The simplest solution to fix this is to copy the tty1 configuration to the console configuration, and then adjust to the correct baud rate.

cp /etc/init/tty1.conf /etc/init/console.conf
vi /etc/init/console.conf

change the last line to

exec /sbin/getty -8 115200 console

Enabling the Ethernet

The wired Ethernet port is not automatically enabled. Edit the interfaces file and add two lines.

vi /etc/network/interfaces

auto eth0
iface eth0 inet dhcp

Other Niceties

Obtain the Ubuntu universe packages. The /etc/apt/sources.list file has most of the sources commented out. These comments should be removed, before installing a GUI.

vi /etc/apt/sources.list

Leaving the ‘chroot’

If you want to get out of the ‘chroot’ just type:


Un-mount the target filesystem: Make sure you stay at the UDOO root point /media/UDOO/ and run the following commands. Go back to the original network settings. And the qemu can be removed too.

for m in `echo 'sys dev proc'`; do sudo umount ./$m; done
sudo mv etc/resolv.conf.saved etc/resolv.conf
sudo rm usr/bin/qemu-arm-static
sync; sync

Booting into UDOO Precise LTS

Insert the new UDOO Precise LTS file system uSD into the appropriate place, and then start up the serial console to watch the system boot. The serial port uUSB connector is the one closest to the RESET button, and should be connected at 115200 baud 8n1. It will appear on an amd64 Ubuntu machine as /dev/ttyUSB0.


When the system is booted the hdmi interfaced terminal should work successfully too. Use the login details you created above to log in, and profit!

Building the Desktop

From this point it is possible to install the GUI of choice. I have tried with LXDE, but given this is a Quad Core device, it may well run well with the standard Unity Desktop.

Installing LXDE or Unity (the standard Ubuntu desktop) can be done once you’re logged into the UDOO board, by either of these commands.

sudo apt-get install lxde-desktop
# OR
sudo apt-get install ubuntu-desktop

Once you have rebooted into your new desktop, it is useful to move the home directories over to the second partition that was prepared. The full desktop environments identify the second uSD partition and mount it automatically as /media/home.

sudo cp -rp /home/* /media/home

Edit the /etc/fstab file to get the partition to mount at /home, and reboot.

One thing missing (in a short amount of testing) is the firmware for the WiFi device. The best place to find the latest firmware-ralink is in the debian Sid repository. It is the same file for all architectures.

sudo dpkg -i firmware-ralink_0.43_all.deb

Final Thoughts

Compared to the Raspberry Pi the UDOO environment certainly runs very hot. The large heat sink on the UDOO is very necessary, whereby the Raspberry Pi doesn’t even need a heatsink. I guess that Freescale has packed a lot more (4x more?) into the same space that Broadcom used for its design, and that consumes more energy. Certainly, the lack of a GPU driver module and user space tools for the display, forcing software rendering doesn’t help. Hopefully Freescale will get their act together soon and Open Source the Vivante GC2000 driver code, or at least the hardware definitions to allow the Etnaviv team to progress quickly.

Neither Raspberry Pi nor UDOO are capable of being battery powered devices, which makes them pretty useless for any Internet of Things sensor project, IHMO. So, I’m not sure what kind of applications they’re really trying to address? Doesn’t matter, they’re still pretty cool devices and I’m going to be using the UDOO often.

avrdude 6.0.1, avr-gcc 4.8, and keestux Eclipse AVR Plugin 2.4.1

Always looking for the latest and greatest code for AVR, I scan the debian Sid repositories every few months for updated packages to use. Recently debian Sid included the latest gcc-avr 4.8 package, binutils-avr and the new avrdude 6.0.1 package. So I had to install them all to test.

Updated and Local

Updated and Local

The new avrdude 6.0.1 is the first release in two years, so it has a lot of good stuff, including a fix for the long standing chip delay bug affecting the AVRmega1284p used in the Goldilocks and Pololu SVP platforms.

Unfortunately, there is a new device format used in the avrdude.conf file which breaks the standard Eclipse AVR Plugin, rendering the MCU choice ineffective.

Asking a question on avrfreaks.net found the answer. keestux has fixed the problem and has released an interim AVR Plugin 2.4.1 which incorporates a fix for the change in avrdude.conf file format.

keestux Eclipse AVR Plugin 2.4.1 is at: http://www.ijzerbout.nl/avr-eclipse/updatesite

Add his update site to your software sources, and life is good again.

AVR Plugin 2.4.1

uIP on Wiznet W5200 versus W5100 on Goldilocks 1284p

I guess it is no secret, the reason why I’ve put so much effort into getting the Goldilocks 1284p board built. I was looking for a platform that would allow me to experiment with the uIP TCP/IP and UDP/IP stack with the most performance and flexibility possible while still being compatible with the huge range of sensors and actuator Shields that form the Arduino legacy. From the microprocessor view, the ATmega1284p used in the Goldilocks certainly achieves that goal.GOLDILOCKS-oblique_large

I’ve written in a previous post about the theoretical performance difference between the common Wiznet (or IINChip) W5100 used in almost all Arduino Ethernet shields and the component I have selected that uses the W5200 to provide the Ethernet interface. This post demonstrates the real world performance differential with a simple example.

Recently, I’ve been working with the W5500 on a ioShield-A.

But first, I am happy with the result of the uIP port to the Wiznet platform within freeRTOS. I’ve taken some of the old uIP v0.9 and v1.0 files from many sources, and updated them with the latest snapshot status from Contiki 2.7, to try to bring the last 5 years of experience into the result. Whilst the resulting codebase has not as yet been extensively tested, it seems to work as expected.


This is a simple test, sending 1300 byte PING packets to the MACRAW interface on the IINChip to be handled by uIP. After 100 PINGs the W5200 takes on average 3.804 ms, whilst the W5100 takes on average 22.109 ms for each round trip.

This means the W5200 is nearly 6x faster than the W5100 in real world performance.

uIP_on_W5200 uIP_on_W5100

Of note, this real world result is achieved whilst over-clocking the W5100 SPI bus out of specification at 5.5MHz (being SCK/4), rather than at 4MHz which is the specification. The W5200 SPI bus can, of course, run up to 30MHz or faster, so its limits are not even being tested by the Goldilocks ATmega1284p MCU.

W5200 SPI bus

The key differential which provides the W5200 its performance advantage is the use of multi-byte burst transfer mode for moving payload data into and out-of its controlling MCU. In theory the entire 32 kByte Address space of the W5200 could be transferred in one transaction. In practice, a full Ethernet frame can be transferred in just over 1 ms.

These shots show how the W5200 SPI multi-byte transfer works in practice.


The W5200 supports multi-byte burst mode transfers on the SPI bus. This is a 1300 Byte PING frame transfer out of the W5200, and returned by the AVR.

This screenshot shows an entire received 1300 Byte payload PING frame being transferred in 1.34ms.


The AVRmega1284p generates a PING response frame, and transfers it back to the W5200 in one burst mode transfer.

The Goldilocks AVR1284p takes 0.29ms to generate the response PING, and then it is transferred back to the W5200 for transmitting on the wire.

Detail of the burst mode multi-byte SPI transfer capability of the W5200.

Detail of the burst mode multi-byte SPI transfer capability of the W5200.

This screenshot shows the detail of the transmission of the PING frame to the AVRmega1284p. Note that each Byte takes less than 1 us to transfer.

W5100 SPI bus

The W5100 SPI bus uses a 4 byte transaction to transfer a single payload byte, and it is not capable of a multi-byte burst mode.


The Wiznet 5100 uses a 4 byte protocol to transfer a single data payload byte.

This screenshot shows the detail of the transmission between the AVRmega1284p and the W5100. It shows that to transfer 1 payload byte it takes about 0.036 ms (which is 36 us or 36x longer than the equivalent transfer on the W5200).


P1040382If you’re planning on building anything that relies on wired Ethernet, then go out of your way to find a Elecrow W5200 Shield or Seeed W5200 Shield. It is about six times faster than the common W5100 in the real world testing, and has many other great features.

uIP works well on the Goldilocks and provides a great platform for developing TCP/IP and UDP/IP stack applications.

Next steps are to implement CoAP and MQTT clients on this platform, to increase my understanding of both of these important IoT protocols.

Code, as usual, on Sourceforge.

Wiznet W5200 Arduino Shield by Elecrow

Oh W5100, why you so slow?

For a long time the standard Arduino Ethernet Shield has been driven by the Wiznet W5100 Internet Processor. This shield and the chip upon which it is based forms the basis of just about every IP enabled networking project in the Arduino world.

The Wiznet W5100 chip has some interesting features, such as direct and indirect memory access, but it has some severe limitations in its SPI bus capabilities . Also, the W5100 can support only 4 ports within its hardware IPv4 engine. Unlimited software ports can be added, by providing your own IP stack in MACRAW mode using Port 0, but that is not the road well travelled.

There are two major issues with interfacing with the W5100. First, the SPI interface is only specified to run at 4MHz. And second, the SPI interface supports only a byte mode transmission.

The limitation in SPI rate to 4MHz means that the standard 16MHz Arduino board SPI bus cannot be driven at any speed greater than SCK/4, if it is to remain within specification for driving the W5100. 20MHz boards, such as the Goldilocks, it must drop to SCK/8 if they are to remain within specification.

Also, the W5100 byte mode transmission requires a 4 byte SPI bus transaction for each byte of data to be transferred into and out of the network interface.

Counting the (unachievable) theoretical best case rate for the W5100, it means that 4 * 8 * 4 = 128 system clocks elapse to transfer a single byte of data. Ugh! Slow.

What to do?

I guess Wiznet must have realised this performance issue (which is more apparent with more capable 32 bit MCUs which run at higher system clocks than the slow old 8 bit AVR ATmega range) and they’ve recently released the W5200 as a replacement (specific to SPI bus interfacing) for the W5100 chip.

Wiznet 5200

Wiznet 5200

The W5200 brings a number of new performance features to the game, based on the well known and understood IPv4 network engine of the W5100. The table below contrasts the two chips.

Comparison Table showing Wiznet W5100 vs W5200

Key features comparison W5200 vs W5100

The W5200 is a much smaller and simpler chip to locate on the board, and it is easier to solder for those interested in private SMD constructions. Importantly for networking performance, the W5200 has twice as much Tx/Rx buffer memory for IP packets, and supports 8 simultaneous hardware IP sockets. These features make the W5200 a great performance increment on the W5100, and already sufficient to make a switch. An example of the size of the two chips compared can be found below, with the Elecrow W5200 on the left and an old DF Robot W5100 v1.0 on the right.


Elecrow W5200 and DF Robot W5100 v1

However, the greatest improvement in the W5200 lies in the area of the SPI bus interface. Wiznet has ditched the Direct addressing mechanisms (that took all the pins) on the W5100, and made the W5200 a SPI specialist, capable of running at up to 80MHz clock. That is a 20x increment.

Additionally, the W5200 supports SPI burst mode transmission. This means that up to the full Tx/Rx buffer (32kByte) could be read or written written in one transaction.

In the Arduino situation the W5200 can be driven at SCK/2, the maximum SPI speed achievable on an AVR ATmega MCU, and each byte takes one SPI byte to transfer. This means we can achieve a rate of 2 * 8 * 1 = 16 system clocks to transfer a byte of data.

This means the W5200 is 8x faster for the Arduino, and for Goldilocks 20MHz boards it will be 16x faster than the W5100 – fast as a leopard!

A practical analysis of the speed difference between the two Wiznet chips is here.

Easy to use.

The W5200 is easy to use, and easy to get.

Wiznet have provided some ready made W5200 driver files to include into the Arduino IDE. These replacement drivers for the existing W5100 driver files provided within the IDE just have to be substituted (or overwritten) to enable the slightly different SPI interfacing requirements of the W5200. They also provide C code drivers, which I used as a basis for my AVR freeRTOS code.

The Socket API provided by the W5100, and utilised by the Arduino IDE remains unchanged in the W5200. This means that it is only the performance enhanced SPI bus interface that needs to be rewritten to take advantage of the burst mode transmission, and the slightly different register locations associated with the increased Tx/Rx buffer and number of sockets available.

W5200 functional blocks

I was waiting for a long time for the W5200 to be put onto an Arduino compatible shield, so that I could use it easily. Suddenly, there are two on the market. One from W5200 Shield from Elecrow in China, and the other W5200 Shield from Wiznet.

I decided to purchase some of the Elecrow W5200 Shields. They looked to have a much better design than the Wiznet version, because Elecrow have utilised proper 5V to 3.3V buffers to ensure the safety of the on board uSD card, and have designed using the Arduino R3 standard.

The key and unique (afaik) feature of the Elecrow W5200 boards is the use of the lowered RJ45 jack, that allows the Ethernet shield to between other boards with no clearance problems. I have taken some pictures to show the difference between the standard RJ45 jack and the Elecrow W5200 board version, mounted on a Goldilocks board, and a standard Arduino Uno, with a LCD Touch Shield (even with under-slung SD Card cage) mounted over the top.

Image Image

Some small improvements.

I spent some time working with the Elecrow W5200, and have been in discussion with Richard and David (Tech Support) at Elecrow about the implementation. They have been very helpful in resolving some issues I have found in using their design.

Firstly, they have used quite a high resistance on the PWDN pin (which is intended to allow the W5200 to be powered down to reduce energy consumption). There is insufficient current on this resistor to hold ground, and sometimes the W5200 slips into PWDN mode and can’t be addressed. This can be solved by pulling jumper J2-2 to ground, or (permanently) by bridging Pin 1 and Pin 2 on U6 which is the buffer chip controlling the PWDN line. Check the schematics to see why this is so.

Secondly, the buffer chips used are driven from from 3.3V for Vcc. They are a little slow (100ns/V skew) at this supply voltage, and for the return data path on the MISO line they should properly be driven from 5V Vcc. At 5V Vcc the buffer chips are also much faster (20ns/V skew). The slower buffer chips, the LPF characteristic generated by the sensibly included output resistors, and the lower logic level compared to the AVR 5V TTL levels all combine to reduce the speed at which the SPI bus can work. Whilst the correct resolution is to drive the buffer chip at 5V Vcc for the inbound (AVR point of view) signal lines, I have found it is sufficient to remove and bridge the R24 resistor to achieve the SCK/2 SPI rate we desire.

This view of the Elecrow W5200 board shows the modifications in detail. I believe that later versions of the board will resolve these issues. And, with the Elecrow W5200 Shield’s unique recessed RF45 connector’s advantages and the speed of the W5200 MCU, all other sins are forgiven.

Elecrow W5200 showing R24 delete and U6 Pin 1-2 bridge.

Elecrow W5200 showing R24 delete and U6 Pin 1-2 bridge.


The Elecrow W5200 is a very speedy and easy to use alternative to the standard Arduino W5100 based solution. It is a great addition to my collection of IPv4 networking shields.

A practical analysis of the speed difference between the two Wiznet chips is here.

My code, as usual, on Sourceforge.

Goldilocks 1284p plus Elecrow W5200 Ethernet Shield

Goldilocks 1284p plus Elecrow W5200 Ethernet Shield