1 2 3 Previous Next 41 Replies Latest reply on Oct 12, 2016 6:49 AM by userc_40366

    Another Ethernet Component


      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!



        • 1. Re: Another Ethernet Component

          Gorgeous gift for the new year.
          Thank you very much.
          Waiting for news here:

          • 2. Re: Another Ethernet Component
                    Hi, ChuckE! I tried to send 2000 bytes in your example PSoC-W5100-Driver-master using the TcpSend (...) For PSoC4 it took 38 ms For PSoC5LP it took 15 ms at PLL = 64MHz For PSoC5 it took 18 ms at PLL = 64MHz and had to include High Speed Mode otherwise - does not go out from while (! ETH0_TcpConnected (socket)) For PSoC3 - did not work: the compiler does not like the word inline ((((   
            • 3. Re: Another Ethernet Component

              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.

              • 4. Re: Another Ethernet Component

                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.

                • 5. Re: Another Ethernet Component

                  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.

                  • 6. Re: Another Ethernet Component
                            Weeeeell :) Try to explain with an example. It is attached below. For testing, I used Hercules SETUP utility http://www.hw-group.com/products/hercules/index_en.html I do: 1. send a test string and see ETH0_SocketRxDataWaiting(socket) > 0 2. execute commands ETH0_TcpReceive(... 3. and check again ETH0_SocketRxDataWaiting(socket) only if I install a flag = 1, in W5100.c as here: str. 1394 `$INSTANCE_NAME`_ProcessRxData( socket, 0, buffer, RxSize, 1); i see ETH0_SocketRxDataWaiting(socket) = 0 Thanks for your patience, it seems this is not my last question   
                    • 7. Re: Another Ethernet Component

                      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





                      • 8. Re: Another Ethernet Component

                         Hi, ChuckE! I'm glad I could help you.

                            Does it seem to you that lm makes sense to create two components:   
                            1. Universal for PSoC 3/4/5 - is one that already exists   
                            2. Separately for PSoC5 using DMA for data transmission / reception.   
                            I guess you have seen this thread:   
                            Adding ethernet to a PSoC3/5 design    
                            Pay attention to the message from avast:   
                            lwip 1.4.1 implementation on Cypress PSOC5 device:     
                            It uses DMA for data transmission / reception.   
                        • 9. Re: Another Ethernet Component

                          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.

                          • 10. Re: Another Ethernet Component

                             And you humorist ......)))

                                You specifically put "Wait for SPI operation to complete" before proceeding?   
                                I made two corrections, the program is started, and I lost trail ((   
                                However, I'm not sure that I have correctly understood the problem.   
                                My changes in the attached file   
                            • 11. Re: Another Ethernet Component
                                      Sorry, here's the file   
                              • 12. Re: Another Ethernet Component

                                 No, I think I do not understand something.

                                    The program is not out of the loop   
                                    107           while (`$ INSTANCE_NAME` _SpiDone == 0)   
                                    I tested tit by logic analyzer   
                                    but I do not understand what  is this:  SPI0_ss0_m_Read ()   
                                • 13. Re: Another Ethernet Component

                                  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.

                                  • 14. Re: Another Ethernet Component

                                     problem - -  `$SPI_INSTANCE`_STS_SPI_DONE

                                        While I did so:   
                                        str 69      #define `$INSTANCE_NAME`_SpiDone  (`$SPI_INSTANCE`_ReadTxStatus()  )   
                                    1 2 3 Previous Next