Can't get MAC, Gateway, Mask, or IP to set
I received my Spinneret today and have been trying to get it to, for lack of a better term, "Hello, World" and can't seem to get that far.
I'm trying to use the UDP echo code that is available in OBEX, but had to edit it because "Brilldea_W5100_SPI_Driver_Ver005.spin" is not the name of the associated .spin file, and I changed it to "W5100_SPI_Driver.spin", the file that is available on the same page of OBEX. I don't believe that is a problem, but wanted to mention it in case it is.
I changed the MAC, IP, Gateway, and Subnet Mask to settings for my network (and used the MAC that is on the sticker on the bottom of the Spinneret). When I run it, I get this in the serial terminal:
So, I guess it isn't writing the values to the W5100 in the first place? Where to begin?
Benj
I'm trying to use the UDP echo code that is available in OBEX, but had to edit it because "Brilldea_W5100_SPI_Driver_Ver005.spin" is not the name of the associated .spin file, and I changed it to "W5100_SPI_Driver.spin", the file that is available on the same page of OBEX. I don't believe that is a problem, but wanted to mention it in case it is.
I changed the MAC, IP, Gateway, and Subnet Mask to settings for my network (and used the MAC that is on the sticker on the bottom of the Spinneret). When I run it, I get this in the serial terminal:
W5100 SPI Driver Test Initialize all addresses... Set MAC ID........00:08:DC:16:F0:B3 Verified MAC ID...00:00:00:00:00:00 Set Gateway.....192.168.64.1 Verified Gateway..0.0.0.0 Set Subnet......255.255.255.0 Verified Subnet...0.0.0.0 Set IP..........192.168.64.129 Verified IP.......0.0.0.0 Initialize socket 0, port 5000 Socket 0 Status Register: 00 - socket closed Attempting to open UDP on socket 0, port 5000... Socket 0 Status Register: 00 - socket closed UDP opening failed, program ending
So, I guess it isn't writing the values to the W5100 in the first place? Where to begin?
Benj

