Nut/OS  4.10.3
API Reference
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 
00144 #ifdef INBANK
00145 static int PortStatus(void)
00146 {
00147     int stat = 0;
00148 
00149 #ifdef INPIN1
00150     stat |= GpioPinGet(INBANK, INPIN1);
00151 #endif
00152 #ifdef INPIN2
00153     stat |= GpioPinGet(INBANK, INPIN2) << 1;
00154 #endif
00155 #ifdef INPIN3
00156     stat |= GpioPinGet(INBANK, INPIN3) << 2;
00157 #endif
00158 #ifdef INPIN4
00159     stat |= GpioPinGet(INBANK, INPIN4) << 3;
00160 #endif
00161 
00162 
00163 #ifdef OUTBANK
00164 #ifdef OUTPIN1
00165     stat |= GpioPinGet(OUTBANK, OUTPIN1) << 4;
00166 #endif
00167 #ifdef OUTPIN2
00168     stat |= GpioPinGet(OUTBANK, OUTPIN2) << 5;
00169 #endif
00170 #ifdef OUTPIN3
00171     stat |= GpioPinGet(OUTBANK, OUTPIN3) << 6;
00172 #endif
00173 #ifdef OUTPIN4
00174     stat |= GpioPinGet(OUTBANK, OUTPIN4) << 7;
00175 #endif
00176 #endif /* OUTBANK */
00177 
00178     return stat;
00179 }
00180 #endif
00181 /*
00182  * Process client requests.
00183  */
00184 void ProcessRequests(FILE * stream)
00185 {
00186     char buff[128];
00187     char *cp;
00188     int stat = -1;
00189 
00190     fputs("200 Welcome to portdio. Type help to get help.\r\n", stream);
00191     for (;;) {
00192         fflush(stream);
00193 
00194         /*
00195          * Read a line from the client. Ignore
00196          * blank lines.
00197          */
00198         if (fgets(buff, sizeof(buff), stream) == 0)
00199             break;
00200         if ((cp = strchr(buff, '\r')) != 0)
00201             *cp = 0;
00202         if ((cp = strchr(buff, '\n')) != 0)
00203             *cp = 0;
00204         if (buff[0] == 0)
00205             continue;
00206 
00207         /*
00208          * Memory info.
00209          */
00210         if (strncmp(buff, "memory", strlen(buff)) == 0) {
00211             fprintf(stream, "210 %u bytes RAM free\r\n", (unsigned int)NutHeapAvailable());
00212             continue;
00213         }
00214 
00215 #ifdef OUTBANK
00216         /*
00217          * Reset output bit.
00218          */
00219         if (strlen(buff) > 1 && strncmp(buff, "reset", strlen(buff) - 1) == 0) {
00220             int ok = 1;
00221             switch (buff[strlen(buff) - 1]) {
00222 #ifdef OUTPIN1
00223             case '1':
00224                 GpioPinSetLow(OUTBANK, OUTPIN1);
00225                 break;
00226 #endif
00227 #ifdef OUTPIN2
00228             case '2':
00229                 GpioPinSetLow(OUTBANK, OUTPIN2);
00230                 break;
00231 #endif
00232 #ifdef OUTPIN3
00233             case '3':
00234                 GpioPinSetLow(OUTBANK, OUTPIN3);
00235                 break;
00236 #endif
00237 #ifdef OUTPIN4
00238             case '4':
00239                 GpioPinSetLow(OUTBANK, OUTPIN4);
00240                 break;
00241 #endif
00242             default:
00243                 ok = 0;
00244                 break;
00245             }
00246             if (ok) {
00247                 fputs("210 OK\r\n", stream);
00248             } else
00249                 fputs("410 Bad pin\r\n", stream);
00250             continue;
00251         }
00252 
00253         /*
00254          * Set output bit.
00255          */
00256         if (strlen(buff) > 1 && strncmp(buff, "set", strlen(buff) - 1) == 0) {
00257             int ok = 1;
00258             switch (buff[strlen(buff) - 1]) {
00259 #ifdef OUTPIN1
00260             case '1':
00261                 GpioPinSetHigh(OUTBANK, OUTPIN1);
00262                 break;
00263 #endif
00264 #ifdef OUTPIN2
00265             case '2':
00266                 GpioPinSetHigh(OUTBANK, OUTPIN2);
00267                 break;
00268 #endif
00269 #ifdef OUTPIN3
00270             case '3':
00271                 GpioPinSetHigh(OUTBANK, OUTPIN3);
00272                 break;
00273 #endif
00274 #ifdef OUTPIN4
00275             case '4':
00276                 GpioPinSetHigh(OUTBANK, OUTPIN4);
00277                 break;
00278 #endif
00279             default:
00280                 ok = 0;
00281                 break;
00282             }
00283             if (ok) {
00284                 fputs("210 OK\r\n", stream);
00285             } else
00286                 fputs("410 Bad pin\r\n", stream);
00287             continue;
00288         }
00289 #endif /* OUTBANK */
00290 
00291 #ifdef INBANK
00292         /*
00293          * Port status.
00294          */
00295         if (strncmp(buff, "query", strlen(buff)) == 0) {
00296             stat = PortStatus();
00297             fprintf(stream, "210 %02X\r\n", stat);
00298             continue;
00299         }
00300 
00301         /*
00302          * wait for status change.
00303          */
00304         if (strncmp(buff, "wait", strlen(buff)) == 0) {
00305             while (stat == PortStatus())
00306                 NutThreadYield();
00307             stat = PortStatus();
00308             fprintf(stream, "210 %02X\r\n", stat);
00309             continue;
00310         }
00311 #endif /* INBANK */
00312 
00313         /*
00314          * Help.
00315          */
00316         fputs("400 List of commands follows\r\n", stream);
00317         fputs("memory\tQueries number of RAM bytes free\r\n", stream);
00318 #if OUTBANK
00319         fputs("reset#\tSet output bit 1..4 low\r\n", stream);
00320         fputs("set#\tSet output bit 1..4 high\r\n", stream);
00321 #endif
00322 #if INBANK
00323         fputs("query\tQuery digital i/o status\r\n", stream);
00324         fputs("wait\tWaits for digital i/o change\r\n", stream);
00325 #endif
00326         fputs(".\r\n", stream);
00327     }
00328 }
00329 
00330 /*
00331  * Init Port D
00332  */
00333 void init_dio(void)
00334 {
00335     /* Configure input pins, enable pull up. */
00336 #ifdef INBANK
00337 #ifdef INPIN1
00338     GpioPinConfigSet(INBANK, INPIN1, GPIO_CFG_PULLUP);
00339 #endif
00340 #ifdef INPIN2
00341     GpioPinConfigSet(INBANK, INPIN2, GPIO_CFG_PULLUP);
00342 #endif
00343 #ifdef INPIN3
00344     GpioPinConfigSet(INBANK, INPIN3, GPIO_CFG_PULLUP);
00345 #endif
00346 #ifdef INPIN4
00347     GpioPinConfigSet(INBANK, INPIN4, GPIO_CFG_PULLUP);
00348 #endif
00349 #endif /* INBANK */
00350 
00351     /* Configure output pins, set to low. */
00352 #ifdef OUTBANK
00353 #ifdef OUTPIN1
00354     GpioPinConfigSet(OUTBANK, OUTPIN1, GPIO_CFG_OUTPUT);
00355     GpioPinSetLow(OUTBANK, OUTPIN1);
00356 #endif
00357 #ifdef OUTPIN2
00358     GpioPinConfigSet(OUTBANK, OUTPIN2, GPIO_CFG_OUTPUT);
00359     GpioPinSetLow(OUTBANK, OUTPIN2);
00360 #endif
00361 #ifdef OUTPIN3
00362     GpioPinConfigSet(OUTBANK, OUTPIN3, GPIO_CFG_OUTPUT);
00363     GpioPinSetLow(OUTBANK, OUTPIN3);
00364 #endif
00365 #ifdef OUTPIN4
00366     GpioPinConfigSet(OUTBANK, OUTPIN4, GPIO_CFG_OUTPUT);
00367     GpioPinSetLow(OUTBANK, OUTPIN4);
00368 #endif
00369 #endif /* OUTBANK */
00370 }
00371 
00372 #ifdef DEV_ETHER
00373 
00374 void service(void)
00375 {
00376     TCPSOCKET *sock;
00377     FILE *stream;
00378 
00379     /*
00380      * Loop endless for connections.
00381      */
00382     for (;;) {
00383         /*
00384          * Create a socket.
00385          */
00386         sock = NutTcpCreateSocket();
00387 
00388         /*
00389          * Listen at the configured port. If we return, we got a client.
00390          */
00391         NutTcpAccept(sock, MY_PORT);
00392 
00393         /*
00394          * Create a stream from the socket.
00395          */
00396         stream = _fdopen((int) sock, "r+b");
00397 
00398         /*
00399          * Process client requests.
00400          */
00401         ProcessRequests(stream);
00402 
00403         /*
00404          * Destroy our device.
00405          */
00406         fclose(stream);
00407 
00408         /*
00409          * Close our socket.
00410          */
00411         NutTcpCloseSocket(sock);
00412     }
00413 }
00414 
00415 THREAD(service_thread, arg)
00416 {
00417     for (;;)
00418         service();
00419 }
00420 
00421 #endif /* DEV_ETHER */
00422 
00423 /*
00424  * Main application routine. 
00425  *
00426  * Nut/OS automatically calls this entry after initialization.
00427  */
00428 int main(void)
00429 {
00430     uint8_t my_mac[] = MY_MAC;
00431 
00432     /*
00433      * Initialize digital I/O.
00434      */
00435     init_dio();
00436 
00437 #ifdef DEV_ETHER
00438     /*
00439      * Register Realtek controller at address 8300 hex
00440      * and interrupt 5.
00441      */
00442     NutRegisterDevice(&DEV_ETHER, 0x8300, 5);
00443 
00444     /*
00445      * Configure lan interface. 
00446      */
00447     if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000) && NutDhcpIfConfig("eth0", my_mac, 60000)) {
00448         /*
00449          * No DHCP server available. Use hard coded values.
00450          */
00451         uint32_t ip_addr = inet_addr(MY_IP);      /* ICCAVR fix. */
00452         NutNetIfConfig("eth0", my_mac, ip_addr, inet_addr(MY_MASK));
00453     }
00454 
00455     /*
00456      * Start another service thread to allow
00457      * two concurrent connections.
00458      */
00459     NutThreadCreate("sback", service_thread, 0, 1384);
00460 
00461     for (;;)
00462         service();
00463 #endif /* DEV_ETHER */
00464 
00465     return 0;
00466 }