portdio.c

Go to the documentation of this file.
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-2007 by egnite Software GmbH - visit http://www.ethernut.de/