After doing some work with the PSoC4, I noticed a few little deficiencies in the alpha version of 1.2 that was in the GutHub repo. So, with my project nearing completion I’ve patched in the updates calling version 1.2 complete.
String parsing of MAC addresses
ASCII String read back of the MAC and IP addresses.nbsp;
Sockets 1 through 3 are addressed correctly in all instances.
Data from a closed socket can now be read from the application.
Skip to the Project setup section if you’re not using an eval board
I mainly use the PSoC Pioneer (PSoC 4) and the FreeSoC Explorer (PSoC 5LP) as test beds for component development, and for the W5100, there happens to be a handy Arduino shield (Ethernet Shield, $38 Digikey) available so no hand wiring today.
For the PSoC 4, just plug the shield in to the Arduino compatible pins on the the Pioneer board (making sure that you’ve soldered in the 6-pin SPI connector), however, the PSoC 5LP setup takes a little more effort since the Explorer does not have the Arduino 6-pin SPI interconnect. So, we just jumper wire from the MISO, MOSI, and SCK pins on the 6-pin socket of the Ethernet Shield to The P4 connector I/O of the explorer.
Once the hardware is set up (or your custom board is built), you need to add the e2forlife_W5100.cylib to the project workspace and set it as a dependency for your PSoC Project. This is simply accomplished by selecting File->Add->Existing Project… from the PSoC Creator menus, or by right clicking the work-space and selecting Add->Existing Project...
Once the driver library project has been added to the work-space, right click the application and select “Dependencies…“. When the dialog opens, select Components check-box for the E2ForLife_W5100 user Dependencies.
Setting up the firmware using PSoC Creator (currently 3.0) is a snap. Just switch to the community tab, and expand the Communications/Ethernet tree. For the PSoC 5LP, drag the “E2ForLife – W5100 (SPIM mode)” macro from the right hand selector and place it on the schematic sheet.
(PSoC 4 Users:) On the PSoC 4, there are two options available. The “E2ForLife – W5100 (SCM Mode)” Macro will utilize the new SCM hardware blocks within the device, and the “E2ForLife – W5100 (SPIM Mode)” Which will utilize UDB SPI Master Mode implementation of the interface.
Configuring Component Options
In order for the PSoC to properly communicate with the W5100 the SPI component needs to be configured to operate in 8-bit mode 0 or 3 SPI. Depending on the board routing, clock scheme, and environment, the data rate can vary between 8 and 30 MHz. The default configuration set by the macro initializes the SPI device for an 8 MHz data rate.
W5100 Driver options
The W5100 driver is sectioned in to Driver Configuration, Configuration, and Hardware Configuration. These sections are initialized by the macro to default values and the hardware configuration section is set function with the SPI hardware added.
PSoC 4 Note: Using the PSoC Pioneer board with the Arduino Ethernet Shield will require that the SS_NUM parameter be modified when using the SCM mode. SS number 1 is tied to the W5100, not 0. Another big note is that you will have to modify the default SCM settings to enable 2 SS outputs from the module, assign the CSn output to SS1 when making pin assignments.
The number of milliseconds to wait for the W5100 command to execute before declaring a timeout
Flag used to include the code for the support of TCP/IP. Since TCP is directly handled by the device, only minimal code is required for TCP networking
Include the protocol processing for UDP
The number of milliseconds to wait for the device PLL to lock after a reset or power on
The number of milliseconds before declaring a generic timeout
The default gateway IP address for which the W5100 will be configured
The IP Address for the device when operating with fixed IP addressing.
The MAC Hardware Address for which the W5100 will be configured
The subnet mask to be used for Ethernet communications. Typically 255.255.255.0
The instance name of the SPI interface. Configure this to be the name of the interface component for the SPI communications interface.
Integer index of the slave select from the SPI interface. This is used for the SCM component interface for PSoC 4
For this post, I’m concentrating on getting up and running using the driver, so the application will start, initialize the board hardware, then open a simple telnet server and wait for a connection. Once the connection is established, it will print “Hello From E2ForLife.com” and end.
For this we will use 7 functions from the API. First we will call W5100_Start() to initialize the W5100 device and local driver data. Next we will create and open a socket using the W5100_TcpOpen(), and start a server using the W5100_TcpStartServerWait(). And lastly use the W5100_TcpPrint() to send the data followed by W5100_TcpDisconnect() and W5100_SocketClose() to terminate the connection
* First the SPI peripheral must be initialized
* so that the W5100 driver has hardware to use
* for the chip initialization that will
* occur next
* The next section initialized the W5100 to
* default settings setup in the component
* configuration dialog.
The startup and in initialization section of the code mainly performs only 2 functions in this case: Start the hardware, Start the driver amp; initialize the W5100 registers. The hardware initialization is executed using the Cypress API call for the SPIM component (or the corresponding SCB for PSoC 4). Following this W5100_Start() is called from the W5100 driver API. This function initializes the internal RAM used by the driver and configures the hardware registers within the W5100.
* Now that the W5100 is initialized and configured,
* open a socket, and start a server and wait for
* connections until the
* If the socket was opened the socket number
* will be in the range of 0 - 3 to reflect
* the socket that was used within the W5100
/* Wait for server connections */
/* Send the string to the remote terminal */
"\x1b[2JHello From E2ForLife.com\r\n");
* Wait for the string string to transmit
* over the network before closing
/* Disconnect from client (drop connection) */
/* Close the socket */
Within the main loop, the socket is opened, a servers is started, output is transferred, and the the connection is terminated. First, the socket is opened through a call to W5100_TcpOpen() with the active port passed as a parameter. In this case, we used the Tcp port 23, since we are going to start a telnet server. The next step in this simple application is to start a server and wait for connections. Since we are not doing anything of value while waiting, I used the simple API call W5100_TcpStartServerWait(), which will start a server on the open socket passed, and wait for a connection to be established.
Once the connection has been established, the API call will return, allowing the application to send it’s string using the W5100_TcpPrint() call to send a string (ASCII-Z style) to the remote client using TCP. After that, we just close the connection gracefully by disconnecting (W5100_TcpDisconnect), and then close the socket to free the socket to be opened for another function using the W5100_SocketClose() API call.
So, there you have it… A very simple Telnet server using the W5100 driver.
Does Ethernet come easy in a world of 8K of RAM and clock speeds under 100 MHz? The simple fact is that the TCP/IP protocol stack can become a beast to implement within a small system, and while there are great projects such as Contiki-OS and LWIP, if there isn’t a port already available for the chosen platform you’ll either have to port the code or change the platform (something that is not always achievable).
So, how does one simply just “add” Ethernet to a project that is already underway without blowing the budget, schedule, or creating a generally irate customer that has no more time, money, or patience to wait for something that his “PC already has for free”? Enter the world of the Ethernet Application Specific Integrated Circuit (ASIC), or as sometimes referred to as TCP/IP Chip. WIZnet (www.wiznet.co.kr), a Korean semiconductor company developed a family of “iEthernet” devices that implement the MAC, PHY, buffer memory, and a protocol implementation ASIC.
This chip provides everything a budding developer might want in order to implement and Ethernet interface to an embedded device without putting you behind schedule. Also worth mentioning here is that the Arduino 8-bit AVR boards have been using this device on the Ethernet shield boards.
It also provides the coolness factor of being able to walk in to a room with a working prototype only two days after the “idea” was sprung.
So before getting in to how to make this device in to a quick, inexpensive solution to an otherwise pesky problem, I’ll first get in to some of the specifics related to this family of devices. Note that while this device offers an excellent solution to the implementation of Ethernet, there are some aspects of the device that might make it a non-ideal end solution.
Protocol Implementation: TCP, UDP, ICMP, IPv4, ARP, IGMP, PPPoE, IP, RAW MAC
Power Down Mode + Wake On LAN
SPI Mode 0/3 interface with Processor
16K RAM for internal circular buffers
Up to 4 simultaneous Socket interfaces
3V IO with 5V Tolerance
What’s the downside? Well, with an SPI link between the processor and the Ethernet device (there is also an 8-bit parallel interface), the max data rate achievable is going to be somewhere around 8 Mbit, a usually acceptable data rate for many small embedded devices. However, if you pay attention to the chip routing on the board, the max tested SPI clock speed is 33 MHz, or roughly 264K bytes per second, which yields a more than adequate data rate for most small embedded devices.
Also, the W5100 lacks a hard-coded MAC address. This could make a handy feature for making embedded hardware that can spoof the address of a computer on a network and capture packets, but for most systems you’ll need a unique MAC address. I’ll address how to get around the MAC address issues later, but simply, this means you’ll need to purchase addresses or a device that has the address pre-programmed (For demo,non-deliverable or test hardware you could always resort to 0x00DEADBEEF00). Also note that Arduino Ethernet shield boards ship with a MAC address that is printed on the sticker on the bottom of the boards.
Next time, I’ll be cracking out the PSoC kit, and hooking up an evaluation module so we can start writing some code to get the W5100 working in a sample application.
If your motivated to just jump right in to the code, the GitHub repository can be found here.