Hi,
I now have a working DHCP client. This means I can just plug in the network cable and the thing gets an IP-adress from the DHCP server (my router in this case). It also passes a host name to the DHCP-server which then somehow passes that on to the DNS server that apparently runs on the router. In the end it means that I can now get to it by browsing to http://amicus or whatever name I wish the unit to have - good times :-)
But, this has lead me to the unavoidable...
The routines previously posted are more or less hardcoded to use socket 0. This is of course not optimal and now is the time to do something about that. Each socket has its own control and status registers etc at a fixed offset of $100 between them so it's pretty easy to calculate the correct adress based on the socket we want the routine to access. For example:
Code:
WizSocket VAR BYTE
WizSocket = 2
WizAdress = W5100_S0_MR + (WizSocket * $100) : WizData = 1 : GOSUB Write_W5100
This will access socket 2's mode register - pretty straight forward.
The problem comes with the resizable circular receive and transmitt buffers. The only fixed point here is the start of socket 0's RX and TX buffer. The end of it as well as the start AND end of the other sockets buffers can move around based on how we set it up. I'm looking for ideas on how to handle this effeciently and user friendly.
Currently I've done this:
Code:
GetSocketRXAdress:
' Complete routine executes in 174 cycles.
WizAdressOffset = WizSocket * $100
' These 3 lookup statements takes 259 bytes of program memory
Lookup2 WizSocket, [W5100_S0_RX_Start, W5100_S1_RX_Start, W5100_S2_RX_Start, W5100_S3_RX_Start], Socket_RX_Start
Lookup2 WizSocket, [W5100_S0_RX_END, W5100_S1_RX_END, W5100_S1_RX_END, W5100_S1_RX_END], Socket_RX_End
Lookup2 WizSocket, [W5100_S0_RX_MASK, W5100_S1_RX_MASK, W5100_S2_RX_MASK, W5100_S3_RX_MASK], Socket_RX_MASK
RETURN
And of course a similar routine for the TX buffers. Instead of using W5100_S0_RX_Start etc the routines that accesses the RX buffer now uses Socket_RX_Start etc instead.
These routines are then called when "changing sockets" meaning that we don't have to calculate the adresses every time we access a register we only do it when changing sockets. The routine to check the amount of free space in any sockets TX buffer then looks like this:
Code:
GetFreeTXSize:
If WizSocket <> WizOldSocket THEN ' No need to get offsets etc if we're using the same socket as last time.
GOSUB GetSocketTXAdress
ENDIF
' Get the total amount of free memory in the sockets transmit buffer.
WizAdress = W5100_S0_TX_FSR0 + WizAdressOffset : GOSUB Read_W5100 : WizSize.HighByte = WizData
WizAdress = W5100_S0_TX_FSR1 + WizAdressOffset : GOSUB Read_W5100 : WizSize.LowByte = WizData
' Get the pointer adress of where to put new data.
WizAdress = W5100_S0_TX_WR0 + WizAdressOffset : GOSUB Read_W5100 : WizPtr.HighByte = WizData
WizAdress = W5100_S0_TX_WR1 + WizAdressOffset : GOSUB Read_W5100 : WizPtr.LowByte = WizData
'Calculate physical adress of first byte
WizStart = Socket_TX_START + (WizPtr & Socket_TX_MASK)
WizOldSocket = WizSocket ' Remember which socket we used.
RETURN
I think this is a workable solution to allowing access to any socket without duplicating all the routines with hardcoded adresses AND without having to calculate/retreive the adresses every time we access the W5100.
What I'm looking for is ideas on how to make it more efficient, I particullarly dislike the fact that the lookup routines (for both TX and RX buffers) takes well over 500 bytes (that's something like 10% of a my complete working web-server including a couple of hundred bytes HTML). Me think there must be a slicker way...
Thank you in advance!
/Henrik.
Bookmarks