spirilis 1,265 Posted February 20, 2014 Share Posted February 20, 2014 This is a code library implementing a sockets-oriented interface to the WizNet W5200. It's been a long time coming, and the plan is to implement DHCP support soon; almost there, had to rewrite the lib from scratch to allow piecemeal I/O with various socket types first. For now, the code includes working examples for the MSP430G2553 and MSP430F5529 LaunchPads. It needs a lot of documentation work though so don't fret if you can't get them working :-) More to come... Link: https://github.com/spirilis/w5200sock After DHCP support is working on the older W5200, I am going to adapt this into a W5500 library called w5500sock. As it stands right now though this library should be sufficient for building TCP and UDP clients and servers, managing several simultaneously along with doing repeated DNS lookups (A records only, i.e. dnslib_gethostbyname() is the only implemented client function so far). Much of the API is designed to allow the MCU to write or read data piecemeal without having to allocate any large buffers of its own to manage the data. See dnslib.c for good examples... there are flags for the various recv, send and flush calls which do "virtual" reads of the data without signalling the readiness to receive new packets, and the wiznet_send() and wiznet_sendto() calls take an argument as to whether the packet should be committed yet. This enables low SRAM usage for e.g. the G2553. I think the API is too fat for the G2452 though, so G2553 at a minimum. bluehash, Automate and dubnet 3 Quote Link to post Share on other sites
spirilis 1,265 Posted February 25, 2014 Author Share Posted February 25, 2014 Ok, sitting down with http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol and http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml to try and bang this one out. Got simple functions for reading & writing the base DHCP packet headers, working on the "option" fields, then composing it all together with an event loop. RobG 1 Quote Link to post Share on other sites
spirilis 1,265 Posted February 26, 2014 Author Share Posted February 26, 2014 Ok well, the code's a bit piggish, and I found a bug in one of the foundation lib functions, but I got a successful connection!! Init- Send DHCPDISCOVER: Our MAC: 54520000F801 Check for DHCPOFFER... Found packet: dhcp_read_option opt = 53, len = 1 Packet is DHCPOFFER dhcp_read_option opt = 1, len = 4 dhcp_read_option opt = 58, len = 4 dhcp_read_option opt = 59, len = 4 dhcp_read_option opt = 51, len = 4 dhcp_read_option opt = 54, len = 4 DHCP server = 0A6808C9 dhcp_read_option opt = 3, len = 4 gateway = 0A687301 dhcp_read_option opt = 6, len = 8 DNS = 0A6808C9 dhcp_read_option opt = 255, len = 0 Send DHCPREQUEST: Check for DHCPACK... Found packet: yiaddr_ack = 0A687329 siaddr_ack = 00000000 dhcp_read_option opt = 53, len = 1 Packet is DHCPACK dhcp_read_option opt = 58, len = 4 dhcp_read_option opt = 59, len = 4 dhcp_read_option opt = 51, len = 4 dhcp_read_option opt = 54, len = 4 siaddr_ack = 0A6808C9 dhcp_read_option opt = 1, len = 4 dhcp_read_option opt = 255, len = 0 DHCPACK contents processed; DNS was provided Configuring WizNet IP settings DHCP completed: Main registers: Mode: 0x00 Sys IRQ: 0x00 Sock IRQ Mask: 0x00 Retry Count: 0x08 Sock IRQ Pending: 0x00 PHY status: 0x27 Sys IRQ Mask: 0x00 Socket #0: Mode: 0x00 IRQ: 0x00 Status: 0x00 Source port: 0x0000 Dest IP: 0x00000000 Dest port: 0x0000 MSS: 0x0000 IP TOS: 0x00 IP TTL: 0x80 TX buffer free: 0x0800 TX readptr: 0x0000 TX writeptr: 0x0000 RX recvsize: 0x0000 RX readptr: 0x0000 RX writeptr: 0x0000 IRQ Mask: 0xFF wiznet_socket(): 6 connect(74.112.203.145): send: GET / HTTP/1.0 Host: spirilis.net recv loop: line: 17 HTTP/1.1 200 OK line: 37 Date: Wed, 26 Feb 2014 19:27:47 GMT line: 70 Server: Apache/2.2.9 (Debian) PHP/5.3.6 mod_ssl/2.2.9 OpenSSL/0.9.8g line: 46 Last-Modified: Mon, 11 Jan 2010 15:10:11 GMT line: 35 ETag: "35446f1-168-47ce4ef003ac0" line: 22 Accept-Ranges: bytes line: 21 Content-Length: 360 line: 23 Vary: Accept-Encoding line: 19 Connection: close line: 25 Content-Type: text/html line: 2 line: 7 <html> line: 7 <head> line: 18 <title>hi</title> line: 7 <body> line: 22 <h1>spirilis.net</h1> line: 16 <p>welcome.</p> line: 8 </body> line: 10 <address> line: 126 <a href="http://ubuntucounter.geekosophical.net" title="The Ubuntu Counter Project - user number # 960"><img src="http://ubuntline: 120 ucounter.geekosophical.net/img/ubuntu-user2.ph> line: 11 </address> line: 8 </html> recv error: Not connected Successful DHCP register, followed by HTTP client request. Damned program ballooned to 14KB though. I do have some strerror() type of functions defined, including a dnslib_strerror() and dhcp_strerror() though with their corresponding rodata descriptions. This example program looks like this for the init & DHCP portion: int main() { int sockfd, i; uint8_t netbuf[128]; uint16_t myip[2], dns[2]; WDTCTL = WDTPW | WDTHOLD; ucs_clockinit(16000000, 1, 0); __delay_cycles(160000); uartcli_begin(uartbuf, 8); uartcli_println_str("Init-"); if ( (sockfd = wiznet_init()) < 0) { // borrowing 'sockfd' for storing return value uartcli_print_str("FAILED: "); interpret_senderror(sockfd); LPM4; } w52_portoffset = 0; while (wiznet_phystate() < 0) __delay_cycles(160000); dns[0] = dns[1] = 0xFFFF; i = dhcp_loop_configure(1, dns); // The DHCP step if (i < 0) { uartcli_print_str("dhcp_loop_configure error: "); interpret_senderror(i); uartcli_print_str("dhcplib errno: "); uartcli_println_str(dhcp_strerror(dhcplib_errno)); LPM4; } dnslib_resolver = dns; uartcli_println_str("DHCP completed:"); wiznet_debug_uart(0); if (dns[0] == 0xFFFF || dns[1] == 0xFFFF) { uartcli_println_str("DHCP completed but DNS not configured."); LPM4; } sockfd = wiznet_socket(IPPROTO_TCP); if (sockfd < 0) { uartcli_print_str("wiznet_socket failed: "); interpret_senderror(sockfd); LPM4; } ...yadda yadda... 4jochen and RobG 2 Quote Link to post Share on other sites
spirilis 1,265 Posted February 26, 2014 Author Share Posted February 26, 2014 Also need to add more arguments/etc. for pulling the lease time information, etc. Then a suitable loop for doing a DHCP renewal in case the user gives a crap about that and all. Quote Link to post Share on other sites
spirilis 1,265 Posted February 27, 2014 Author Share Posted February 27, 2014 Ah yes, also going to clean up the uartcli crap I have in there and consolidate it into a #define'able wiznet_lib_debug() function or something. Having a true "debug" feature that can be compiled in or left out is important when dealing with TCP/IP crap. Quote Link to post Share on other sites
spirilis 1,265 Posted February 28, 2014 Author Share Posted February 28, 2014 Library and examples (minus G2553 examples which I haven't touched in a while) have been revamped to use a new debugging infrastructure, wiznet_debug_printf() and a 6-layer debug setting... wiznet_debug1_printf() through wiznet_debug6_printf() which become aliased to wiznet_debug_printf(), or just to ";", in response to the value of #define WIZNET_DEBUG. So you can dial up the bloat & verbosity by setting that #define higher, or stick to the basics by setting it lower, or ignore them altogether by setting it to 0. Implemented like this: /* Debug levels: * 1 - Basic information from libraries * 2 - Verbose error reporting from libraries * 3 - Gratuitous information from libraries * 4 - Verbose detail from base socket library * 5 - Extraneous detail from base socket library * 6 - Low-level I/O dump from SPI transfer functions * * Each debug level includes information from all levels below. */ #define WIZNET_DEBUG 3 void wiznet_debug_init(); void wiznet_debug_printf(char *format, ...); void wiznet_debug_dumpregs_main(); void wiznet_debug_dumpregs_sock(int); void wiznet_debug_putc(unsigned int); void wiznet_debug_puts(const char *); #if WIZNET_DEBUG > 0 #define wiznet_debug1_printf(...) wiznet_debug_printf(__VA_ARGS__) #else #define wiznet_debug1_printf(...) ; #endif #if WIZNET_DEBUG > 1 #define wiznet_debug2_printf(...) wiznet_debug_printf(__VA_ARGS__) #else #define wiznet_debug2_printf(...) ; #endif #if WIZNET_DEBUG > 2 #define wiznet_debug3_printf(...) wiznet_debug_printf(__VA_ARGS__) #else #define wiznet_debug3_printf(...) ; #endif #if WIZNET_DEBUG > 3 #define wiznet_debug4_printf(...) wiznet_debug_printf(__VA_ARGS__) #else #define wiznet_debug4_printf(...) ; #if WIZNET_DEBUG > 4 #define wiznet_debug5_printf(...) wiznet_debug_printf(__VA_ARGS__) #else #define wiznet_debug5_printf(...) ; #endif #if WIZNET_DEBUG > 5 #define wiznet_debug6_printf(...) wiznet_debug_printf(__VA_ARGS__) #else #define wiznet_debug6_printf(...) ; #endif I've found any serious work with TCP/IP needs the ability to generate gobloads of debugging crap. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.