Comments
CON 'Constants to be located here '*************************************** '*************************************** ' Firmware Version '*************************************** FWmajor = 0 FWminor = 4 DAT TxtFWdate byte "June 13, 2010",0 CON '*************************************** ' Processor Settings '*************************************** _clkmode = xtal1 + pll16x 'Use the PLL to multiple the external clock by 16 _xinfreq = 5_000_000 'An external clock of 5MHz. is used (80MHz. operation) '*************************************** ' System Definitions '*************************************** _OUTPUT = 1 'Sets pin to output in DIRA register _INPUT = 0 'Sets pin to input in DIRA register _HIGH = 1 'High=ON=1=3.3V DC _ON = 1 _LOW = 0 'Low=OFF=0=0V DC _OFF = 0 _ENABLE = 1 'Enable (turn on) function/mode _DISABLE = 0 'Disable (turn off) function/mode '*************************************** ' I/O Definitions of PropNET Module '*************************************** '~~~~Propeller Based I/O~~~~ 'W5100 Module Interface _WIZ_data0 = 0 'SPI Mode = MISO, Indirect Mode = data bit 0. _WIZ_miso = 0 _WIZ_data1 = 1 'SPI Mode = MOSI, Indirect Mode = data bit 1. _WIZ_mosi = 1 _WIZ_data2 = 2 'SPI Mode unused, Indirect Mode = data bit 2 dependent on solder jumper on board. _WIZ_data3 = 3 'SPI Mode = SCLK, Indirect Mode = data bit 3. _WIZ_sclk = 3 _WIZ_data4 = 4 'SPI Mode unused, Indirect Mode = data bit 4 dependent on solder jumper on board. _WIZ_data5 = 5 'SPI Mode unused, Indirect Mode = data bit 5 dependent on solder jumper on board. _WIZ_data6 = 6 'SPI Mode unused, Indirect Mode = data bit 6 dependent on solder jumper on board. _WIZ_data7 = 7 'SPI Mode unused, Indirect Mode = data bit 7 dependent on solder jumper on board. _WIZ_addr0 = 8 'SPI Mode unused, Indirect Mode = address bit 0 dependent on solder jumper on board. _WIZ_addr1 = 9 'SPI Mode unused, Indirect Mode = address bit 1 dependent on solder jumper on board. _WIZ_wr = 10 'SPI Mode unused, Indirect Mode = /write dependent on solder jumper on board. _WIZ_rd = 11 'SPI Mode unused, Indirect Mode = /read dependent on solder jumper on board. _WIZ_cs = 12 'SPI Mode unused, Indirect Mode = /chip select dependent on solder jumper on board. _WIZ_int = 13 'W5100 /interrupt dependent on solder jumper on board. Shared with _OW. _WIZ_rst = 14 'W5100 chip reset. _WIZ_scs = 15 'SPI Mode SPI Slave Select, Indirect Mode unused dependent on solder jumper on board. 'I2C Interface _I2C_scl = 28 'Output for the I2C serial clock _I2C_sda = 29 'Input/output for the I2C serial data 'Serial/Programming Interface (via Prop Plug Header) _SERIAL_tx = 30 'Output for sending misc. serial communications via a Prop Plug _SERIAL_rx = 31 'Input for receiving misc. serial communications via a Prop Plug '*************************************** ' I2C Definitions '*************************************** _EEPROM0_address = $A0 'Slave address of EEPROM '*************************************** ' Debugging Definitions '*************************************** '*************************************** ' Misc Definitions '*************************************** _bytebuffersize = 2000 '************************************** VAR 'Variables to be located here '*************************************** 'Configuration variables for the W5100 byte MAC[6] '6 element array contianing MAC or source hardware address ex. "02:00:00:01:23:45" byte Gateway[4] '4 element array containing gateway address ex. "192.168.0.1" byte Subnet[4] '4 element array contianing subnet mask ex. "255.255.255.0" byte IP[4] '4 element array containing IP address ex. "192.168.0.13" 'verify variables for the W5100 byte vMAC[6] '6 element array contianing MAC or source hardware address ex. "02:00:00:01:23:45" byte vGateway[4] '4 element array containing gateway address ex. "192.168.0.1" byte vSubnet[4] '4 element array contianing subnet mask ex. "255.255.255.0" byte vIP[4] '4 element array containing IP address ex. "192.168.0.13" long socket '1 element for the socket number 'Variables to info for where to return the data to byte destIP[4] '4 element array containing IP address ex. "192.168.0.16" 'Misc variables byte data[_bytebuffersize] long stack[50] '*************************************** OBJ 'Object declaration to be located here '*************************************** 'Choose which driver to use by commenting/uncommenting the driver. Only one can be chosen. ETHERNET : "W5100_SPI_Driver.spin" 'The serial terminal to use PST : "Parallax Serial Terminal.spin" 'A terminal object created by Parallax, used for debugging '*************************************** PUB main | temp0, temp1, temp2 '*************************************** '' First routine to be executed in the program '' because it is first PUB in the file PauseMSec(2_000) 'A small delay to allow time to switch to the terminal application after loading the device '************************************** ' Start the processes in their cogs '************************************** 'Start the terminal application 'The terminal operates at 115,200 BAUD on the USB/COM Port the Prop Plug is attached to PST.Start(115_200) 'Start the W5100 driver ETHERNET.StartSPI(_WIZ_scs, _WIZ_sclk, _WIZ_mosi, _WIZ_miso, _WIZ_rst) '************************************** ' Initialize the variables '************************************** 'The following variables can be adjusted by the demo user to fit in their particular network application. 'Note the MAC ID is a locally administered address. See Wikipedia MAC_Address 'MAC ID to be assigned to W5100 MAC[0] := $00 MAC[1] := $08 MAC[2] := $DC MAC[3] := $16 MAC[4] := $F0 MAC[5] := $B3 'Subnet address to be assigned to W5100 Subnet[0] := 255 Subnet[1] := 255 Subnet[2] := 255 Subnet[3] := 0 'IP address to be assigned to W5100 IP[0] := 192 IP[1] := 168 IP[2] := 64 IP[3] := 129 'Gateway address of the system network Gateway[0] := 192 Gateway[1] := 168 Gateway[2] := 64 Gateway[3] := 1 'Destination IP address - can be left zeros, the UDP echo echos to computer that sent packet destIP[0] := 0 destIP[1] := 0 destIP[2] := 0 destIP[3] := 0 socket := 5000 '************************************** ' Begin '************************************** 'Clear the terminal screen PST.Home PST.Clear 'Draw the title bar PST.Str(string(" W5100 SPI Driver Test ", PST#NL, PST#NL)) 'Reset W5100 to prepare to applying settings to W5100 ETHERNET.ResetHardware(true) 'Set the W5100 addresses PST.Str(string("Initialize all addresses... ", PST#NL)) SetVerifyMAC(@MAC[0]) SetVerifyGateway(@Gateway[0]) SetVerifySubnet(@Subnet[0]) SetVerifyIP(@IP[0]) 'Addresses should now be set and displayed in the terminal window. 'Next initialize Socket 0 for being the echo PST.Str(string("Initialize socket 0, port ")) PST.dec(socket) PST.Str(string(PST#NL)) 'Testing Socket 0's status register and display information PST.Str(string("Socket 0 Status Register: ")) ETHERNET.readSPI(ETHERNET#_S0_SR, @temp0, 1) case temp0 ETHERNET#_SOCK_CLOSED : PST.Str(string("00 - socket closed", PST#NL, PST#NL)) ETHERNET#_SOCK_UDP : PST.Str(string("22 - socket UDP open", PST#NL, PST#NL)) 'Try opening a socket using a ASM method PST.Str(string("Attempting to open UDP on socket 0, port ")) PST.dec(socket) PST.Str(string("...", PST#NL)) ETHERNET.SocketOpen(0, ETHERNET#_UDPPROTO, socket, socket, @destIP[0]) 'Wait a moment for the socket to get established PauseMSec(500) 'Testing Socket 0's status register and display information PST.Str(string("Socket 0 Status Register: ")) ETHERNET.readSPI(ETHERNET#_S0_SR, @temp0, 1) case temp0 ETHERNET#_SOCK_CLOSED : PST.Str(string("00 - socket closed", PST#NL, PST#NL)) ETHERNET#_SOCK_UDP : PST.Str(string("22 - socket UDP open", PST#NL, PST#NL)) if temp0 == ETHERNET#_SOCK_UDP PST.Str(string("Configuration succesful", PST#NL)) PST.Str(string("Send UDP packet to IP/socket and it will be echoed", PST#NL, PST#NL)) 'Stay in this loop forever - receiving and echoing repeat bytefill(@data, 0, _bytebuffersize) PST.Str(string("Waiting to receive....")) repeat until ETHERNET.rxUDP(0, @data[0]) PST.Str(string("received and echoing....")) ETHERNET.txUDP(0, @data[0]) PST.Str(string("sent", PST#NL)) else PST.Str(string("UDP opening failed, program ending")) repeat return 'end of main '*************************************** PRI SetVerifyMAC(_firstOctet) '*************************************** 'Set the MAC ID and display it in the terminal ETHERNET.WriteMACaddress(true, _firstOctet) PST.Str(string(" Set MAC ID........")) PST.hex(byte[_firstOctet + 0], 2) PST.Str(string(":")) PST.hex(byte[_firstOctet + 1], 2) PST.Str(string(":")) PST.hex(byte[_firstOctet + 2], 2) PST.Str(string(":")) PST.hex(byte[_firstOctet + 3], 2) PST.Str(string(":")) PST.hex(byte[_firstOctet + 4], 2) PST.Str(string(":")) PST.hex(byte[_firstOctet + 5], 2) PST.Str(string(PST#NL)) 'Wait a moment PauseMSec(500) ETHERNET.ReadMACAddress(@vMAC[0]) PST.Str(string(" Verified MAC ID...")) PST.hex(vMAC[0], 2) PST.Str(string(":")) PST.hex(vMAC[1], 2) PST.Str(string(":")) PST.hex(vMAC[2], 2) PST.Str(string(":")) PST.hex(vMAC[3], 2) PST.Str(string(":")) PST.hex(vMAC[4], 2) PST.Str(string(":")) PST.hex(vMAC[5], 2) PST.Str(string(PST#NL)) PST.Str(string(PST#NL)) return 'end of SetVerifyMAC '*************************************** PRI SetVerifyGateway(_firstOctet) '*************************************** 'Set the Gatway address and display it in the terminal ETHERNET.WriteGatewayAddress(true, _firstOctet) PST.Str(string(" Set Gateway.....")) PST.dec(byte[_firstOctet + 0]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 1]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 2]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 3]) PST.Str(string(PST#NL)) 'Wait a moment PauseMSec(500) ETHERNET.ReadGatewayAddress(@vGATEWAY[0]) PST.Str(string(" Verified Gateway..")) PST.dec(vGATEWAY[0]) PST.Str(string(".")) PST.dec(vGATEWAY[1]) PST.Str(string(".")) PST.dec(vGATEWAY[2]) PST.Str(string(".")) PST.dec(vGATEWAY[3]) PST.Str(string(PST#NL)) PST.Str(string(PST#NL)) return 'end of SetVerifyGateway '*************************************** PRI SetVerifySubnet(_firstOctet) '*************************************** 'Set the Subnet address and display it in the terminal ETHERNET.WriteSubnetMask(true, _firstOctet) PST.Str(string(" Set Subnet......")) PST.dec(byte[_firstOctet + 0]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 1]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 2]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 3]) PST.Str(string(PST#NL)) 'Wait a moment PauseMSec(500) ETHERNET.ReadSubnetMask(@vSUBNET[0]) PST.Str(string(" Verified Subnet...")) PST.dec(vSUBNET[0]) PST.Str(string(".")) PST.dec(vSUBNET[1]) PST.Str(string(".")) PST.dec(vSUBNET[2]) PST.Str(string(".")) PST.dec(vSUBNET[3]) PST.Str(string(PST#NL)) PST.Str(string(PST#NL)) return 'end of SetVerifySubnet '*************************************** PRI SetVerifyIP(_firstOctet) '*************************************** 'Set the IP address and display it in the terminal ETHERNET.WriteIPAddress(true, _firstOctet) PST.Str(string(" Set IP..........")) PST.dec(byte[_firstOctet + 0]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 1]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 2]) PST.Str(string(".")) PST.dec(byte[_firstOctet + 3]) PST.Str(string(PST#NL)) 'Wait a moment PauseMSec(500) ETHERNET.ReadIPAddress(@vIP[0]) PST.Str(string(" Verified IP.......")) PST.dec(vIP[0]) PST.Str(string(".")) PST.dec(vIP[1]) PST.Str(string(".")) PST.dec(vIP[2]) PST.Str(string(".")) PST.dec(vIP[3]) PST.Str(string(PST#NL)) PST.Str(string(PST#NL)) return 'end of SetVerifyIP '*************************************** PRI PauseMSec(Duration) '*************************************** '' Pause execution for specified milliseconds. '' This routine is based on the set clock frequency. '' '' params: Duration = number of milliseconds to delay '' return: none waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt) return 'end of PauseMSecCON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 'W5100 Interface W5100_DATA0 = 0 W5100_DATA1 = 1 W5100_DATA2 = 2 W5100_DATA3 = 3 W5100_DATA4 = 4 W5100_DATA5 = 5 W5100_DATA6 = 6 W5100_DATA7 = 7 W5100_ADDR0 = 8 W5100_ADDR1 = 9 W5100_WR = 10 W5100_RD = 11 W5100_CS = 12 W5100_INT = 13 W5100_RST = 14 W5100_SEN = 15 ' UDP port numbers for DHCP DHCP_SERVER_PORT = 67 ' from server to client DHCP_CLIENT_PORT = 68 ' from client to server ' DHCP message OP code DHCP_BOOTREQUEST = 1 DHCP_BOOTREPLY = 2 ' DHCP message type DHCP_DISCOVER = 1 DHCP_OFFER = 2 DHCP_REQUEST = 3 DHCP_DECLINE = 4 DHCP_ACK = 5 DHCP_NAK = 6 DHCP_RELEASE = 7 DHCP_INFORM = 8 ' MISC DHCP stuff DHCP_TIMEOUT = 80_000_000 * 4 ' 4 seconds, assumes 80Mhz clkfreq DHCP_FLAGSBROADCAST = $8000 DHCP_HTYPE10MB = 1 DHCP_HLENETHERNET = 6 MAGIC_COOKIE_0 = $63 MAGIC_COOKIE_1 = $82 MAGIC_COOKIE_2 = $53 MAGIC_COOKIE_3 = $63 ' DHCP Options OPT_padOption = 0 OPT_subnetMask = 1 OPT_timerOffset = 2 OPT_routersOnSubnet = 3 OPT_timeServer = 4 OPT_nameServer = 5 OPT_dns = 6 OPT_logServer = 7 OPT_cookieServer = 8 OPT_lprServer = 9 OPT_impressServer = 10 OPT_resourceLocationServer = 11 OPT_hostName = 12 OPT_bootFileSize = 13 OPT_meritDumpFile = 14 OPT_domainName = 15 OPT_swapServer = 16 OPT_rootPath = 17 OPT_extentionsPath = 18 OPT_IPforwarding = 19 OPT_nonLocalSourceRouting = 20 OPT_policyFilter = 21 OPT_maxDgramReasmSize = 22 OPT_defaultIPTTL = 23 OPT_pathMTUagingTimeout = 24 OPT_pathMTUplateauTable = 25 OPT_ifMTU = 26 OPT_allSubnetsLocal = 27 OPT_broadcastAddr = 28 OPT_performMaskDiscovery = 29 OPT_maskSupplier = 30 OPT_performRouterDiscovery = 31 OPT_routerSolicitationAddr = 32 OPT_staticRoute = 33 OPT_trailerEncapsulation = 34 OPT_arpCacheTimeout = 35 OPT_ethernetEncapsulation = 36 OPT_tcpDefaultTTL = 37 OPT_tcpKeepaliveInterval = 38 OPT_tcpKeepaliveGarbage = 39 OPT_nisDomainName = 40 OPT_nisServers = 41 OPT_ntpServers = 42 OPT_vendorSpecificInfo = 43 OPT_netBIOSnameServer = 44 OPT_netBIOSdgramDistServer = 45 OPT_netBIOSnodeType = 46 OPT_netBIOSscope = 47 OPT_xFontServer = 48 OPT_xDisplayManager = 49 OPT_dhcpRequestedIPaddr = 50 OPT_dhcpIPaddrLeaseTime = 51 OPT_dhcpOptionOverload = 52 OPT_dhcpMessageType = 53 OPT_dhcpServerIdentifier = 54 OPT_dhcpParamRequest = 55 OPT_dhcpMsg = 56 OPT_dhcpMaxMsgSize = 57 OPT_dhcpT1value = 58 OPT_dhcpT2value = 59 OPT_dhcpClassIdentifier = 60 OPT_dhcpClientIdentifier = 61 OPT_endOption = 255 ' offsets for UDP header UDP_HEADER_DESTADDR = 0 UDP_HEADER_PORT = 4 UDP_HEADER_PAYLOADSIZE = 6 UDP_HEADER_SIZE = 8 ' offsets for DHCP packet (UDP header is in front of this) DHCP_OP = 8 DHCP_HTYPE = 9 DHCP_HLEN = 10 DHCP_HOPS = 11 DHCP_XID = 12 DHCP_SECS = 16 DHCP_FLAGS = 18 DHCP_CIADDR = 20 DHCP_YIADDR = 24 DHCP_SIADDR = 28 DHCP_GIADDR = 32 DHCP_CHADDR = 36 DHCP_SNAME = 52 DHCP_FILE = 116 DHCP_COOKIE = 244 DHCP_OPT = 248 DHCP_END = 556 ' return codes SUCCESS = 0 SOCKET_FAILED_OPENING = 1 SERVER_TIMEOUT = 2 SERVER_NAK = 3 BUFFER_SIZE = 2048 VAR byte MAC_Address[6] byte IP[4] byte SubnetMask[4] byte GatewayIP[4] byte vMAC[6] long DHCP_LeaseTime ' duration of lease in seconds byte DHCP_Server[4] byte DNS_Server[4] byte HostName[64] byte DomainName[64] ' you may need to make this larger if you have a very long domain name byte Buffer[BUFFER_SIZE] DAT DEFAULT_HOST_NAME BYTE "Spinneret", 0 OBJ W5100 : "W5100_Indirect_Driver.spin" 'W5100 : "W5100_SPI_Driver.spin" 'uncomment this block to test this DHCP object by itself PST : "Parallax Serial Terminal" PUB main PST.Start(115200) ' sets up W5100 and initializes our variables Start MAC_Address[0] := $00 MAC_Address[1] := $08 MAC_Address[2] := $DC MAC_Address[3] := $16 MAC_Address[4] := $F0 MAC_Address[5] := $B3 W5100.WriteMACaddress(true, @MAC_Address[0]) ' delay to allow time to enable PST PauseMSec(8000) W5100.ReadMACAddress(@vMAC[0]) PST.Str(string(" Verified MAC ID...")) PST.hex(vMAC[0], 2) PST.Str(string(":")) PST.hex(vMAC[1], 2) PST.Str(string(":")) PST.hex(vMAC[2], 2) PST.Str(string(":")) PST.hex(vMAC[3], 2) PST.Str(string(":")) PST.hex(vMAC[4], 2) PST.Str(string(":")) PST.hex(vMAC[5], 2) PST.Str(string(PST#NL)) PST.Str(string(PST#NL)) 'PST.Home 'PST.Clear PST.Str(string("DHCP Demo", PST#NL, PST#NL)) result := DoDHCP(0, $4242_4242) ' at this point if result == SUCCESS, then the W5100 is configured if result == SUCCESS PST.Str(string("IP : ")) PST.Dec(IP[0]) PST.Str(string(".")) PST.Dec(IP[1]) PST.Str(string(".")) PST.Dec(IP[2]) PST.Str(string(".")) PST.Dec(IP[3]) PST.Str(string(PST#NL)) PST.Str(string("Subnet Mask: ")) PST.Dec(SubnetMask[0]) PST.Str(string(".")) PST.Dec(SubnetMask[1]) PST.Str(string(".")) PST.Dec(SubnetMask[2]) PST.Str(string(".")) PST.Dec(SubnetMask[3]) PST.Str(string(PST#NL)) PST.Str(string("Gateway IP : ")) PST.Dec(GatewayIP[0]) PST.Str(string(".")) PST.Dec(GatewayIP[1]) PST.Str(string(".")) PST.Dec(GatewayIP[2]) PST.Str(string(".")) PST.Dec(GatewayIP[3]) PST.Str(string(PST#NL)) PST.Str(string("DNS Server : ")) PST.Dec(DNS_Server[0]) PST.Str(string(".")) PST.Dec(DNS_Server[1]) PST.Str(string(".")) PST.Dec(DNS_Server[2]) PST.Str(string(".")) PST.Dec(DNS_Server[3]) PST.Str(string(PST#NL)) PST.Str(string("DHCP Server: ")) PST.Dec(DHCP_Server[0]) PST.Str(string(".")) PST.Dec(DHCP_Server[1]) PST.Str(string(".")) PST.Dec(DHCP_Server[2]) PST.Str(string(".")) PST.Dec(DHCP_Server[3]) PST.Str(string(PST#NL)) PST.Str(string("Domain Name: ")) PST.Str(@DomainName) PST.Str(string(PST#NL)) else PST.Str(string("Error: ")) PST.Dec(result) PST.Str(string(PST#NL)) Stop ' PUB Start ' clear all our variables BYTEFILL(@MAC_Address[0], 0, 158) ' set the default host name BYTEMOVE(@HostName[0], @DEFAULT_HOST_NAME[0], STRSIZE(@DEFAULT_HOST_NAME[0])) ' init the Wiznet 5100 chip W5100.StartINDIRECT(W5100_DATA0, W5100_ADDR0, W5100_ADDR1, W5100_CS, W5100_RD, W5100_WR, W5100_RST, W5100_SEN) PUB Stop W5100.StopINDIRECT '' only call these GetXXX functions after calling DoDHCP() PUB GetIP(ipPtr) bytemove(ipPtr, @IP[0], 4) PUB GetGatewayIP(gatewayPtr) bytemove(gatewayPtr, @GatewayIP[0], 4) PUB GetSubnetMask(subnetPtr) bytemove(subnetPtr, @SubnetMask[0], 4) PUB GetDNSServer(dnsPtr) bytemove(dnsPtr, @DNS_Server[0], 4) PUB GetDHCPServer(dhcpPtr) bytemove(dhcpPtr, @DHCP_Server[0], 4) PUB GetDomainName return @DomainName[0] PUB GetLeaseTime return DHCP_LeaseTime '' call this function after Start, but before DoDHCP() PUB SetHostName(newHostName) bytemove(@HostName[0], newHostName, STRSIZE(newHostName)) PUB GetHostName return @HostName[0] '' call this function after Start, but before DoDHCP() PUB SetMAC_Address(newMAC_Address) MAC_Address[0] := byte[newMAC_Address][0] MAC_Address[1] := byte[newMAC_Address][1] MAC_Address[2] := byte[newMAC_Address][2] MAC_Address[3] := byte[newMAC_Address][3] MAC_Address[4] := byte[newMAC_Address][4] MAC_Address[5] := byte[newMAC_Address][5] W5100.WriteMACaddress(true, @MAC_Address[0]) PUB GetMAC_Address(macPtr) bytemove(macPtr, @MAC_Address[0], 6) '' You should call SetMAC_Address() and SetHostName() before calling this. PUB DoDHCP(socket, XID) | packetSize, startCnt, timeoutCnt, currentCnt, serverReply, DestinationIP[4], status ' open the socket with the broadcast IP and the DHCP port DestinationIP[0] := 255 DestinationIP[1] := 255 DestinationIP[2] := 255 DestinationIP[3] := 255 W5100.SocketOpen(socket, W5100#_UDPPROTO, DHCP_CLIENT_PORT, DHCP_CLIENT_PORT, @DestinationIP[0]) ' check the status of the socket status := ReadStatus(socket) if status <> W5100#_SOCK_UDP return SOCKET_FAILED_OPENING ' construct a DHCP Discover packet and send it, this asks DHCP servers to send us an Offer packet FillHeader(255,255,255,255, 67, DHCP_END-UDP_HEADER_SIZE, @Buffer[0]) FillDiscoverPacket(XID, @Buffer[0]) W5100.txUDP(socket, @Buffer[0]) PauseMSec(100) ' wait for a DHCP Offer reply, we just go with the first server to reply startCnt := CNT timeoutCnt := startCnt + DHCP_TIMEOUT repeat packetSize := W5100.rxUDP(socket, @Buffer[0]) if packetSize > 0 serverReply := ParseDHCPReply(XID, DHCP_OFFER, @Buffer[0]) case serverReply 1: ' we got our packet QUIT 2: ' got NAK from server W5100.SocketClose(socket) return SERVER_NAK ' check for timeout, handling wrap case currentCnt := CNT if startCnt < timeoutCnt if (currentCnt => timeoutCnt) OR (currentCnt < startCnt) return SERVER_TIMEOUT else if (currentCnt => timeoutCnt) AND (currentCnt < startCnt) return SERVER_TIMEOUT ' construct a DHCP Request packet and send it, requesting to claim the offered IP FillHeader(255,255,255,255, 67, DHCP_END-UDP_HEADER_SIZE, @Buffer[0]) FillRequestPacket(XID, @Buffer[0]) W5100.txUDP(socket, @Buffer[0]) PauseMSec(100) ' wait for a DHCP Ack reply, this grants us our claim on the IP startCnt := CNT timeoutCnt := startCnt + DHCP_TIMEOUT repeat packetSize := W5100.rxUDP(socket, @Buffer[0]) if packetSize > 0 serverReply := ParseDHCPReply(XID, DHCP_ACK, @Buffer[0]) case serverReply 1: ' we got our packet QUIT 2: ' got NAK from server W5100.SocketClose(socket) return SERVER_NAK ' check for timeout, handling wrap case currentCnt := CNT if startCnt < timeoutCnt if (currentCnt => timeoutCnt) OR (currentCnt < startCnt) return SERVER_TIMEOUT else if (currentCnt => timeoutCnt) AND (currentCnt < startCnt) return SERVER_TIMEOUT W5100.WriteGatewayAddress(true, @GatewayIP[0]) W5100.WriteSubnetMask(true, @SubnetMask[0]) W5100.WriteIPAddress(true, @IP[0]) W5100.SocketClose(socket) return SUCCESS PUB RenewLease(socket) 'still to be done return SERVER_NAK PRI ReadStatus(socket) | socketStatus W5100.readIND((W5100#_S0_SR + (socket * $0100)), @socketStatus, 1) { case socketStatus W5100#_SOCK_CLOSED : PST.Str(string("$00 - socket closed", PST#NL, PST#NL)) W5100#_SOCK_INIT : PST.Str(string("$13 - socket initalized", PST#NL, PST#NL)) W5100#_SOCK_LISTEN : PST.Str(string("$14 - socket listening", PST#NL, PST#NL)) W5100#_SOCK_ESTAB : PST.Str(string("$17 - socket established", PST#NL, PST#NL)) W5100#_SOCK_UDP : PST.Str(string("$22 - socket UDP open", PST#NL, PST#NL)) '} return socketStatus PRI FillHeader(ip0,ip1,ip2,ip3, port, payloadSize, packetBuffer) byte[packetBuffer][UDP_HEADER_DESTADDR] := ip3 byte[packetBuffer][UDP_HEADER_DESTADDR+1] := ip2 byte[packetBuffer][UDP_HEADER_DESTADDR+2] := ip1 byte[packetBuffer][UDP_HEADER_DESTADDR+3] := ip0 byte[packetBuffer][UDP_HEADER_PORT] := port.byte[1] byte[packetBuffer][UDP_HEADER_PORT+1] := port.byte[0] byte[packetBuffer][UDP_HEADER_PAYLOADSIZE] := payloadSize.byte[1] byte[packetBuffer][UDP_HEADER_PAYLOADSIZE+1] := payloadSize.byte[0] PRI FillBasePacket(XID, messageType, packetBuffer) | index, optionOffset, hostNameLength BYTEFILL(@byte[packetBuffer][DHCP_OP], 0, DHCP_END-UDP_HEADER_SIZE) byte[packetBuffer][DHCP_OP] := DHCP_BOOTREQUEST byte[packetBuffer][DHCP_HTYPE] := DHCP_HTYPE10MB byte[packetBuffer][DHCP_HLEN] := DHCP_HLENETHERNET byte[packetBuffer][DHCP_XID+0] := XID.byte[3] byte[packetBuffer][DHCP_XID+1] := XID.byte[2] byte[packetBuffer][DHCP_XID+2] := XID.byte[1] byte[packetBuffer][DHCP_XID+3] := XID.byte[0] byte[packetBuffer][DHCP_FLAGS+0] := DHCP_FLAGSBROADCAST>>8 'high-order byte8 byte[packetBuffer][DHCP_FLAGS+1] := (DHCP_FLAGSBROADCAST & $00FF) 'low-order byte repeat index from 0 to 5 byte[packetBuffer][DHCP_CHADDR+index] := MAC_Address[index] byte[packetBuffer][DHCP_COOKIE+0] := MAGIC_COOKIE_0 byte[packetBuffer][DHCP_COOKIE+1] := MAGIC_COOKIE_1 byte[packetBuffer][DHCP_COOKIE+2] := MAGIC_COOKIE_2 byte[packetBuffer][DHCP_COOKIE+3] := MAGIC_COOKIE_3 optionOffset := 0 byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpMessageType byte[packetBuffer][DHCP_OPT+optionOffset++] := 1 byte[packetBuffer][DHCP_OPT+optionOffset++] := messageType byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpClientIdentifier byte[packetBuffer][DHCP_OPT+optionOffset++] := 7 byte[packetBuffer][DHCP_OPT+optionOffset++] := 1 repeat index from 0 to 5 byte[packetBuffer][DHCP_OPT+optionOffset++] := MAC_Address[index] byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_hostName hostNameLength := STRSIZE(@HostName[0]) ' force to be even, so next option after this will be word aligned (16bit) if (hostNameLength & 1) == 1 hostNameLength += 1 byte[packetBuffer][DHCP_OPT+optionOffset++] := hostNameLength repeat index from 0 to hostNameLength-1 byte[packetBuffer][DHCP_OPT+optionOffset++] := HostName[index] return optionOffset PRI FillDiscoverPacket(XID, packetBuffer) | optionOffset optionOffset := FillBasePacket(XID, DHCP_DISCOVER, packetBuffer) byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpParamRequest byte[packetBuffer][DHCP_OPT+optionOffset++] := 6 byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_subnetMask byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_domainName byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dns byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_routersOnSubnet byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpT1value byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpT2value byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_endOption PRI FillRequestPacket(XID, packetBuffer) | optionOffset optionOffset := FillBasePacket(XID, DHCP_REQUEST, packetBuffer) byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpRequestedIPaddr byte[packetBuffer][DHCP_OPT+optionOffset++] := 4 byte[packetBuffer][DHCP_OPT+optionOffset++] := IP[0] byte[packetBuffer][DHCP_OPT+optionOffset++] := IP[1] byte[packetBuffer][DHCP_OPT+optionOffset++] := IP[2] byte[packetBuffer][DHCP_OPT+optionOffset++] := IP[3] byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpServerIdentifier byte[packetBuffer][DHCP_OPT+optionOffset++] := 4 byte[packetBuffer][DHCP_OPT+optionOffset++] := DHCP_Server[0] byte[packetBuffer][DHCP_OPT+optionOffset++] := DHCP_Server[1] byte[packetBuffer][DHCP_OPT+optionOffset++] := DHCP_Server[2] byte[packetBuffer][DHCP_OPT+optionOffset++] := DHCP_Server[3] byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpParamRequest byte[packetBuffer][DHCP_OPT+optionOffset++] := 8 byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_subnetMask byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_routersOnSubnet byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dns byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_domainName byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpT1value byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_dhcpT2value byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_performRouterDiscovery byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_staticRoute byte[packetBuffer][DHCP_OPT+optionOffset++] := OPT_endOption PRI ParseDHCPReply(XID, expectedType, packetBuffer) | index, optionOffset, option, optionLength, port, payloadSize port := (byte[packetBuffer][UDP_HEADER_PORT] * 256) + byte[packetBuffer][UDP_HEADER_PORT+1] payloadsize := (byte[packetBuffer][UDP_HEADER_PAYLOADSIZE] * 256) + byte[packetBuffer][UDP_HEADER_PAYLOADSIZE+1] ' verify the packet is from the DHCP server and is at least of minimum size if port <> DHCP_SERVER_PORT OR payloadSize < DHCP_OPT return 0 ' this is not a DHCP packet ' verify that the packet is a DHCP Reply if byte[packetBuffer][DHCP_OP] <> DHCP_BOOTREPLY return 0 ' this is not a DHCP Reply ' verify XID match repeat index from 0 to 3 if XID.byte[index] <> byte[packetBuffer][DHCP_XID+3-index] return 0 ' does not match, so not for us ' verify MAC Address match repeat index from 0 to 5 if MAC_Address[index] <> byte[packetBuffer][DHCP_CHADDR+index] return 0 ' does not match, so not for us ' save the IP that is offered/claimed IP[0] := byte[packetBuffer][DHCP_YIADDR+0] IP[1] := byte[packetBuffer][DHCP_YIADDR+1] IP[2] := byte[packetBuffer][DHCP_YIADDR+2] IP[3] := byte[packetBuffer][DHCP_YIADDR+3] DHCP_LeaseTime := 0 ' scan through options pulling out stuff we need optionOffset := 0 repeat option := byte[packetBuffer][DHCP_OPT+optionOffset++] if option <> 0 optionLength := byte[packetBuffer][DHCP_OPT+optionOffset++] else optionLength := 0 case option OPT_endOption : QUIT OPT_dhcpMessageType : if byte[packetBuffer][DHCP_OPT+optionOffset] <> expectedType if byte[packetBuffer][DHCP_OPT+optionOffset] == DHCP_NAK return 2 else return 0 OPT_subnetMask : SubnetMask[0] := byte[packetBuffer][DHCP_OPT+optionOffset+0] SubnetMask[1] := byte[packetBuffer][DHCP_OPT+optionOffset+1] SubnetMask[2] := byte[packetBuffer][DHCP_OPT+optionOffset+2] SubnetMask[3] := byte[packetBuffer][DHCP_OPT+optionOffset+3] OPT_routersOnSubnet : GatewayIP[0] := byte[packetBuffer][DHCP_OPT+optionOffset+0] GatewayIP[1] := byte[packetBuffer][DHCP_OPT+optionOffset+1] GatewayIP[2] := byte[packetBuffer][DHCP_OPT+optionOffset+2] GatewayIP[3] := byte[packetBuffer][DHCP_OPT+optionOffset+3] OPT_dhcpIPaddrLeaseTime : DHCP_LeaseTime.byte[0] := byte[packetBuffer][DHCP_OPT+optionOffset+3] DHCP_LeaseTime.byte[1] := byte[packetBuffer][DHCP_OPT+optionOffset+2] DHCP_LeaseTime.byte[2] := byte[packetBuffer][DHCP_OPT+optionOffset+1] DHCP_LeaseTime.byte[3] := byte[packetBuffer][DHCP_OPT+optionOffset+0] OPT_dns : DNS_Server[0] := byte[packetBuffer][DHCP_OPT+optionOffset+0] DNS_Server[1] := byte[packetBuffer][DHCP_OPT+optionOffset+1] DNS_Server[2] := byte[packetBuffer][DHCP_OPT+optionOffset+2] DNS_Server[3] := byte[packetBuffer][DHCP_OPT+optionOffset+3] OPT_dhcpServerIdentifier : DHCP_Server[0] := byte[packetBuffer][DHCP_OPT+optionOffset+0] DHCP_Server[1] := byte[packetBuffer][DHCP_OPT+optionOffset+1] DHCP_Server[2] := byte[packetBuffer][DHCP_OPT+optionOffset+2] DHCP_Server[3] := byte[packetBuffer][DHCP_OPT+optionOffset+3] OPT_domainName : BYTEMOVE(@DomainName[0], @byte[packetBuffer][DHCP_OPT+optionOffset], optionLength) optionOffset += optionLength return 1 PRI PauseMSec(Duration) '' Pause execution for specified milliseconds. '' This routine is based on the set clock frequency. '' '' params: Duration = number of milliseconds to delay '' return: none waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)Also, it appears that the reset button does not work. Cycling the power reloads the code from EEPROM, but pushing the reset button does not.
http://forums.parallax.com/showthread.php?128520-Google-Code-repository-for-open-source-Spinneret-Web-Server-firmware
I appreciate all of your suggestions, but I am still not able to get it working. I downloaded all fresh copies of W5100_Indirect_Driver.spin and W5100_UDP_Echo_Demo_indirect.spin from the code repository, and PST from OBEX. Here is the output:
W5100 Indirect Driver Test UDP Packet Demo Initialize all addresses... Set MAC ID........02:00:00:01:23:45 Verified MAC ID...E9:E9:E9:E9:E9:E9 Set Gateway.....192.168.10.1 Verified Gateway..225.225.225.225 Set Subnet......255.255.255.0 Verified Subnet...237.237.237.237 Set IP..........192.168.10.75 Verified IP.......239.239.239.239 Initialize socket 0, port 5000 Socket 0 Status Register: Attempting to open UDP on socket 0, port 5000... Socket 0 Status Register: UDP opening failed, program endingUsing the TCP Echo Demo for indirect, it still doesn't work, but I get different numbers:
W5100 Indirect Driver Test TCP Server Demo Initialize all addresses... Set MAC ID........02:00:00:01:23:45 Verified MAC ID...E1:E1:E1:E1:E1:E1 Set Gateway.....192.168.10.1 Verified Gateway..233.233.233.233 Set Subnet......255.255.255.0 Verified Subnet...237.237.237.237 Set IP..........192.168.10.75 Verified IP.......239.239.239.239 Socket Memory size initialized Initialize socket 0, port 5000 Socket 0 Status Register: Attempting to open TCP on socket 0, port 5000... Socket 0 Status Register: Setting TCP on socket 0, port 5000 to listening Socket 0 Status Register: Waiting for a client to connect....I power cycle and go back to the UDP demo and get yet another set of numbers:
W5100 Indirect Driver Test UDP Packet Demo Initialize all addresses... Set MAC ID........02:00:00:01:23:45 Verified MAC ID...E9:E9:E9:E9:E9:E9 Set Gateway.....192.168.10.1 Verified Gateway..233.233.233.233 Set Subnet......255.255.255.0 Verified Subnet...229.229.229.229 Set IP..........192.168.10.75 Verified IP.......231.231.231.231 Initialize socket 0, port 5000 Socket 0 Status Register: Attempting to open UDP on socket 0, port 5000... Socket 0 Status Register: UDP opening failed, program endingWhen I get home from work I'll post code I know works.
Parallax Serial Terminal.spin
W5100_Indirect_Driver.spin
W5100_TCP_Server_Echo_Demo_indirect.spin
W5100_UDP_Echo_Demo_indirect.spin
I am beginning to wonder if I have a defective unit.
On a side note, I have no way to determining the version of code you are running without the source. There are countless posts where folks publish code snippets. Often the problem is elsewhere. Anyway, now forum members can verify the version you have loaded.
First of all, I don't mind admitting when I make mistakes. Don't believe me? Keep reading.
I talked via email to Dave Andreae @ Parallax and basically said that I can't get my spinneret working and sent him a link to this thread as to the things that I had tried. He got back to me later that day and told me that he would send out another module to see if it solves the issue. The new module arrived today and I put everything else on hold to hook it up and confirm that I am a genius and my first spinneret was in fact defective. I hooked it up, download the fresh code just to be sure, sent it off, switched to the serial terminal and waited excitedly..... Awww cripes... This one doesn't work either! Perhaps they are getting damaged in shipping? Perhaps it was from a bad batch? Either way, my genius status is intact... right? I thought it would be a good idea to try the TCP code instead of UDP, just for kicks. I clicked send again and hung my head in disgust, knowing that it still wasn't going to work. This is when I happened to notice something that made my genius status head right for the recycle bin. What I noticed was some pretty twinkling lights, but not really where they should be. They were on the demo board's USB controller. It then took me about a half a second to really realize what was wrong and that I'm an idiot. I had sent the right program about 50 times to ...... you guessed it... the WRONG PROP!! Once I disconnected the USB cable for it (COM3) the prop tool was able to program the spinneret on COM4 and the lights on the prop plug were all twinkly. It didn't even occur to me before that they weren't lighting up when I sent a program or was receiving serial data.
So, long story short is: Both spinnerets work and I'm an idiot.
Hopefully if 100 people read this, 1 will remember it and save themselves some time and frustration at a later date, and the other 99 will get a good laugh.
Benj