Main Site Documentation

Wiznet W5500 Driver


Did that Wiznet W5500 driver ever see the light of day?


not that I saw


Well, I’ve been sitting on it forever hoping to put it in a unified network stack with my ESP8266 work, but the list is long and time is short, so here’s a quick zip-up of the driver source. I didn’t try building it and it is extracted from a larger project dir where I was trying to unify stuff, so let me know if there are any glitches when compiling and I’ll help you get past it…


@mcalsyn, Well I can say your code is better than mine.


no real surprise :grinning:


This for TinyCLR or NetMF? Is there a working driver for one but not the other? Or a lack of working driver in general?

I have a G30 based board waiting to get populated on my bench with a W5500 onboard. When I get around to assembling it I can do some work on the driver if it’s needed.


The driver was written for NETMF, however the low-level IO parts should be factored well enough to make the changeover pretty straightforward. In general, while this driver works, and it interoperates with the rest of my TCP stack (dhcp, ntp, dns, etc and the drivers for other chipsets), it has a pretty big code and mem footprint. I used it on a G30-class project and while the project was successful, it was a squeeze to get everything in there. This is the kind of driver that really ought to be baked into the native code, but I made a devtime-vs-footprint tradeoff. If I did it again with TinyCLR, I’d make it native code, presuming that there’s better support now for that sort of thing (I’ve not looked).

And thanks @Mr_John_Smith for the kind words.


OK I’m using NETMF, so that’s fine, no changeover required on my end. Is that driver licensed or available for commercial use? I’ll “skinny it up” and optimize it best I can this winter (probably around the month of December). I need FTP, and can make an optional add-on in the namespace for it if it doesn’t exist (I’ve built FTP implementations off of the RFC’s before and have some code I can port for this, if it doesn’t already exist).

Do you think the best way to get this to work well on a G30 without eating up all of the tiny amount of RAM, would be to split up the code in to sub modules? That way you can reference only the parts you really need…


I didn’t put my usual header on there, but it’s Apache v2 (party on!). I’ll get it up on github at some point and up on nuget with a TinyCLR port … someday. The zip was just to get it out there without further delay because I’ve been sitting on it a very long time.

The problem with modules (assemblies) is that each one takes up a bit of runtime mem overhead and perf penalties so you quickly hit a point of diminishing return when refactoring into assemblies. With NETMF, I only use assemblies for factoring when runtime composition and dynamic loading is required. Otherwise the per-assembly overhead will eat you alive.

I publish stuff as nuget packages, but more often than not, when I use it myself, I use shared-source projects as my preferred factoring, purely for perf reasons.

If you wanted to save some space, you could jettison functionality that you don’t need and I think you could probably optimize data buffer use a bit. And, depending on your application, you might want to keep the net driver resident, but use dynamic loading to swap in/out various app-level pieces. For instance, in wifi apps, I use a dynamic module for network onboarding, which then gets evicted from memory in favor of core functionality modules. I have used app domains for isolation and crash safety (but that brings with it a bunch of marshalling complexity and runtime penalties that would challenge a G30).

For the Radius watch (another marvelous Justin/Ingenuity Micro widget), I used a very thin core and driver layer and then dynamic modules for each watch applet.


Well, I’ve tried to port the driver to use TinyClr 0.6.0 and immediately ran into an insurmountable problem. There is SPI.WriteRead function. We can’t specify location in arrays to begin read and write, nor offests. This also dooms my L6470 driver.


Using right-sized arrays (instead of offset and len) and doing mem copies (instead of relying on offsets) are the necessary workarounds. That does introduce time and space inefficiencies of course, but (without having actually done it) I believe that it can be made to work under TinyCLR.


Considering that I would also have to do that to get my L6470 driver to work, it may just be better to add the functionality to a forked version of TinyClr. I’ll look into that as well. :sweat:


Oh crap that’s going to be a deal killer for several things I need to do as well, on networking code.

I have to be able to pluck partial blocks out of arrays.


You can pluck stuff out of arrays, just not as part of a SPI call. That’s a silly thing to leave out of a SPI API if you ask me, but clearly … nobody asked me. And that’s a Microsoft Windows.Devices.Spi design choice - not a GHI design choice. Even for Windows-class devices, it’s a silly inefficient choice. Heap allocations have real perf consequences (locks, heap fragmentation, increased GCs, etc), so forcing right-sized arrays seems daffy to me.

You can work around it of course - it does not preclude any scenario. It just adds unnecessary overhead.


Well it seems that I can’t load bootloader 2 onto the G120, which means I can’t load the modified firmware with the SPI changes. sigh.


Why can’t you load bootloader 2?


I downloaded the file, connected LDR0 and LDR1 to ground while power up the device. I then disconnect them, after which I connect to the the device via the virtual com port using tera term. When I press V (uppercase v) it shows me the version number (1.02). When I press X (uppercase x) I am prompted with repeating uppercase Cs to which I respond by sending the downloaded file via xmodem with the 1K option checked.

Upon restarting the device, grounding LDR0 & 1, connecting to the virtual serial port with Tera Term and pressing v (lower case v), I am presented with “BR”. When I press V (upper case v) I am presented with 1.02

My device will not update.


Bootloader 2 (BL2) doesn’t replace Bootloader 1 (BL1). If you hold down LDR0 and LDR1 on startup you will always enter BL1. To enter BL2, just hold down LDR0.

If no BL2 compatible firmware is found, the device will wait in BL2 mode just like it’ll wait in BL1 mode if there’s no firmware for BL1 to run.


So what does the truth table look like for the G120?

LDR 0, LDR1, Effect
Low, Low = Wait in GHI Bootloader 1.02
High, Low = Wait in TinyBooter
Low, High = Wait in GHI Bootloader 2.02
Ignored, High = Execute the managed application

Or is TinyBooter the same as Bootloader 2.02?


When using TinyCLR, there is no TinyBooter. The G120 BL2 exists where NETMF’s TinyBooter used to.

L, L = Wait in BL1
L, H = Wait in BL2
H, L = Don’t run deployed TinyCLR app
H, H = Run deployed TinyCLR app

The above table is true for all current TinyCLR devices. For devices that only have BL2 and no BL1, like the G400, “L, L” is an invalid combination that has the effect of waiting in BL2.