| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 |
- /*!
- * Copyright (C) 2001-2008 by egnite Software GmbH
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * For additional information see http://www.ethernut.de/
- */
- /*!
- * $Id: portdio.c 4116 2012-04-12 22:35:23Z olereinhardt $
- */
- /*!
- * \example 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.
- */
- #define MY_MAC {0x00,0x06,0x98,0x20,0x00,0x00}
- #define MY_IP "192.168.192.100"
- #define MY_MASK "255.255.255.0"
- #define MY_PORT 12345
- #include <string.h>
- #include <stdio.h>
- #include <dev/board.h>
- #include <dev/gpio.h>
- #include <sys/heap.h>
- #include <sys/thread.h>
- #include <sys/timer.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <net/route.h>
- #include <netdb.h>
- #include <pro/dhcp.h>
- #if defined(ETHERNUT1) || defined(ETHERNUT2)
- #define INBANK 2 /* PORTB */
- #define INPIN1 0
- #define INPIN2 1
- #define INPIN3 2
- #define INPIN4 3
- #define OUTBANK 2 /* PORTB */
- #define OUTPIN1 4
- #define OUTPIN2 5
- #define OUTPIN3 6
- #define OUTPIN4 7
- #elif defined(ETHERNUT3)
- /* Uses same expansion port pins as Ethernut 1/2. */
- #define INBANK 0 /* PIO */
- #define INPIN1 0
- #define INPIN2 1
- #define INPIN3 2
- #define INPIN4 3
- #define OUTBANK 0 /* PIO */
- #define OUTPIN1 4
- #define OUTPIN2 5
- #define OUTPIN3 6
- #define OUTPIN4 7
- #elif defined(AT91SAM7X_EK)
- #define INBANK 1 /* PIOA Joystick */
- #define INPIN1 21
- #define INPIN2 22
- #define INPIN3 23
- #define INPIN4 24
- #define OUTBANK 2 /* PIOB User LEDs */
- #define OUTPIN1 19
- #define OUTPIN2 20
- #define OUTPIN3 21
- #define OUTPIN4 22
- #elif defined(AT91SAM9260_EK)
- #define INBANK 1 /* PIOA */
- #define INPIN1 30 /* Push button 3 */
- #define INPIN2 31 /* Push button 4 */
- #define OUTBANK 1 /* PIOA */
- #define OUTPIN1 6 /* User LED */
- #define OUTPIN2 9 /* Power LED */
- #elif defined(EVK1100)
- #define INBANK 0 /* PA Joystick */
- #define INPIN1 25
- #define INPIN2 26
- #define INPIN3 27
- #define INPIN4 28
- #define OUTBANK 1 /* PIOB User LEDs */
- #define OUTPIN1 27
- #define OUTPIN2 28
- #define OUTPIN3 29
- #define OUTPIN4 30
- #endif
- /*
- * Previous AVR versions read the full PIN register. Now each input
- * and output pin is freely configurable (within a single port bank).
- * This routine collects all pins as they would have been read
- * from a single 8-bit register.
- */
- #ifdef INBANK
- static int PortStatus(void)
- {
- int stat = 0;
- #ifdef INPIN1
- stat |= GpioPinGet(INBANK, INPIN1);
- #endif
- #ifdef INPIN2
- stat |= GpioPinGet(INBANK, INPIN2) << 1;
- #endif
- #ifdef INPIN3
- stat |= GpioPinGet(INBANK, INPIN3) << 2;
- #endif
- #ifdef INPIN4
- stat |= GpioPinGet(INBANK, INPIN4) << 3;
- #endif
- #ifdef OUTBANK
- #ifdef OUTPIN1
- stat |= GpioPinGet(OUTBANK, OUTPIN1) << 4;
- #endif
- #ifdef OUTPIN2
- stat |= GpioPinGet(OUTBANK, OUTPIN2) << 5;
- #endif
- #ifdef OUTPIN3
- stat |= GpioPinGet(OUTBANK, OUTPIN3) << 6;
- #endif
- #ifdef OUTPIN4
- stat |= GpioPinGet(OUTBANK, OUTPIN4) << 7;
- #endif
- #endif /* OUTBANK */
- return stat;
- }
- #endif
- /*
- * Process client requests.
- */
- void ProcessRequests(FILE * stream)
- {
- char buff[128];
- char *cp;
- int stat = -1;
- fputs("200 Welcome to portdio. Type help to get help.\r\n", stream);
- for (;;) {
- fflush(stream);
- /*
- * Read a line from the client. Ignore
- * blank lines.
- */
- if (fgets(buff, sizeof(buff), stream) == 0)
- break;
- if ((cp = strchr(buff, '\r')) != 0)
- *cp = 0;
- if ((cp = strchr(buff, '\n')) != 0)
- *cp = 0;
- if (buff[0] == 0)
- continue;
- /*
- * Memory info.
- */
- if (strncmp(buff, "memory", strlen(buff)) == 0) {
- fprintf(stream, "210 %u bytes RAM free\r\n", (unsigned int)NutHeapAvailable());
- continue;
- }
- #ifdef OUTBANK
- /*
- * Reset output bit.
- */
- if (strlen(buff) > 1 && strncmp(buff, "reset", strlen(buff) - 1) == 0) {
- int ok = 1;
- switch (buff[strlen(buff) - 1]) {
- #ifdef OUTPIN1
- case '1':
- GpioPinSetLow(OUTBANK, OUTPIN1);
- break;
- #endif
- #ifdef OUTPIN2
- case '2':
- GpioPinSetLow(OUTBANK, OUTPIN2);
- break;
- #endif
- #ifdef OUTPIN3
- case '3':
- GpioPinSetLow(OUTBANK, OUTPIN3);
- break;
- #endif
- #ifdef OUTPIN4
- case '4':
- GpioPinSetLow(OUTBANK, OUTPIN4);
- break;
- #endif
- default:
- ok = 0;
- break;
- }
- if (ok) {
- fputs("210 OK\r\n", stream);
- } else
- fputs("410 Bad pin\r\n", stream);
- continue;
- }
- /*
- * Set output bit.
- */
- if (strlen(buff) > 1 && strncmp(buff, "set", strlen(buff) - 1) == 0) {
- int ok = 1;
- switch (buff[strlen(buff) - 1]) {
- #ifdef OUTPIN1
- case '1':
- GpioPinSetHigh(OUTBANK, OUTPIN1);
- break;
- #endif
- #ifdef OUTPIN2
- case '2':
- GpioPinSetHigh(OUTBANK, OUTPIN2);
- break;
- #endif
- #ifdef OUTPIN3
- case '3':
- GpioPinSetHigh(OUTBANK, OUTPIN3);
- break;
- #endif
- #ifdef OUTPIN4
- case '4':
- GpioPinSetHigh(OUTBANK, OUTPIN4);
- break;
- #endif
- default:
- ok = 0;
- break;
- }
- if (ok) {
- fputs("210 OK\r\n", stream);
- } else
- fputs("410 Bad pin\r\n", stream);
- continue;
- }
- #endif /* OUTBANK */
- #ifdef INBANK
- /*
- * Port status.
- */
- if (strncmp(buff, "query", strlen(buff)) == 0) {
- stat = PortStatus();
- fprintf(stream, "210 %02X\r\n", stat);
- continue;
- }
- /*
- * wait for status change.
- */
- if (strncmp(buff, "wait", strlen(buff)) == 0) {
- while (stat == PortStatus())
- NutThreadYield();
- stat = PortStatus();
- fprintf(stream, "210 %02X\r\n", stat);
- continue;
- }
- #endif /* INBANK */
- /*
- * Help.
- */
- fputs("400 List of commands follows\r\n", stream);
- fputs("memory\tQueries number of RAM bytes free\r\n", stream);
- #if OUTBANK
- fputs("reset#\tSet output bit 1..4 low\r\n", stream);
- fputs("set#\tSet output bit 1..4 high\r\n", stream);
- #endif
- #if INBANK
- fputs("query\tQuery digital i/o status\r\n", stream);
- fputs("wait\tWaits for digital i/o change\r\n", stream);
- #endif
- fputs(".\r\n", stream);
- }
- }
- /*
- * Init Port D
- */
- void init_dio(void)
- {
- /* Configure input pins, enable pull up. */
- #ifdef INBANK
- #ifdef INPIN1
- GpioPinConfigSet(INBANK, INPIN1, GPIO_CFG_PULLUP);
- #endif
- #ifdef INPIN2
- GpioPinConfigSet(INBANK, INPIN2, GPIO_CFG_PULLUP);
- #endif
- #ifdef INPIN3
- GpioPinConfigSet(INBANK, INPIN3, GPIO_CFG_PULLUP);
- #endif
- #ifdef INPIN4
- GpioPinConfigSet(INBANK, INPIN4, GPIO_CFG_PULLUP);
- #endif
- #endif /* INBANK */
- /* Configure output pins, set to low. */
- #ifdef OUTBANK
- #ifdef OUTPIN1
- GpioPinConfigSet(OUTBANK, OUTPIN1, GPIO_CFG_OUTPUT);
- GpioPinSetLow(OUTBANK, OUTPIN1);
- #endif
- #ifdef OUTPIN2
- GpioPinConfigSet(OUTBANK, OUTPIN2, GPIO_CFG_OUTPUT);
- GpioPinSetLow(OUTBANK, OUTPIN2);
- #endif
- #ifdef OUTPIN3
- GpioPinConfigSet(OUTBANK, OUTPIN3, GPIO_CFG_OUTPUT);
- GpioPinSetLow(OUTBANK, OUTPIN3);
- #endif
- #ifdef OUTPIN4
- GpioPinConfigSet(OUTBANK, OUTPIN4, GPIO_CFG_OUTPUT);
- GpioPinSetLow(OUTBANK, OUTPIN4);
- #endif
- #endif /* OUTBANK */
- }
- #ifdef DEV_ETHER
- void service(void)
- {
- TCPSOCKET *sock;
- FILE *stream;
- /*
- * Loop endless for connections.
- */
- for (;;) {
- /*
- * Create a socket.
- */
- sock = NutTcpCreateSocket();
- /*
- * Listen at the configured port. If we return, we got a client.
- */
- NutTcpAccept(sock, MY_PORT);
- /*
- * Create a stream from the socket.
- */
- stream = _fdopen((int) sock, "r+b");
- /*
- * Process client requests.
- */
- ProcessRequests(stream);
- /*
- * Destroy our device.
- */
- fclose(stream);
- /*
- * Close our socket.
- */
- NutTcpCloseSocket(sock);
- }
- }
- THREAD(service_thread, arg)
- {
- for (;;)
- service();
- }
- #endif /* DEV_ETHER */
- /*
- * Main application routine.
- *
- * Nut/OS automatically calls this entry after initialization.
- */
- int main(void)
- {
- uint8_t my_mac[] = MY_MAC;
- /*
- * Initialize digital I/O.
- */
- init_dio();
- #ifdef DEV_ETHER
- /*
- * Register Realtek controller at address 8300 hex
- * and interrupt 5.
- */
- NutRegisterDevice(&DEV_ETHER, 0x8300, 5);
- /*
- * Configure lan interface.
- */
- if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000) && NutDhcpIfConfig("eth0", my_mac, 60000)) {
- /*
- * No DHCP server available. Use hard coded values.
- */
- uint32_t ip_addr = inet_addr(MY_IP); /* ICCAVR fix. */
- NutNetIfConfig("eth0", my_mac, ip_addr, inet_addr(MY_MASK));
- }
- /*
- * Start another service thread to allow
- * two concurrent connections.
- */
- NutThreadCreate("sback", service_thread, 0, 1384);
- for (;;)
- service();
- #endif /* DEV_ETHER */
- return 0;
- }
|