- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A while back I started looking for a viable solution to adding Ethernet control to my PSoC 5LP project, and unfortunately, I did not find a solution that would work in . After trying several other alternative solutions, I developed the attached implementation of a driver for the W5100 WIZnet device used on the Arduino shield.
This component is a software-only driver (you will need to link it to a SPI port), and it currently supports TCP, ARP, and UDP using the built-in protocols of the W5100 device. It also supports SPI port sharing to allow the application to take advantage of the ability of the SPI bus to handle multiple connected devices. The driver also includes macros for using the driver with the SPIM or SCB components from the Cypress libraries.
This is not a conversion of the C++ code from the arduino library (ref. Element14 100 Projects in 100 days); it was written from scratch as a component for the PSoC devices.
I have tested this using the PSoC 4 and PSoC 5/5LP and I have sucessfully built a 6-port application with a PSoC 5LP. The driver has not yet been fully tested o nthe the PSoC 3, but I believe that it should work based on some initial testing results.
Hope everyone has as much fun using this component as I had writing it!
-Chuck
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Gorgeous gift for the new year.
Thank you very much.
Waiting for news here:
http://www.e2forlife.com/author/chuck/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Pavloven! I happy to see you tried out the component, and I am sorry to have replied so slowly.
When using the macros within the component to quick-start a project, you might need to tweek some of the settings due to relationships between the BUS_CLK rate and the SPI interface divisor. I tried to default them to what seemd to work right out of the box, but that was assuming a 48 MHz PLL out. with a 64 MHz input to the SPI part, you might need a larger divisor to divide down to the data rate for the part, so the "High speed mode" may need to be checked.
I plugged your settings and data length in to a test application to measure the timing and the SPI settings with a setup similar to what you were using, and I measured whese results using my logic analyzer:
PSoC 4 SCB mode was about 30 ms PSoC4 SPIM mode was about 46 ms using a PSoC Pioneer board + Arduino shield and a 48 MHz BUS_CLK with data rate at 6 Mbps.
PSoC5LP was roughly 11.6 ms measured using a FreeSOC Explorer + Ardiouno Ethernet shield, and a BUS_CLK of 64 MHz and a SPI data rate of 16 Mbps.
What this means in effective "baud" rate for the port ranges from roughly 1.38 Mbps (11.6 ms xfer) to a worst case (46 ms xfer) the data rate on the port was about 348 Kbps. The effective data rate of the driver is highly dependent upon the READ_WRITE_DELAY configuration parameter of the component, the data rate between the PSoC device and the W5100 component itself.
The W5100 device does not support "burst mode" transfers ( see the W5200 for the inclusion of burst mode), so for each byte transfered using the device, the processor has to write 4 bytes to the W5100 over the SPI port, and additional 8 bytes to update the txx pointer and another 8 bytes to read the tx pointer at the start. This equates to a huge amount of overhead and a loss of EDR.
You can try to tweek the READ_WRITE_DELAY within the W5100 interface driver to reduce some of the overhead of the driver. Basically this parameter is a "cheap" way to estimate how long to wait for the SPI interface to complete any operation and allow the CS to return to an inactive state. It is specified in microseconds of delay, so for example at 6 Mbps data rate on the SPI port it would take roughly 5.33 uS to send the 32-bit packet to the W5100. The READ_WRITE_DELAY would be set to 5 in this case. At a rate of 16 Mbps, it takes about 2 us to send the 32-bit packet, which would save about 3 us per operation on the W5100 which in the case of 2000 bytes saves about 6 mS off a transfer between a 6 Mbps and 16 Mbps data rate.
Also switching from DEBUG to RELEASE will speed up the execution of the code slightly.
The GIT repository: https://github.com/e2forlife/PSoC-W5100-Driver/ has 3 example projects and the latest development code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, ChuckE! I have questions about W5100.c:
_SocketRxDataWaiting(socket) is cleared only when the flags in _ProcessRxData set to 1.
When and how can I manage the flags.
thank you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
SocketRxDataWaiting() returns the number of bytes stored in the RX circular buffer within the W5100 device (register Sx_RXRSR in teh W5100). It is a handy way to check if there is a packet waiting. The function reads the RXSIZE register within the 5100 in a loop until it detects two buffer lengths that are identical (an attempt to block until a packet receive has compmleted). In order for this to be zero, you must read the waiting data from the device, which is why the call to ProcessRxData clears the result from SocketRxDataWaiting().
In order to clear the result without reading the data from the chip you'd probably have to write the RX Read Pointer to an address of the RxReadPtr + SocketGetRxDataWaiting(), then issue a RECV command to the W5100, or use the code from lines 979 through 1012 of W5100.c, without executing the loop from lines 988 through 1004. You may also need to execute the line at 1442 as well for the W5100 to register that the received hdata has been removed.
I didn't include any buffer management, since the Ethernet controller will reject packets that are not addressed for the MAC, and for my application I needed to handle every packet that was received, thus all of the management of the buffer length was done through the receive data functions. Basically once a loop I would call the TcpReceive() function and check the result. If the result was non-zero there was data received, if it was zero there was no data read and the Ethernet handler in the main code would have no data to process.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I took a look at the project which you ahd posted, and yes, you are correct. Executing a TcpReceive() woudl not cause the receive data pointer to be updated, also this would have been the same with the UdpReceive() as well.
It appears that you have discovered a bug in the _ProcessRxData() function that was preventing the Rx read pointer from being updated when pulling data out of the buffer. The "flag" parameter was provided as a placeholder for future enhancement, such as look-ahead processing without having to read the entire buffer in to memory. For example stream processing, where you want to keep the bulk of the data in teh chip to conserve chip PSoC memory.
Sometimes we're too smart for our own good 🙂 I have fixed thebug and build an updated component V1.1. The updated library is attached to this post.
Also, thanks for finding the bug, and let me know if you find any others
Thanks
Chuck
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, ChuckE! I'm glad I could help you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using DMA for transfers betwen the PSoC and W5100 would be an interesting addiiton to the component, and I 'm presently looking in to this to support an enhancement to the PSoC5/5LP version. I think that adding DMA to the transfer of data blocks could help quite a bit, but, since all of the transfers occur in 32-bit blocks the overall operational speed of the component might not increase much due to the overhead of the W5100 device. Unfortunately this is a limitation of the W5100.
To obtain a big speed increase, considder using the W5200, where data transfers support burst mode, which an ideal situation for DMA.
I'm looking at adding the ability to use DMA as an option for the configuration settings from the schematic editor, since that will keep all of the code contiguous and a bug fix/enhancement in one version would be replacated in to the other chip versions. Also, it will help to speed regression testing.
There is a big defference betwen what this component does and what the port of lwip does. Mainly, most of what LWIP does is handled by the W5100 device with 0 processor involvement. The W5100 is an ASIC that includes a PHY, MAC and the TCP/IP engine for processing packets, thus the only additional software required beyond the low-level device interface are for the implementation of protocols that are not directly supported by the chip (TCP/UDP/PPP), for example DHCP, STMP, and WWW.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
And you humorist ......)))
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, I think I do not understand something.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The SPI0_ss0_m_Read () call reads the state of the SPI SS pin that is used to select the W5100 device. Since there is no counterpart ti SPI_DONE in a status register for the SCB (there is an iterrupt that could be generated), The SCB code reads the state of the pin used for the SSx attached to the W5100. When the pin is high, the SCB is available for writing, when low, it is busy.
The counterpart to this is the SPI_DONE flag in the SPIM. I'm not sure what is going on with the lockup (I ave experienced something similar before on another project), but I'll look in to it today.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
problem - - `$SPI_INSTANCE`_STS_SPI_DONE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On line 73 of W5100.c, change the code to the following statement:
#define `$INSTANCE_NAME`_SpiDone (`$SPI_INSTANCE`_ReadTxStatus() & (`$SPI_INSTANCE`_STS_SPI_DONE | `$SPI_INSTANCE`_STS_SPI_IDLE))
This will include the IDLE flag in the condition to determine that the SPI device is available for writing. In the testing that I was performing, the deadlock seems to be caused by a condition where the SPI is reporting that it is not DONE, but it is IDLE. Either condition is acceptable for writing, so I added the IDLE flag in to the conditions.
This change will be included in the v1.2 release, and is available on the GitHub archive.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When working with TCP, if the connection is terminated you need to "recycle" the connection by closing, re-opening and restarting the server. this is because the TCP controller in the W5100 enters a "TERMINATING" state when the remote system ends the connection, which requires the software to then close the open socket to complete the termination, then another socket must be opened to allow for further connections to occur, otherwise the system will appear to be "dead" or locked-up.
Try using the _SocketProcessConnections() call to handle the socket at then end of the loop. There is some example code in the document, what it doesn't show, however, is that the server must also be started to allow for future connections to the server to be established. If you are processing your connection within a loop, after re-opening the socket with a call to _TcpOpen(), call a _TcpStartServer() to place the W5100 in to the LISTEN state and allow for future connections.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This project looks very well designed.
My interest is getting it to work with the later model W5500 chips (esp. on psoc5lp).
I believe that the key changes would be the type/size of SPI comms.
But I am uneasy about tinkering with the component code.
Any clues, or pointers?
Thanks for the great job sofar.
http://wizwiki.net/wiki/doku.php?id=products:wiz550io:allpages
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi ChuckE,
Thanks a lot for your work on this! I, like Michael, am interested in using the new part, the W5500, with a PSoC5LP. Do you think your component could easily be used with the W5500? When I go on Wiznet's website and go to the pages for the W5100 and the W5500, it looks like the drivers they provide are different between the 2 parts, which makes me think there might be differences that would require some tinkering in your component. Have you, or someone you know, tried to use your component with a W5500?
Thanks!
Scott
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for taking the time to check out the component. I too am interested in the 5500, and evaluated the device for a project on which I was working. Unfortunately, WizNET was not consistent with their device interface across the family and the driver won't work right out of the box for other components.
I have a version that works with the W5200, and I've started work on the W5500, but I've not gotten to the point of being able to get something that looks like it's ready for testing in hardware. This is mainly due to the somewhat obvious extension of just building a driver that works with all of the family. So, presently I'm in the process of merging the W5200 code with the W5100 code that is already working then adding in the 5500 processing.
I'll post an update when the merge is complete.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the meantime I have managed to get a port of the current Wiznet ioLibrary_BSD working.
Simple upd and tcp loopbacks look ok.
Using W550io (W5500) chip along with psoc 5.
let me know if interested.
rgds Michael.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh yes, since I intend to use a Wiz550io within my current project, this would help me tremendously. Maybe I can port it over to PSoC4, that would be even better...
Thanks,
hli
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is the trimmed sample code. (WIZNET W550io PSoC5)
Pls. note project settings (jpg), I hope I included everything...
good luck, Michael.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
trying again, file upload failed...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3rd time lucky ??
trimmed file size.
MJ
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
wonder what the limit on file upload is??
again I try...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the following is a correction and tweak...
//------line 226 --------------------------------------------------------------
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ChuckE, your newest PSoCPioneer+ArduinoShield_SPIM_Example worked straight out of the box...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Nice projects collection going.
Many thanks to the authors!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I also got the server example to work !! (thanks Pavloven), , and the random char transfer test.
All on PSoc4, in SPIM mode.
good work folks...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to use WiFi: ESP83266 as Access Point
SSID: "AP_test" PASS "12345678" http://192.168.4.1
My code is still very primitive ....
The project file for CY8CKIT-030: AP_Serwer.zip it here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your latest post Pavloven, I have ordered a device (good price).
Many need a little help with English translation...
Rgds Michael.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does the ESP83266 board use a separate power supply?
Rgds Michael.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, but ..... A 300 mA/3.3V power supply is definitely required, as well as at least a 10 µF decoupling capacitor.....
http://www.esp8266.com/viewtopic.php?f=6&t=497&p=2293&hilit=supply#p2293