portdio.c

Go to the documentation of this file.
00001 
00099 #define MY_MAC          {0x00,0x06,0x98,0x20,0x00,0x00}
00100 #define MY_IP           "192.168.192.100"
00101 #define MY_MASK         "255.255.255.0"
00102 #define MY_PORT         12345
00103 
00104 #include <string.h>
00105 #include <stdio.h>
00106 
00107 #include <dev/board.h>
00108 #include <dev/gpio.h>
00109 
00110 #include <sys/heap.h>
00111 #include <sys/thread.h>
00112 #include <sys/timer.h>
00113 #include <sys/socket.h>
00114 
00115 #include <arpa/inet.h>
00116 #include <net/route.h>
00117 #include <netdb.h>
00118 
00119 #include <pro/dhcp.h>
00120 
00121 #if defined(ETHERNUT1) || defined(ETHERNUT2)
00122 #define INBANK      2    /* PORTB */
00123 #define INPIN1      0
00124 #define INPIN2      1
00125 #define INPIN3      2
00126 #define INPIN4      3
00127 #define OUTBANK     2    /* PORTB */
00128 #define OUTPIN1     4
00129 #define OUTPIN2     5
00130 #define OUTPIN3     6
00131 #define OUTPIN4     7
00132 #elif defined(ETHERNUT3)
00133 /* Uses same expansion port pins as Ethernut 1/2. */
00134 #define INBANK      0    /* PIO */
00135 #define INPIN1      0
00136 #define INPIN2      1
00137 #define INPIN3      2
00138 #define INPIN4      3
00139 #define OUTBANK     0    /* PIO */
00140 #define OUTPIN1     4
00141 #define OUTPIN2     5
00142 #define OUTPIN3     6
00143 #define OUTPIN4     7
00144 #elif defined(AT91SAM7X_EK)
00145 #define INBANK      1    /* PIOA Joystick */
00146 #define INPIN1      21
00147 #define INPIN2      22
00148 #define INPIN3      23
00149 #define INPIN4      24
00150 #define OUTBANK     2    /* PIOB User LEDs */
00151 #define OUTPIN1     19
00152 #define OUTPIN2     20
00153 #define OUTPIN3     21
00154 #define OUTPIN4     22
00155 #elif defined(AT91SAM9260_EK)
00156 #define INBANK      1   /* PIOA */
00157 #define INPIN1      30  /* Push button 3 */
00158 #define INPIN2      31  /* Push button 4 */
00159 #define OUTBANK     1   /* PIOA */
00160 #define OUTPIN1     6   /* User LED */
00161 #define OUTPIN2     9   /* Power LED */
00162 #endif
00163 
00164 /*
00165  * Previous AVR versions read the full PIN register. Now each input
00166  * and output pin is freely configurable (within a single port bank).
00167  * This routine collects all pins as they would have been read
00168  * from a single 8-bit register.
00169  */
00170 static int PortStatus(void)
00171 {
00172     int stat = 0;
00173 #ifdef INBANK
00174 #ifdef INPIN1
00175     stat |= GpioPinGet(INBANK, INPIN1);
00176 #endif
00177 #ifdef INPIN2
00178     stat |= GpioPinGet(INBANK, INPIN2) << 1;
00179 #endif
00180 #ifdef INPIN3
00181     stat |= GpioPinGet(INBANK, INPIN3) << 2;
00182 #endif
00183 #ifdef INPIN4
00184     stat |= GpioPinGet(INBANK, INPIN4) << 3;
00185 #endif
00186 #endif /* INBANK */
00187 
00188 #ifdef OUTBANK
00189 #ifdef OUTPIN1
00190     stat |= GpioPinGet(OUTBANK, OUTPIN1) << 4;
00191 #endif
00192 #ifdef OUTPIN2
00193     stat |= GpioPinGet(OUTBANK, OUTPIN2) << 5;
00194 #endif
00195 #ifdef OUTPIN3
00196     stat |= GpioPinGet(OUTBANK, OUTPIN3) << 6;
00197 #endif
00198 #ifdef OUTPIN4
00199     stat |= GpioPinGet(OUTBANK, OUTPIN4) << 7;
00200 #endif
00201 #endif /* OUTBANK */
00202 
00203     return stat;
00204 }
00205 
00206 /*
00207  * Process client requests.
00208  */
00209 void ProcessRequests(FILE * stream)
00210 {
00211     char buff[128];
00212     char *cp;
00213     int stat = -1;
00214 
00215     fputs("200 Welcome to portdio. Type help to get help.\r\n", stream);
00216     for (;;) {
00217         fflush(stream);
00218 
00219         /*
00220          * Read a line from the client. Ignore
00221          * blank lines.
00222          */
00223         if (fgets(buff, sizeof(buff), stream) == 0)
00224             break;
00225         if ((cp = strchr(buff, '\r')) != 0)
00226             *cp = 0;
00227         if ((cp = strchr(buff, '\n')) != 0)
00228             *cp = 0;
00229         if (buff[0] == 0)
00230             continue;
00231 
00232         /*
00233          * Memory info.
00234          */
00235         if (strncmp(buff, "memory", strlen(buff)) == 0) {
00236             fprintf(stream, "210 %u bytes RAM free\r\n", (u_int)NutHeapAvailable());
00237             continue;
00238         }
00239 
00240 #ifdef OUTBANK
00241         /*
00242          * Reset output bit.
00243          */
00244         if (strlen(buff) > 1 && strncmp(buff, "reset", strlen(buff) - 1) == 0) {
00245             int ok = 1;
00246             switch (buff[strlen(buff) - 1]) {
00247 #ifdef OUTPIN1
00248             case '1':
00249                 GpioPinSetLow(OUTBANK, OUTPIN1);
00250                 break;
00251 #endif
00252 #ifdef OUTPIN2
00253             case '2':
00254                 GpioPinSetLow(OUTBANK, OUTPIN2);
00255                 break;
00256 #endif
00257 #ifdef OUTPIN3
00258             case '3':
00259                 GpioPinSetLow(OUTBANK, OUTPIN3);
00260                 break;
00261 #endif
00262 #ifdef OUTPIN4
00263             case '4':
00264                 GpioPinSetLow(OUTBANK, OUTPIN4);
00265                 break;
00266 #endif
00267             default:
00268                 ok = 0;
00269                 break;
00270             }
00271             if (ok) {
00272                 fputs("210 OK\r\n", stream);
00273             } else
00274                 fputs("410 Bad pin\r\n", stream);
00275             continue;
00276         }
00277 
00278         /*
00279          * Set output bit.
00280          */
00281         if (strlen(buff) > 1 && strncmp(buff, "set", strlen(buff) - 1) == 0) {
00282             int ok = 1;
00283             switch (buff[strlen(buff) - 1]) {
00284 #ifdef OUTPIN1
00285             case '1':
00286                 GpioPinSetHigh(OUTBANK, OUTPIN1);
00287                 break;
00288 #endif
00289 #ifdef OUTPIN2
00290             case '2':
00291                 GpioPinSetHigh(OUTBANK, OUTPIN2);
00292                 break;
00293 #endif
00294 #ifdef OUTPIN3
00295             case '3':
00296                 GpioPinSetHigh(OUTBANK, OUTPIN3);
00297                 break;
00298 #endif
00299 #ifdef OUTPIN4
00300             case '4':
00301                 GpioPinSetHigh(OUTBANK, OUTPIN4);
00302                 break;
00303 #endif
00304             default:
00305                 ok = 0;
00306                 break;
00307             }
00308             if (ok) {
00309                 fputs("210 OK\r\n", stream);
00310             } else
00311                 fputs("410 Bad pin\r\n", stream);
00312             continue;
00313         }
00314 #endif /* OUTBANK */
00315 
00316 #ifdef INBANK
00317         /*
00318          * Port status.
00319          */
00320         if (strncmp(buff, "query", strlen(buff)) == 0) {
00321             stat = PortStatus();
00322             fprintf(stream, "210 %02X\r\n", stat);
00323             continue;
00324         }
00325 
00326         /*
00327          * wait for status change.
00328          */
00329         if (strncmp(buff, "wait", strlen(buff)) == 0) {
00330             while (stat == PortStatus())
00331                 NutThreadYield();
00332             stat = PortStatus();
00333             fprintf(stream, "210 %02X\r\n", stat);
00334             continue;
00335         }
00336 #endif /* INBANK */
00337 
00338         /*
00339          * Help.
00340          */
00341         fputs("400 List of commands follows\r\n", stream);
00342         fputs("memory\tQueries number of RAM bytes free\r\n", stream);
00343 #if OUTBANK
00344         fputs("reset#\tSet output bit 1..4 low\r\n", stream);
00345         fputs("set#\tSet output bit 1..4 high\r\n", stream);
00346 #endif
00347 #if INBANK
00348         fputs("query\tQuery digital i/o status\r\n", stream);
00349         fputs("wait\tWaits for digital i/o change\r\n", stream);
00350 #endif
00351         fputs(".\r\n", stream);
00352     }
00353 }
00354 
00355 /*
00356  * Init Port D
00357  */
00358 void init_dio(void)
00359 {
00360     /* Configure input pins, enable pull up. */
00361 #ifdef INBANK
00362 #ifdef INPIN1
00363     GpioPinConfigSet(INBANK, INPIN1, GPIO_CFG_PULLUP);
00364 #endif
00365 #ifdef INPIN2
00366     GpioPinConfigSet(INBANK, INPIN2, GPIO_CFG_PULLUP);
00367 #endif
00368 #ifdef INPIN3
00369     GpioPinConfigSet(INBANK, INPIN3, GPIO_CFG_PULLUP);
00370 #endif
00371 #ifdef INPIN4
00372     GpioPinConfigSet(INBANK, INPIN4, GPIO_CFG_PULLUP);
00373 #endif
00374 #endif /* INBANK */
00375 
00376     /* Configure output pins, set to low. */
00377 #ifdef OUTBANK
00378 #ifdef OUTPIN1
00379     GpioPinConfigSet(OUTBANK, OUTPIN1, GPIO_CFG_OUTPUT);
00380     GpioPinSetLow(OUTBANK, OUTPIN1);
00381 #endif
00382 #ifdef OUTPIN2
00383     GpioPinConfigSet(OUTBANK, OUTPIN2, GPIO_CFG_OUTPUT);
00384     GpioPinSetLow(OUTBANK, OUTPIN2);
00385 #endif
00386 #ifdef OUTPIN3
00387     GpioPinConfigSet(OUTBANK, OUTPIN3, GPIO_CFG_OUTPUT);
00388     GpioPinSetLow(OUTBANK, OUTPIN3);
00389 #endif
00390 #ifdef OUTPIN4
00391     GpioPinConfigSet(OUTBANK, OUTPIN4, GPIO_CFG_OUTPUT);
00392     GpioPinSetLow(OUTBANK, OUTPIN4);
00393 #endif
00394 #endif /* OUTBANK */
00395 }
00396 
00397 void service(void)
00398 {
00399     TCPSOCKET *sock;
00400     FILE *stream;
00401 
00402     /*
00403      * Loop endless for connections.
00404      */
00405     for (;;) {
00406         /*
00407          * Create a socket.
00408          */
00409         sock = NutTcpCreateSocket();
00410 
00411         /*
00412          * Listen at the configured port. If we return, we got a client.
00413          */
00414         NutTcpAccept(sock, MY_PORT);
00415 
00416         /*
00417          * Create a stream from the socket.
00418          */
00419         stream = _fdopen((int) sock, "r+b");
00420 
00421         /*
00422          * Process client requests.
00423          */
00424         ProcessRequests(stream);
00425 
00426         /*
00427          * Destroy our device.
00428          */
00429         fclose(stream);
00430 
00431         /*
00432          * Close our socket.
00433          */
00434         NutTcpCloseSocket(sock);
00435     }
00436 }
00437 
00438 THREAD(service_thread, arg)
00439 {
00440     for (;;)
00441         service();
00442 }
00443 
00444 /*
00445  * Main application routine. 
00446  *
00447  * Nut/OS automatically calls this entry after initialization.
00448  */
00449 int main(void)
00450 {
00451     u_char my_mac[] = MY_MAC;
00452 
00453     /*
00454      * Initialize digital I/O.
00455      */
00456     init_dio();
00457 
00458     /*
00459      * Register Realtek controller at address 8300 hex
00460      * and interrupt 5.
00461      */
00462     NutRegisterDevice(&DEV_ETHER, 0x8300, 5);
00463 
00464     /*
00465      * Configure lan interface. 
00466      */
00467     if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000) && NutDhcpIfConfig("eth0", my_mac, 60000)) {
00468         /*
00469          * No DHCP server available. Use hard coded values.
00470          */
00471         u_long ip_addr = inet_addr(MY_IP);      /* ICCAVR fix. */
00472         NutNetIfConfig("eth0", my_mac, ip_addr, inet_addr(MY_MASK));
00473     }
00474 
00475     /*
00476      * Start another service thread to allow
00477      * two concurrent connections.
00478      */
00479     NutThreadCreate("sback", service_thread, 0, 1384);
00480 
00481     for (;;)
00482         service();
00483 
00484     return 0;
00485 }

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