portdio.c

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

© 2000-2010 by contributors - visit http://www.ethernut.de/