Shop OBEX P1 Docs P2 Docs Learn Events
W5500 Driver for the P2 — Parallax Forums

W5500 Driver for the P2

Hi All, I need a P2 driver for the W5500 SPI to ethernet chip for a project I am working on and was wondering if anone has looked at this before?

I like to look of the P1 version in OBEX but have no idea where to start converting the Machine code from the P1 to the P2. I can just about cope with SPIN1 to SPIN2 conversion but have no idea how to start converting the PASM1 part to PASM2 at this time.

Are there any Tutorials / hint sheets relating to converting existing PASM1 into PASM2?

Any tips apreciated, thanks all.

Comments

  • ke4pjwke4pjw Posts: 1,169

    I wrote a driver for the W6100 that supports SPI. Let me take a look at the W5500 datasheet and see of different it is. We might be able to get it working easily.

  • ke4pjwke4pjw Posts: 1,169

    Looking at the datasheet they look almost identical. This post, essentially says the same thing.
    I think I may have a W5500 in an Arduino shield that I bought in the RadioShack going out of business sale years ago.

  • Here's a driver I wrote a while back for the WIZ550io module to function as a client for a project, since expanded to use as a server just to play around with.

    Wiznet W5500 server demo

  • ke4pjwke4pjw Posts: 1,169

    @ChrisGadd very nice!

  • lab_geslab_ges Posts: 91
    edited 2024-04-29 10:37

    Wow, thanks very much @ChrisGadd & @ke4pjw.
    Sorry it has taken me several days to reply but I left that message on Friday afternoon here in the UK and I was busy all weekend & it is now Monday morning before I could get back into it.

    I searched the OBEX for W5500 on the P2 and got no results, I never thought to do a search for Wiznet5500 or even just 5500 & P2.
    I even searched the forums and saw a few discussions but nothing about the P2.
    That will save me a lot of work, as at the same time I am trying to learn to program the P2 for the first time.
    All my previous projects have involved the P1 but I couldn't resist trying the P2 on this occasion.

    Thanks again, I hope I can help out in some way on a future ocasion.

  • Hi @ChrisGadd
    I have been looking through your "Wiz550io driver.spin2" code.
    In PUB init() you do a divide by 20_000_000.

    PUB init(cs_pin, sck_pin, mosi_pin, miso_pin, reset_pin)
      longmove(@cs,@cs_pin,5)
      pinstart(sck,P_OE | P_TRANSITION,(clkfreq / 20_000_000),0)                                ' Configure smart pins for sck, mosi, and miso
    

    I am still trying to understand smartpins but I assume this is refering to the standard 20Mhz P2 clock?
    Can you confirm that please? My board has a 25Mhz clock, so I guess I need to divide by 25_000_000 instead?

  • JonnyMacJonnyMac Posts: 9,156
    edited 2024-04-30 17:39

    This line

    pinstart(sck,P_OE | P_TRANSITION,(clkfreq / 20_000_000),0) 
    

    is setting the SCK pin to transition mode which when used to generate pulses, results in a 10MHz clock (2 transitions per clock phase). In transition mode the X register holds system ticks between transitions. In this case the timing will be 1/20_000_000 second (clkfreq is ticks in 1 second).

    I ran this as a test:

      pinstart(0, P_OE | P_TRANSITION, (clkfreq / 20_000_000), 0) 
      wypin(0, 50) 
    

    As you can see in this image, 50 transitions created a pulse train of 25 pulses at 10MHz

    When I uses smart pins to create a clock, I use pulse mode, but it requires a little extra setup because you're setting the period and low time separately. This is a clock setup blurb from a P2 SPI project

      m := P_PULSE | P_OE                                           ' pulses for spi clock
      if (spimode.[0])                                              ' CPHS == 1?
        m |=  P_INVERT_OUTPUT
      x.word[0] := 2 #> (clkfreq / (khz*1000)) <# $FFFF             ' ticks in period
      x.word[1] := x.word[0] >> 1                                   ' ticks in low cycle (50%)
      pinstart(sck, m, x, 0)                                        ' configure smart pin
    

    I'm not suggesting you change Chris's code -- just letting you know there are other smart pin modes that can be helpful.

  • Thank you very much @JonnyMac, that is the clearest description I have seen anywhere for smart pins (for transition mode anyway) and I have been looking for a while.
    I worked out for myself that it was "transition mode" after manually doing this bit Bitwise OR Using the information in "Smart Pins rev 5.docx" at
    https://drive.google.com/file/d/1iTA4dwbntgaUVnpt0-9pDcFCVSsvCUnU/view

    P_OE | P_TRANSITION
    
    %0000_0000_000_0000000000000_01_00000_0     P_OE        Enable output in smart pin mode, regardless of DIR
    %0000_0000_000_0000000000000_00_00101_0     P_TRANSITION    Transition output
    ==3=8=7====3===2===========8=7==5=====0==   <bit count>
    %AAAA_BBBB_FFF_PPPPPPPPPPPPP_TT_MMMMM_0 <6 sections>
    %0000_0000_000_0000000000000_01_00101_0     |       Bitwise OR of the above 2 lines
    
    MMMMM Smart Pin Mode (5 bits)
    00101* = transition output
    

    So I had a good try, but had no real understanding of what that meant, other than it was fairly obviously generating the SPI clock.
    I was stumped reading the "Smart Pins rev 5.docx" on-line as the images overlay the text so i couldn't read the words.

    I just tried downloading "Smart Pins rev 5.docx" and it reads OK locally in Word.
    Thanks again for your assistance, very helpfull as always.

  • JonnyMacJonnyMac Posts: 9,156

    Glad I could help. An important detail in that information from Jon Titus is that the timing between pulses is limited to 16 bits.

  • Hi All,
    I am not sure many here can help anyone familiar with Ethernet might be able to see where I am going wrong as i am guessing few would have access to both a P2 board and a W5500 module?
    I have been struggling a bit since I haven't used a P2 or TCP/IP before and all the Demo code I can find seems to be for HTML which I am not using.

    I am using Chris Gadds 's W5500 driver to simulate 2 serial to ethernet ports to 2 x Tera-term (TT) TCP/IP Terminal Programs for now.
    This program is just as a test of concept to get things working before moving on to more complex things, but even this has me stumped.

    It took me a while and lots of reading but I did get these 2 x TCP server ports working (with static data for now) but for some reason Port 7351(Socket1) data stops if I close the TT terminal for Port 7350(Socket0) and I have been unable to find anything in the code to explain this, to my eye (half blind admittedly), the two sockets should be able to operate independently, so that closing one shouldn't affect the other, but in my program it does?

    My problem is I don't know what to check or if there is an obvious reason for this, my guess is I have configured something wrong setting up the two TCP ports but they work if I open the TT terminals in order Port 7350(Socket0) then Port 7351(Socket1), or if I re-open Port 7350(Socket0) then Port 7351(Socket1) will once again start receiving data (it also receives garbage at this point which is probably a hint if I were smart enough to recognize it as such).

    I know this forum is full of better programmers than me so i am hoping there is something here that is obvious to someone out there.

    Thanks all

    '' =================================================================================================
    ''
    ''   File....... Wiz550io Test B1.spin2
    ''   Purpose.... Serial to Ethernet PCB
    ''   Author..... GGW
    ''
    '' < Simplified, all excess code removed>
    '' =================================================================================================
    {
     W5500 Ethernet settings
            Gateway:    192.168.1.254
            SubnetMask: 255.255.255.0
            MAC:        00.08.DC.16.F8.01
            IP:         192.168.1.10
            SOCK/Port:  <TCP> 00 / 7350
                        <UDP> 04 / 5000
    }
    {$P2}
    
    CON { timing }
      _xinfreq = 25_000_000                '| 25Mhz osc.     ' Use X5500 25Mhz oscillator frequency as the common clock
      CLK_FREQ = 250_000_000               '| PCB            ' system freq as a constant
     '_xtlfreq = 20_000_000                '| 20M xtal       ' crystal oscillator frequency as a constant
     'CLK_FREQ = 200_000_000               '| P2 Edge PCB    ' system freq as a constant
    
      _clkfreq = CLK_FREQ                                    ' set system clock
    
      MS_001   = CLK_FREQ / 1_000                            ' ticks in 1ms
      US_001   = CLK_FREQ / 1_000_000                        ' ticks in 1us
    
    
    con { terminal }
    
      BR_TERM  = 115_200                                            ' terminal baud rate
    
    
    CON { P2 Edge+W5500 module   }
      WIZ_RST      = 16  { I } ' [/RST] Reset (active low)
      WIZ_INT      = 17  { I } ' [/INT] Interupt (active low)
      WIZ_MOSI     = 18  { B } ' [MOSI] SPI master out serial in to slave
      WIZ_MISO     = 19  { B } ' [MISO] SPI master in serial out from slave
      WIZ_SCK      = 20  { O } ' [SCLK] SPI clock from master to all slaves
      WIZ_SCS      = 21  { O } ' [/SCS] SPI chip select (active low)
    
    CON { Misc}
      Buzz         = 29  { O } ' Buzzer/speaker perhaps use P2 DAC mode?
    
      SCL          = 48  { O } ' [i2c SCL] I2C clock
      SDA          = 49  { B } ' [i2c SDA] I2C data
    
    CON {  alive leds }
      LED_GN       = 56  { O } ' [Led1] Edge LEDs < Green >
      LED_RD       = 57  { O } ' [Led2] Eval +    < Red >
    
    CON { P2 Serial / Flash/ SDcard io pins }
      SF_MISO      = 58  { I } ' flash storage
      SF_MOSI      = 59  { O }
      SF_SCLK      = 60  { O }
      SF_CS        = 61  { O }
    
      SD_MISO      = 58  { I } ' <NA> usd card storage
      SD_MOSI      = 59  { O } '
      SD_CS        = 60  { O } ' not used
      SD_SCLK      = 61  { O } '
    
      PGM_TX       = 62  { O } ' programming / debug
      PGM_RX       = 63  { I }
    
    
    CON
    
      #true,  ON, OFF
      #false, NO, YES
    
    
    OBJ
    
    ' main                                                          ' * master Spin cog
      wiz  : "Wiz550io driver"      'Uses Obex ID : 4746 WizNet 5500io Driver (2024-04-26 20:40:16) by Chris Gadd
      term : "jm_fullduplexserial"  ' * serial IO for terminal Thanks JonnyMac
    
    ' * uses cog when loaded
    
    pub main(): result | dipr, port, size
    
      setup()
      term.tx(term.CLS)           'clear terminal <Spin Tools IDE Only>
      waitms(100)
    
      term.str(string("Ethernet Serial Board is online!", 13, 10))
    
      waitms(200)
      '======== End of common code all above GGW <same> ==============
    
      'Configure SPI setting for W5500 network
      wiz.init(WIZ_SCS,WIZ_SCK,WIZ_MOSI,WIZ_MISO,WIZ_RST)  ' Initialize the SPI bus for the Wiznet chip.
      wiz.reset()                                          ' Hardware Reset W5500 IC <toggle the pin!>
      waitms(1000)
      'Set W5500 network default IP/MAC etc.
      wiz.writeIPAddress(@local_IP)                        'Store (WE) IP Address
      wiz.writeSubnetMask(@subnet)                         'Store (WE) Subnet Mask
      wiz.writeGatewayAddress(@gateway)                    'Store (TS) Gateway Address
      wiz.writeMACaddress(@mac_addr)
    
      'By default all 8 ports are allocated 2K of the available 16K (MAX) for TX & 16K (MAX) for RX.
      'wiz.writeSocket(0,wiz._Sn_TXBUF_SIZE,8)              'Enable Socket Tx Buffers for Ethernet Port 0) <8K ggw>
    
      waitms(1000)
    
      term.fstr0(@"Wiz W5500 initialized!\r\r")
      waitms(10)
    
    
      repeat
        SendTCPSock(0)  'works ok but if closed (1) also stops receiving data till (0) is restarted
        waitms(100)
        SendTCPSock(1)  'works ok but if (0) is closed (1) also stops receiving data till (0) is restarted
                        'the starting order above isn't relevant
        waitms(1000)
    
    pri SendTCPSock(_socket)
    ''Send String via TCP to the socket specified
    '' TCP Port# is (local_port+ socket#) where Socket# is 0-1 so Ports<7350 - 7351>
    
      term.fstr3(string("Status of Socket < %d >, Port < %d > %s \r"), _socket, local_port+_socket, wiz.statusString(_socket))
      waitms(10)
    
      case wiz.socketStatus(_socket)                        ' check the socket<n> status
        wiz._SOCK_CLOSED:                                   ' <$00> so socket closed? then open it
          wiz.socketOpen(_socket,local_port+_socket)        ' open the local TCPip port+_socket <7350 - 7351>
          waitms(10)
        wiz._SOCK_CLOSE_WAIT:                               ' <$00> so socket closed? then open it
          wiz.socketOpen(_socket,local_port+_socket)        ' ' open the local TCPip port+_socket <7350 - 7351>
          waitms(10)
        wiz._SOCK_INIT:                                     ' <$13> so opened with TCP mode
          wiz.socketTCPlisten(_socket)                      ' Open socket<n> to listen as a TCP/IP server.
          waitms(10)
        wiz._SOCK_ESTAB:
          wiz.resetBuffer(_socket)
          ' <Do RX Code here for this socket?>
          waitms(10)
          loadSockString(_socket, @@TCPmsg[_socket])
          waitms(10)
          wiz.sendBuffer(_socket)
          waitms(10)
    
    
    PRI loadSockString(_socket, p_str)
    ''Loads string pointer into Socket buffer
      wiz.loadBuffer(_socket,p_str,strsize(p_str))
    
    
    con {Smart Pin config}
    
      SP_PWM = %0000_0000_000_0000000000000_01_01001_0              ' smart pin pwm (true)
      OP_INV = %0000_0000_000_0000001000000_00_00000_0              ' output pin invert
    
    pub PWMpin(pin, freq) | x
    
    ''Setup PWM Pin & Frequency for alive leds / Speaker
    
      x := 255 << 16                     ' set pwm period to 255 units
      x |= 1 #> ((clkfreq / 255) / freq) <# $FFFF ' set timing of 1 pwm unit
    
      pinstart(pin, SP_PWM, x, 0)
    
    pub PWMpinLevel(pin, level)
    
    '' Set PWM level on pin in the Range of  0..255
      wypin(pin, 0 #> level <# 255)                  ' pwm on pin
    
    
    con {Std template objects}
    
    pub setup()
    
    '' Configure IO and objects for application
    
      term.tstart(BR_TERM)                                          ' start terminal io
      term.rxflush()
      term.txflush()
    
    
    DAT   '' LAN settings
      local_IP      byte      192,168,1,10                          '192,168,1,102         'ggw was 192,168,1,200
      gateway       byte      192,168,1,254                         '192,168,1,254         'ggw was 169,254,103,137
      subnet        byte      255,255,255,0
      mac_addr      byte      $00, $08, $DC, $16, $F8, $01          ' MAC is 6 bytes  <$00, $08 is Wiznet>
                                                                    ' Address: Wiznet_16:f8:01 (00:08:dc:16:f8:01)
      'ALIGNL        '<cog symbols must be long-aligned, also prevents compile error>
      local_port    word      7350
    
      'ALIGNL
      TCPmsg0       byte  "Socket 0 , Port 7350 ",$0D,$0A,$00
      TCPmsg1       byte  "Socket 1 , Port 7351 ",$0D,$0A,$00
    
     ' Set up a pointer variable to access the above via addressed strings
      TCPmsg        word @TCPmsg0, @TCPmsg1
    {{
    
      Terms of Use: MIT License
    
      Permission is hereby granted, free of charge, to any person obtaining a copy of this
      software and associated documentation files (the "Software"), to deal in the Software
      without restriction, including without limitation the rights to use, copy, modify,
      merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
      permit persons to whom the Software is furnished to do so, subject to the following
      conditions:
    
      The above copyright notice and this permission notice shall be included in all copies
      or substantial portions of the Software.
    
      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
      INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
      PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
      CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
      OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    }}
    
  • ke4pjwke4pjw Posts: 1,169
    edited 2024-05-31 16:54

    Just a quick glance:

    Why is it local_port + _socket? Should just be local_port I would think. Socket is the virtual socket within the Wiznet. local_port is the actual port used by TCP/IP, right?

    Nevermind, I think I see what you are doing there.

  • ke4pjwke4pjw Posts: 1,169

    Change
    local_port word 7350
    to
    local_port long 7350

    and see what that does.

  • ke4pjwke4pjw Posts: 1,169

    Also, I would make TCPmsg longs.

  • Thanks @ke4pjw, your hints are appreciated.
    I hope you don't think I have been ignoring your suggestions, since i am in the UK that message was sent at the end of day on a Friday, I am not sure where you are located but I would guess the USA and made those comment near the start of your Friday. I am back at work now on the following Monday.

    @ke4pjw said:
    Change
    local_port word 7350
    to
    local_port long 7350

    and see what that does.

    I see no difference there, 7350 will fit into a WORD or a LONG

    @ke4pjw said:
    Also, I would make TCPmsg longs.

    I have also tried changing this pointer to a LONG but again no difference.
    I have left both as longs for now but the programs operation is still the same.

    I need to start looking at the packets I am sending (wireshark??) and work out exactly what is changed on port 7351 after 7350 is shut down, and then work out why.

    For future programmers, below is what I am seeing on my debug terminal with comments <> after significant lines the ... just means the same thing keeps happening on the same lines below till noted.

    Status of Socket < 0 >, Port < 7350 > _SOCK_ESTAB   <7350 now established and sending data to Teraterm7350>...
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB   <7351 now established and sending data to Teraterm7350>...
    Status of Socket < 0 >, Port < 7350 > _SOCK_ESTAB
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB
    Status of Socket < 0 >, Port < 7350 > _SOCK_ESTAB
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB
    Status of Socket < 0 >, Port < 7350 > _SOCK_CLOSE_WAIT  <Disconnected Teraterm7350 session here>
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB   <7351 is still connected, but data flow to Teraterm7351 has stopped>
    Status of Socket < 0 >, Port < 7350 > _SOCK_INIT        <7350 now re-initialised here>
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB   <7351 is still connected, but data flow to Teraterm7351 still stopped>...
    Status of Socket < 0 >, Port < 7350 > _SOCK_LISTEN  <7350 now Listening for connection as a server>...
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB
    Status of Socket < 0 >, Port < 7350 > _SOCK_LISTEN
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB
    Status of Socket < 0 >, Port < 7350 > _SOCK_LISTEN
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB
    Status of Socket < 0 >, Port < 7350 > _SOCK_LISTEN
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB
    Status of Socket < 0 >, Port < 7350 > _SOCK_LISTEN
    Status of Socket < 0 >, Port < 7350 > _SOCK_ESTAB   <7350 now established and sending data to <Teraterm7350>
    Status of Socket < 1 >, Port < 7351 > _SOCK_ESTAB   <7351 is still connected, and data flow resumed to Teraterm7351>
    
    

    Again, thanks for your input, I work in isolation on this so this forum often points out things others see as obvious and I value the different perspectives given.

  • I found a bug in the sendBuffer method:

    PUB sendBuffer(_socket) | buf_size
      writeSocket(_socket,_Sn_TX_WR,_wr_ptr)            ' Should be _wr_ptr[_socket]
      writeSocket(_socket,_Sn_CR,_SEND)
      buf_size := readSocket(_socket,_Sn_TXBUF_SIZE) * 1024
      repeat
        resetBuffer(_socket)
      until _fsr[_socket] == buf_size
    

    I only ever used socket 0 while playing with the webserver demo so I never encountered that bug, corrected it and now the demo works on all sockets.

  • Thank you @ChrisGadd, I was looking into why socket 0 was significant but it would have taken me some time to get to that correction.
    My Program (as detailed above), is now working as expected with that small but vital change.
    <For any future searchers, my code above sets up 2 TCP/IP ports and sends different strings to each (will be replaced with real serial data soon).
    Either port can be opened or closed independently as needed to receive the data from that source, I can see no reason why this can't be expanded to the full 8 sockets supported by the W5500 chip.
    For testing I am using 2 separate instances of the excellent TeraTerm program on Ports 7350 & 7351 (random un-allocated TCP port numbers) as shown below. From past experience these TeraTerm settings work with any serial over Ethernet data and that is what I want my board to emulate. Ultimately, I would like to convert the code and serial Rx routines to machine code to reduce serial latency but that is really out of my comfort zone at this point in time..>

    Can I request that someone update the driver on OBEX4746?
    Is there a process to offically correct / update the OBEX? Is this up to the Authors or Parallax?
    A slight name change could also make this more findable too, as I couldn't find it till Chris pointed me too it, see top posts above.
    The other Wiznet drivers all have the chip number as part of the title, I could have / should have searched for WIZNET but didn't so the only W5500 driver I could find was for the P1.

    I realise Chris wrote this for a specific Wiznet Ethernet board, but I don't use that board, mine was a generic chinese W5500 board.
    A (W5500) somewhere would have made it much more searchable, something like Title: "WizNet (W5500) 5500io Driver"?

    Thank you Chris for a great driver and the support.

  • ChrisGaddChrisGadd Posts: 310
    edited 2024-06-04 11:43

    I'm glad that worked. I'll update the obex title and files.

  • ke4pjwke4pjw Posts: 1,169

    @lab_ges No worries. My concern was more of about alignment, as it appears A word (local_port) was being added to a long (_socket). I have seen goofy stuff happen when doing that. I am happy @ChrisGadd was able to spot the bug and get it fixed!

    --Terry

  • @ke4pjw said:
    @lab_ges No worries. My concern was more of about alignment, as it appears A word (local_port) was being added to a long (_socket). I have seen goofy stuff happen when doing that. I am happy @ChrisGadd was able to spot the bug and get it fixed!

    --Terry

    Thanks for that comment Terry.
    I had missed that point completely, I was thinking purely on the lines of a container size, i.e. will it fit rather than how it relates to the item that is being added to it.
    I need to pay more attention as sometimes these things can turn arround and bite you. :#
    It is a long now and I will leave it like that!

  • RaymanRayman Posts: 14,744

    As a side note... There appears to be a W5500 driver built into micropython. Going to be testing that soon, hopefully,...

  • I got it mostly converted to pasm for ya, but I don't see any significant difference with your test program regarding latency. Didn't really expect to; all of the time-critical stuff was already in in-line assembly.
    It's considerably slower with my web-page demo at the moment, but that's due to the way I'm sending packets.
    The Spin-based driver allows for an entire message to be constructed in the buffer which is then sent in one block, as opposed to the (current) PASM version that sends data as soon as loaded into the buffer, resulting in many short packets. That's also the reason for each socket having its own wr_ptr and fsr registers.
    Unfortunately, the W5500 Sn_WR_PTR and Sn_FSR registers are only updated following a SEND command; the value written into Sn_WR_PTR cannot be read back out, and so cannot be used to keep track of position inside the buffers.
    I'll see about adding that capability into the PASM object after I get back from a long weekend.

  • @ChrisGadd said:
    I got it mostly converted to pasm for ya, but I don't see any significant difference with your test program regarding latency. Didn't really expect to; all of the time-critical stuff was already in in-line assembly.
    It's considerably slower with my web-page demo at the moment, but that's due to the way I'm sending packets.
    The Spin-based driver allows for an entire message to be constructed in the buffer which is then sent in one block, as opposed to the (current) PASM version that sends data as soon as loaded into the buffer, resulting in many short packets. That's also the reason for each socket having its own wr_ptr and fsr registers.
    Unfortunately, the W5500 Sn_WR_PTR and Sn_FSR registers are only updated following a SEND command; the value written into Sn_WR_PTR cannot be read back out, and so cannot be used to keep track of position inside the buffers.
    I'll see about adding that capability into the PASM object after I get back from a long weekend.

    Hi Chris, I hope you had a good long Weekend.
    I just had a 4 day long weekend myself, and went for a quick visit to Hadrian’s Wall. I love the Roman ruins along the wall, it is a very special place.

    Thanks for the continued code development, it is much appreciated by me and I am sure by others here.
    Nothing I said above was meant as a criticism of your driver, which, as you say, already buffers the inputs before it is sent.
    My concerns about latency were really related to my code writing ability rather than yours, since in my example code I am just sending constant known string values, which is relatively easy.
    I need to add code that will read several serial ports (up to 8) and send them to Ethernet via your driver, all hopefully while not adding too much latency to the incoming serial data, but that is still a work in progress.

  • PS Chris, Don't let me stop you from adding the above changes to the PASM version.
    That could be handy to a lot of peope.
    If you do finish it, I will happily use it and help you test it.

  • I have been working on this in the background with Chris Gadd and now wish to conclude this discussion with the working code, see attached ZIP file.

    W5500 8 TCPserial port demo.spin2
    
    Hardware: P2 Edge Board and W5500 Ethernet module & a source of 8 serial ports.
    The received Serial strings need to be terminated with <cr><lf> by default to work with this code.
    The serial inputs should be digital for connecting directly to the P2 Edge, though RS232 drivers could be used.
    
    Sends Data received by each connected Serial Port to the fixed, associated TCP socket.
    RS232       TCP Socket
      0              7350
      1              7351
      2              7352
      3              7353
      4              7354
      5              7355
      6              7356
      7              7357
    
    For testing you can receive the TCP data using Tera Term on a PC on the same network as the W5500.
    HOST: <local_IP>
    TCP port#: <7350> to <7357>
    Service: Other
    

    My thanks goes to @ChrisGadd for his help with this code and specifically his wonderful W5500 driver, he has worked tirelessly on this and has now updated his driver on the OBEX [OB#4746].

    My thanks also to @"Stephen Moraco" for his "isp_octoport_serial" [OB#4257] that is used here to handle the 8 serial ports. Chris did notice a slight issue with using the Octoport Driver:-

    The octoport object does have a method for copying completed strings (terminated with $0A) out of the circular buffer into a user-defined buffer. It was glitching out whenever the serial transmitters were stopped and restarted, evidently the serial object can return zero-length strings which was causing my W5500 object to try to load four billion bytes into the W5500 chip.

    So he made a change to compensate for that:-

    I added a simple check for message length and haven't been able to break it again. If your messages don't end with a line-feed ($0A), you can change that in the nextRxString method, where it checks if nChar == $0a.

    Thanks too to @JonnyMac for his "jm_fullduplexserial" [OB#2842] and lots of additional help to me and other community members.

    Thanks everyone, I hope this might be of assistance to someone else in the future.

Sign In or Register to comment.