portdio/portdio.c

TCP server for Port D I/O.

Program Ethernut with portdio.hex and enter

telnet x.x.x.x 12345

two times on two command prompts, replacing x.x.x.x with the IP address of your ethernut board. This will start two telnet session.

Enter help for a list of available commands.

Enter query on the first will show the current port status.

Then enter wait on this session, which will hang until the port status changes.

On the second telnet session enter set1 to set the first output bit.

00001 
00090 #define MY_MAC          {0x00,0x06,0x98,0x20,0x00,0x00}
00091 #define MY_IP           "192.168.192.100"
00092 #define MY_MASK         "255.255.255.0"
00093 
00094 #include <string.h>
00095 #include <stdio.h>
00096 
00097 #include <dev/board.h>
00098 
00099 #include <sys/heap.h>
00100 #include <sys/thread.h>
00101 #include <sys/timer.h>
00102 #include <sys/socket.h>
00103 
00104 #include <arpa/inet.h>
00105 #include <net/route.h>
00106 #include <netdb.h>
00107 
00108 #include <pro/dhcp.h>
00109 
00110 
00111 /*
00112  * Process client requests.
00113  */
00114 void ProcessRequests(FILE * stream)
00115 {
00116     u_char buff[128];
00117     u_char *cp;
00118     int stat = -1;
00119 
00120     fputs("200 Welcome to portdio. Type help to get help.\r\n", stream);
00121     for (;;) {
00122         fflush(stream);
00123 
00124         /*
00125          * Read a line from the client. Ignore
00126          * blank lines.
00127          */
00128         if (fgets(buff, sizeof(buff), stream) == 0)
00129             break;
00130         if ((cp = strchr(buff, '\r')) != 0)
00131             *cp = 0;
00132         if ((cp = strchr(buff, '\n')) != 0)
00133             *cp = 0;
00134         if (buff[0] == 0)
00135             continue;
00136 
00137         /*
00138          * Memory info.
00139          */
00140         if (strncmp(buff, "memory", strlen(buff)) == 0) {
00141             fprintf(stream, "210 %u bytes RAM free\r\n", (u_int)NutHeapAvailable());
00142             continue;
00143         }
00144 
00145         /*
00146          * List threads.
00147          */
00148         if (strncmp(buff, "threads", strlen(buff)) == 0) {
00149             NUTTHREADINFO *tdp;
00150             NUTTIMERINFO *tnp;
00151 
00152             fputs("220 List of threads with name,state,prio,stack,mem,timeout follows\r\n", stream);
00153             for (tdp = nutThreadList; tdp; tdp = tdp->td_next) {
00154                 fputs(tdp->td_name, stream);
00155                 fputs("\t", stream);
00156                 switch (tdp->td_state) {
00157                 case TDS_TERM:
00158                     fputs("\tTerm\t", stream);
00159                     break;
00160                 case TDS_RUNNING:
00161                     fputs("\tRun\t", stream);
00162                     break;
00163                 case TDS_READY:
00164                     fputs("\tReady\t", stream);
00165                     break;
00166                 case TDS_SLEEP:
00167                     fputs("\tSleep\t", stream);
00168                     break;
00169                 }
00170                 fprintf(stream, "%u\t%u", tdp->td_priority, (u_int) tdp->td_sp - (u_int) tdp->td_memory);
00171                 if (*((u_long *) tdp->td_memory) != DEADBEEF)
00172                     fputs("\tCorrupted\t", stream);
00173                 else
00174                     fputs("\tOK\t", stream);
00175 
00176                 if ((tnp = (NUTTIMERINFO *) tdp->td_timer) != 0)
00177                     fprintf(stream, "%lu", tnp->tn_ticks_left);
00178                 else
00179                     fputs("None", stream);
00180                 fputs("\r\n", stream);
00181             }
00182             fputs(".\r\n", stream);
00183             continue;
00184         }
00185 
00186         /*
00187          * List timer.
00188          */
00189         if (strncmp(buff, "timers", strlen(buff)) == 0) {
00190             NUTTIMERINFO *tnp;
00191 
00192             fputs("221 List of timers with ticks left and interval follows\r\n", stream);
00193             for (tnp = nutTimerList; tnp; tnp = tnp->tn_next) {
00194                 fprintf(stream, "%lu", tnp->tn_ticks_left);
00195                 if (tnp->tn_ticks)
00196                     fprintf(stream, "\t%lu\r\n", tnp->tn_ticks);
00197                 else
00198                     fputs("\tOneshot\r\n", stream);
00199             }
00200             fputs(".\r\n", stream);
00201             continue;
00202         }
00203 
00204         /*
00205          * Port status.
00206          */
00207         if (strncmp(buff, "query", strlen(buff)) == 0) {
00208 #ifdef __AVR__
00209             stat = inb(PIND);
00210 #endif
00211             fprintf(stream, "210 %02X\r\n", stat);
00212             continue;
00213         }
00214 
00215         /*
00216          * Reset output bit.
00217          */
00218         if (strlen(buff) > 1 && strncmp(buff, "reset", strlen(buff) - 1) == 0) {
00219             int mask = 0;
00220             switch (buff[strlen(buff) - 1]) {
00221             case '1':
00222                 mask = 0x10;
00223                 break;
00224             case '2':
00225                 mask = 0x20;
00226                 break;
00227             case '3':
00228                 mask = 0x40;
00229                 break;
00230             case '4':
00231                 mask = 0x80;
00232                 break;
00233             }
00234             if (mask) {
00235 #ifdef __AVR__
00236                 outb(PORTD, inb(PORTD) & ~mask);
00237 #endif
00238                 fputs("210 OK\r\n", stream);
00239             } else
00240                 fputs("410 Bad pin\r\n", stream);
00241             continue;
00242         }
00243 
00244         /*
00245          * Set output bit.
00246          */
00247         if (strlen(buff) > 1 && strncmp(buff, "set", strlen(buff) - 1) == 0) {
00248             int mask = 0;
00249             switch (buff[strlen(buff) - 1]) {
00250             case '1':
00251                 mask = 0x10;
00252                 break;
00253             case '2':
00254                 mask = 0x20;
00255                 break;
00256             case '3':
00257                 mask = 0x40;
00258                 break;
00259             case '4':
00260                 mask = 0x80;
00261                 break;
00262             }
00263             if (mask) {
00264 #ifdef __AVR__
00265                 outb(PORTD, inb(PORTD) | mask);
00266 #endif
00267                 fputs("210 OK\r\n", stream);
00268             } else
00269                 fputs("410 Bad pin\r\n", stream);
00270             continue;
00271         }
00272 
00273         /*
00274          * wait for status change.
00275          */
00276         if (strncmp(buff, "wait", strlen(buff)) == 0) {
00277 #ifdef __AVR__
00278             while (stat == inb(PIND))
00279                 NutThreadYield();
00280             stat = inb(PIND);
00281 #endif
00282             fprintf(stream, "210 %02X\r\n", stat);
00283             continue;
00284         }
00285 
00286         /*
00287          * Help.
00288          */
00289         fputs("400 List of commands follows\r\n", stream);
00290         fputs("memory\tQueries number of RAM bytes free\r\n", stream);
00291         fputs("query\tQuery digital i/o status\r\n", stream);
00292         fputs("reset#\tSet output bit 1..4 low\r\n", stream);
00293         fputs("set#\tSet output bit 1..4 high\r\n", stream);
00294         fputs("threads\tLists all created threads\r\n", stream);
00295         fputs("timers\tLists all running timers\r\n", stream);
00296         fputs("wait\tWaits for digital i/o change\r\n", stream);
00297         fputs(".\r\n", stream);
00298     }
00299 }
00300 
00301 /*
00302  * Init Port D
00303  */
00304 void init_dio(void)
00305 {
00306 #ifdef __AVR__
00307     /*
00308      * Upper four pins are output pins.
00309      */
00310     outb(DDRD, 0xf0);
00311 
00312     /*
00313      * Outputs to low and inputs pulled up.
00314      */
00315     outb(PORTD, 0x0f);
00316 #endif
00317 }
00318 
00319 void service(void)
00320 {
00321     TCPSOCKET *sock;
00322     FILE *stream;
00323 
00324     /*
00325      * Loop endless for connections.
00326      */
00327     for (;;) {
00328         /*
00329          * Create a socket.
00330          */
00331         sock = NutTcpCreateSocket();
00332 
00333         /*
00334          * Listen on port 12345. If we return,
00335          * we got a client.
00336          */
00337         NutTcpAccept(sock, 12345);
00338 
00339         /*
00340          * Create a stream from the socket.
00341          */
00342         stream = _fdopen((int) sock, "r+b");
00343 
00344         /*
00345          * Process client requests.
00346          */
00347         ProcessRequests(stream);
00348 
00349         /*
00350          * Destroy our device.
00351          */
00352         fclose(stream);
00353 
00354         /*
00355          * Close our socket.
00356          */
00357         NutTcpCloseSocket(sock);
00358     }
00359 }
00360 
00361 THREAD(service_thread, arg)
00362 {
00363     for (;;)
00364         service();
00365 }
00366 
00367 /*
00368  * Main application routine. 
00369  *
00370  * Nut/OS automatically calls this entry after initialization.
00371  */
00372 int main(void)
00373 {
00374     u_char my_mac[] = MY_MAC;
00375 
00376     /*
00377      * Initialize digital I/O.
00378      */
00379     init_dio();
00380 
00381     /*
00382      * Register Realtek controller at address 8300 hex
00383      * and interrupt 5.
00384      */
00385     NutRegisterDevice(&DEV_ETHER, 0x8300, 5);
00386 
00387     /*
00388      * Configure lan interface. 
00389      */
00390     if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000) && NutDhcpIfConfig("eth0", my_mac, 60000)) {
00391         /*
00392          * No DHCP server available. Use hard coded values.
00393          */
00394         u_long ip_addr = inet_addr(MY_IP);      /* ICCAVR fix. */
00395         NutNetIfConfig("eth0", my_mac, ip_addr, inet_addr(MY_MASK));
00396     }
00397 
00398     /*
00399      * Start another service thread to allow
00400      * two concurrent connections.
00401      */
00402     NutThreadCreate("sback", service_thread, 0, 1384);
00403 
00404     for (;;)
00405         service();
00406 }

© 2000-2006 by egnite Software GmbH - visit http://www.ethernut.de/