diff --git a/examples/zolertia/zoul/orion/README.md b/examples/zolertia/zoul/orion/README.md new file mode 100644 index 000000000..bd57b5284 --- /dev/null +++ b/examples/zolertia/zoul/orion/README.md @@ -0,0 +1,56 @@ +RE-Mote IP64 README file +======================== + +This example shows how to use the Zolertia's Orion Ethernet router, based on the Zoul and ENC28J60 modules, with active POE support. + +IP64 router +----------------- +The router packs a built-in webserver and optionally can run on 2.4GHz or with the Sub-1GHz radio interface. In the `project-conf.h` file you can alternatively enable one or another as follows: + +* RF 2.4GHz (cc2538 built-in) + +```` +#define NETSTACK_CONF_RADIO cc2538_rf_driver +#define ANTENNA_SW_SELECT_DEF_CONF ANTENNA_SW_SELECT_2_4GHZ +```` + +* RF Sub-1GHz (CC1200) + +```` +#define NETSTACK_CONF_RADIO cc1200_driver +#define ANTENNA_SW_SELECT_DEF_CONF ANTENNA_SW_SELECT_SUBGHZ +```` + +To compile and flash run: + +```` +cd ip64-router +make TARGET=zoul BOARD=router ip64-router.upload +```` + +As default we enable the `DHCP` support for autoconfiguration. Just connect to a DHCP-enabled device to obtain an IPv4 IP address and that's it!. + +HTTP client examples +----------------- + +There are available 2 examples ready to use using the `http-socket` library: + +* The `client` example just makes a HTTP `GET` request to a know page and retrieves + the result. + +* The `ifttt-client` example sends a HTTP `POST` request to [IFTTT](https://ifttt.com/recipes) whenever the user button is pressed, building an Internet button to connect to several channels and applications, such as `Drive`, `Evernote` and many others. + +To configure the `IFTTT` demo just edit the `project-conf.h` file and change the name of the event and write your API key: + +```` +#define IFTTT_EVENT "button" +#define IFTTT_KEY "XXXXXX" +```` + +To compile and flash: + +```` +cd client +make TARGET=zoul ifttt-client.upload +```` + diff --git a/examples/zolertia/zoul/orion/client/Makefile b/examples/zolertia/zoul/orion/client/Makefile new file mode 100644 index 000000000..51b6bea47 --- /dev/null +++ b/examples/zolertia/zoul/orion/client/Makefile @@ -0,0 +1,12 @@ +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = client ifttt_client +all: $(CONTIKI_PROJECT) + +BOARD = orion + +MODULES += core/net/http-socket + +WITH_IP64 = 1 + +CONTIKI = ../../../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/orion/client/client.c b/examples/zolertia/zoul/orion/client/client.c new file mode 100644 index 000000000..5fe1c76d4 --- /dev/null +++ b/examples/zolertia/zoul/orion/client/client.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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 holder nor the names of its + * 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 HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-net.h" +#include "http-socket.h" +#include "ip64-addr.h" +#include "dev/leds.h" +#include "rpl.h" +#include +/*---------------------------------------------------------------------------*/ +static struct http_socket s; +static char data_received[HTTP_CLIENT_BUFFER_LEN]; +static int bytes_received = 0; +static int restarts; +static struct ctimer reconnect_timer; +static const char *url = "http://httpbin.org/ip"; +/*---------------------------------------------------------------------------*/ +static void callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen); +/*---------------------------------------------------------------------------*/ +PROCESS(http_example_process, "HTTP Example"); +AUTOSTART_PROCESSES(&http_example_process); +/*---------------------------------------------------------------------------*/ +static void +reconnect(void *dummy) +{ + rpl_set_mode(RPL_MODE_MESH); + http_socket_get(&s, url, 0, 0, callback, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +restart(void) +{ + int scale; + restarts++; + printf("Number of restarts %d\n", restarts); + + scale = restarts; + if(scale > 5) { + scale = 5; + } + ctimer_set(&reconnect_timer, random_rand() % ((CLOCK_SECOND * 10) << scale), + reconnect, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen) +{ + uint8_t i; + + if(e == HTTP_SOCKET_ERR) { + printf("HTTP socket error\n"); + } else if(e == HTTP_SOCKET_TIMEDOUT) { + printf("HTTP socket error: timed out\n"); + restart(); + } else if(e == HTTP_SOCKET_ABORTED) { + printf("HTTP socket error: aborted\n"); + restart(); + } else if(e == HTTP_SOCKET_HOSTNAME_NOT_FOUND) { + printf("HTTP socket error: hostname not found\n"); + restart(); + } else if(e == HTTP_SOCKET_CLOSED) { + + if(bytes_received) { + printf("HTTP socket received data:\n\n"); + for(i=0; i +/*---------------------------------------------------------------------------*/ +static struct http_socket s; +static char data_received[HTTP_CLIENT_BUFFER_LEN]; +static char url_buffer[HTTP_CLIENT_BUFFER_LEN]; +static int bytes_received = 0; +static int restarts; +static struct ctimer reconnect_timer; +/*---------------------------------------------------------------------------*/ +static void callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen); +/*---------------------------------------------------------------------------*/ +PROCESS(http_example_process, "IFTTT HTTP Example"); +AUTOSTART_PROCESSES(&http_example_process); +/*---------------------------------------------------------------------------*/ +static void +reconnect(void *dummy) +{ + rpl_set_mode(RPL_MODE_MESH); + leds_on(LEDS_GREEN); + http_socket_post(&s, url_buffer, NULL, 0, NULL, callback, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +restart(void) +{ + int scale; + restarts++; + printf("Number of restarts %d\n", restarts); + leds_off(LEDS_GREEN); + + scale = restarts; + if(scale > 5) { + scale = 5; + } + + ctimer_set(&reconnect_timer, random_rand() % ((CLOCK_SECOND * 10) << scale), + reconnect, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen) +{ + uint8_t i; + + if(e == HTTP_SOCKET_ERR) { + printf("HTTP socket error\n"); + } else if(e == HTTP_SOCKET_TIMEDOUT) { + printf("HTTP socket error: timed out\n"); + restart(); + } else if(e == HTTP_SOCKET_ABORTED) { + printf("HTTP socket error: aborted\n"); + restart(); + } else if(e == HTTP_SOCKET_HOSTNAME_NOT_FOUND) { + printf("HTTP socket error: hostname not found\n"); + restart(); + } else if(e == HTTP_SOCKET_CLOSED) { + + if(bytes_received) { + printf("HTTP socket received data:\n\n"); + for(i=0; i + * Niclas Finne + * Joakim Eriksson + */ +/*---------------------------------------------------------------------------*/ +#include +#include +#include "contiki-net.h" +#include "httpd-simple.h" +#define webserver_log_file(...) +#define webserver_log(...) + +#ifndef WEBSERVER_CONF_CFS_CONNS +#define CONNS UIP_CONNS +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define CONNS WEBSERVER_CONF_CFS_CONNS +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +#ifndef WEBSERVER_CONF_CFS_URLCONV +#define URLCONV 0 +#else /* WEBSERVER_CONF_CFS_URLCONV */ +#define URLCONV WEBSERVER_CONF_CFS_URLCONV +#endif /* WEBSERVER_CONF_CFS_URLCONV */ +/*---------------------------------------------------------------------------*/ +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 +/*---------------------------------------------------------------------------*/ +MEMB(conns, struct httpd_state, CONNS); +/*---------------------------------------------------------------------------*/ +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_period 0x2e +#define ISO_slash 0x2f +/*---------------------------------------------------------------------------*/ +static const char *NOT_FOUND = "" +"
" +"

404 - file not found

" +"
" +"" +""; +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_string(struct httpd_state *s, const char *str)) +{ + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, str); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char http_content_type_html[] = "Content-type: text/html\r\n\r\n"; +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + /* char *ptr; */ + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, statushdr); + SEND_STRING(&s->sout, http_content_type_html); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char http_header_200[] = "HTTP/1.0 200 OK\r\nServer: Contiki/Zolertia/\r\nConnection: close\r\n"; +const char http_header_404[] = "HTTP/1.0 404 Not found\r\nServer: Contiki/Zolertia/\r\nConnection: close\r\n"; +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + PT_BEGIN(&s->outputpt); + + s->script = NULL; + s->script = httpd_simple_get_script(&s->filename[1]); + if(s->script == NULL) { + strncpy(s->filename, "/notfound.html", sizeof(s->filename)); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_404)); + PT_WAIT_THREAD(&s->outputpt, + send_string(s, NOT_FOUND)); + uip_close(); + webserver_log_file(&uip_conn->ripaddr, "404 - not found"); + PT_EXIT(&s->outputpt); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_200)); + PT_WAIT_THREAD(&s->outputpt, s->script(s)); + } + s->script = NULL; + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +const char http_get[] = "GET "; +const char http_index_html[] = "/index.html"; +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + +#if URLCONV + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + urlconv_tofilename(s->filename, s->inputbuf, sizeof(s->filename)); +#else /* URLCONV */ + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, s->inputbuf, sizeof(s->filename)); + } +#endif /* URLCONV */ + + webserver_log_file(&uip_conn->ripaddr, s->filename); + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + s->script = NULL; + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + webserver_log_file(&uip_conn->ripaddr, "reset (no memory block)"); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->script = NULL; + s->state = STATE_WAITING; + timer_set(&s->timer, CLOCK_SECOND * 10); + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + if(timer_expired(&s->timer)) { + uip_abort(); + s->script = NULL; + memb_free(&conns, s); + webserver_log_file(&uip_conn->ripaddr, "reset (timeout)"); + } + } else { + timer_restart(&s->timer); + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_init(void) +{ + tcp_listen(UIP_HTONS(80)); + memb_init(&conns); +#if URLCONV + urlconv_init(); +#endif /* URLCONV */ +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/zolertia/zoul/orion/ip64-router/httpd-simple.h b/examples/zolertia/zoul/orion/ip64-router/httpd-simple.h new file mode 100644 index 000000000..c3e2a0769 --- /dev/null +++ b/examples/zolertia/zoul/orion/ip64-router/httpd-simple.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * 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 Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * A simple webserver + * \author + * Adam Dunkels + * Niclas Finne + * Joakim Eriksson + */ +/*---------------------------------------------------------------------------*/ +#ifndef HTTPD_SIMPLE_H_ +#define HTTPD_SIMPLE_H_ + +#include "contiki-net.h" +#ifndef WEBSERVER_CONF_CFS_PATHLEN +#define HTTPD_PATHLEN 2 +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define HTTPD_PATHLEN WEBSERVER_CONF_CFS_PATHLEN +#endif /* WEBSERVER_CONF_CFS_CONNS */ +/*---------------------------------------------------------------------------*/ +struct httpd_state; +typedef char (* httpd_simple_script_t)(struct httpd_state *s); +/*---------------------------------------------------------------------------*/ +struct httpd_state { + struct timer timer; + struct psock sin, sout; + struct pt outputpt; + char inputbuf[HTTPD_PATHLEN + 24]; +/*char outputbuf[UIP_TCP_MSS]; */ + char filename[HTTPD_PATHLEN]; + httpd_simple_script_t script; + char state; +}; +/*---------------------------------------------------------------------------*/ +void httpd_init(void); +void httpd_appcall(void *state); +httpd_simple_script_t httpd_simple_get_script(const char *name); +/*---------------------------------------------------------------------------*/ +#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, strlen(str)) +/*---------------------------------------------------------------------------*/ +#endif /* HTTPD_SIMPLE_H_ */ diff --git a/examples/zolertia/zoul/orion/ip64-router/ip64-router.c b/examples/zolertia/zoul/orion/ip64-router/ip64-router.c new file mode 100644 index 000000000..b69e4d80c --- /dev/null +++ b/examples/zolertia/zoul/orion/ip64-router/ip64-router.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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 holder nor the names of its + * 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 HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zolertia-orion-router + * @{ + * + * \file + * Example of an Ethernet IP64 router with weberver + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/rpl/rpl.h" +#include "rpl-dag-root.h" +#include "dev/leds.h" +#include "ip64.h" +#include "net/netstack.h" +#include "httpd-simple.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BUFFER_LENGTH 256 +/*---------------------------------------------------------------------------*/ +#define LEDS_DHCP LEDS_GREEN +#define WEBSERVER_CONF_LOADTIME 0 +#define WEBSERVER_CONF_FILESTATS 0 +#define WEBSERVER_CONF_NEIGHBOR_STATUS 0 +/*---------------------------------------------------------------------------*/ +PROCESS(router_node_process, "Router node w/ webserver"); +/*---------------------------------------------------------------------------*/ +#if WEBSERVER_CONF_ROUTE_LINKS + #define BUF_USES_STACK 1 +#endif + +PROCESS(webserver_nogui_process, "Web server"); +PROCESS_THREAD(webserver_nogui_process, ev, data) +{ + PROCESS_BEGIN(); + + httpd_init(); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + httpd_appcall(data); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +AUTOSTART_PROCESSES(&router_node_process,&webserver_nogui_process); +/*---------------------------------------------------------------------------*/ +static const char *TOP = "Zolertia IP64 Router\n"; +static const char *BOTTOM = "\n"; +#if BUF_USES_STACK +static char *bufptr, *bufend; +#define ADD(...) do { \ + bufptr += snprintf(bufptr, bufend - bufptr, __VA_ARGS__); \ + } while(0) +#else +static char buf[BUFFER_LENGTH]; +static int blen; +#define ADD(...) do { \ + blen += snprintf(&buf[blen], sizeof(buf) - blen, __VA_ARGS__); \ + } while(0) +#endif + +/*---------------------------------------------------------------------------*/ +static void +ipaddr_add(const uip_ipaddr_t *addr) +{ + uint16_t a; + int i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) ADD("::"); + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + ADD(":"); + } + ADD("%x", a); + } + } +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(generate_routes(struct httpd_state *s)) +{ + static uip_ds6_route_t *r; + static uip_ds6_nbr_t *nbr; +#if BUF_USES_STACK + char buf[BUFFER_LENGTH]; +#endif +#if WEBSERVER_CONF_LOADTIME + static clock_time_t numticks; + numticks = clock_time(); +#endif + + PSOCK_BEGIN(&s->sout); + SEND_STRING(&s->sout, TOP); +#if BUF_USES_STACK + bufptr = buf;bufend=bufptr+sizeof(buf); +#else + blen = 0; +#endif + ADD("Neighbors
");
+
+  for(nbr = nbr_table_head(ds6_neighbors);
+      nbr != NULL;
+      nbr = nbr_table_next(ds6_neighbors, nbr)) {
+
+#if WEBSERVER_CONF_NEIGHBOR_STATUS
+#if BUF_USES_STACK
+      {
+        char* j = bufptr + 25;
+        ipaddr_add(&nbr->ipaddr);
+        while (bufptr < j) ADD(" ");
+        switch (nbr->state) {
+          case NBR_INCOMPLETE: ADD(" INCOMPLETE");break;
+          case NBR_REACHABLE: ADD(" REACHABLE");break;
+          case NBR_STALE: ADD(" STALE");break;
+          case NBR_DELAY: ADD(" DELAY");break;
+          case NBR_PROBE: ADD(" NBR_PROBE");break;
+        }
+      }
+#else
+      {
+        uint8_t j = blen + 25;
+        ipaddr_add(&nbr->ipaddr);
+        while (blen < j) ADD(" ");
+        switch (nbr->state) {
+          case NBR_INCOMPLETE: ADD(" INCOMPLETE");break;
+          case NBR_REACHABLE: ADD(" REACHABLE");break;
+          case NBR_STALE: ADD(" STALE");break;
+          case NBR_DELAY: ADD(" DELAY");break;
+          case NBR_PROBE: ADD(" NBR_PROBE");break;
+        }
+      }
+#endif
+#else
+      ipaddr_add(&nbr->ipaddr);
+#endif
+
+      ADD("\n");
+#if BUF_USES_STACK
+      if(bufptr > bufend - 45) {
+        SEND_STRING(&s->sout, buf);
+        bufptr = buf; bufend = bufptr + sizeof(buf);
+      }
+#else
+      if(blen > sizeof(buf) - 45) {
+        SEND_STRING(&s->sout, buf);
+        blen = 0;
+      }
+#endif
+  }
+  ADD("
Routes
");
+  SEND_STRING(&s->sout, buf);
+#if BUF_USES_STACK
+  bufptr = buf; bufend = bufptr + sizeof(buf);
+#else
+  blen = 0;
+#endif
+
+  for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) {
+
+#if BUF_USES_STACK
+#if WEBSERVER_CONF_ROUTE_LINKS
+    ADD("ipaddr);
+    ADD("]/status.shtml>");
+    ipaddr_add(&r->ipaddr);
+    ADD("");
+#else
+    ipaddr_add(&r->ipaddr);
+#endif
+#else
+#if WEBSERVER_CONF_ROUTE_LINKS
+    ADD("ipaddr);
+    ADD("]/status.shtml>");
+    SEND_STRING(&s->sout, buf);
+    blen = 0;
+    ipaddr_add(&r->ipaddr);
+    ADD("");
+#else
+    ipaddr_add(&r->ipaddr);
+#endif
+#endif
+    ADD("/%u (via ", r->length);
+    ipaddr_add(uip_ds6_route_nexthop(r));
+    if(1 || (r->state.lifetime < 600)) {
+      ADD(") %lus\n", (unsigned long)r->state.lifetime);
+    } else {
+      ADD(")\n");
+    }
+    SEND_STRING(&s->sout, buf);
+#if BUF_USES_STACK
+    bufptr = buf; bufend = bufptr + sizeof(buf);
+#else
+    blen = 0;
+#endif
+  }
+  ADD("
"); + +#if WEBSERVER_CONF_FILESTATS + static uint16_t numtimes; + ADD("
This page sent %u times",++numtimes); +#endif + +#if WEBSERVER_CONF_LOADTIME + numticks = clock_time() - numticks + 1; + ADD(" (%u.%02u sec)", numticks / CLOCK_SECOND, + (100 * (numticks % CLOCK_SECOND)) / CLOCK_SECOND)); +#endif + + SEND_STRING(&s->sout, buf); + SEND_STRING(&s->sout, BOTTOM); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_simple_script_t +httpd_simple_get_script(const char *name) +{ + return generate_routes; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(router_node_process, ev, data) +{ + PROCESS_BEGIN(); + + static struct etimer et; + + /* Turn radio off while initialazing */ + NETSTACK_MAC.off(0); + + /* Initialize the IP64 module so we'll start translating packets */ + ip64_init(); + + printf("Waiting for an address...\n"); + + /* Wait to get a DHCP address */ + etimer_set(&et, CLOCK_SECOND * 5); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + leds_toggle(LEDS_DHCP); + + if(ip64_hostaddr_is_configured()) { + + const uip_ip4addr_t *hostaddr = ip64_get_hostaddr(); + const uip_ip4addr_t *netmask = ip64_get_netmask(); + const uip_ip4addr_t *gwaddr = ip64_get_draddr(); + + printf("IPv4 DHCP address: %d.%d.%d.%d\n", hostaddr->u8[0], + hostaddr->u8[1], + hostaddr->u8[2], + hostaddr->u8[3]); + printf("Netmask : %d.%d.%d.%d\n", netmask->u8[0], netmask->u8[1], + netmask->u8[2], netmask->u8[3]); + printf("Gateway: %d.%d.%d.%d\n", gwaddr->u8[0], gwaddr->u8[1], + gwaddr->u8[2], gwaddr->u8[3]); + break; + } + etimer_reset(&et); + } + + leds_off(LEDS_DHCP); + + /* Turn the radio on and create the network */ + NETSTACK_MAC.off(1); + + /* Set us up as a RPL root node. */ + rpl_dag_root_init_dag(); + + /* ... and do nothing more. */ + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/zolertia/zoul/orion/ip64-router/project-conf.h b/examples/zolertia/zoul/orion/ip64-router/project-conf.h new file mode 100644 index 000000000..088f71761 --- /dev/null +++ b/examples/zolertia/zoul/orion/ip64-router/project-conf.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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 holder nor the names of its + * 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 HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zolertia-orion-router Zolertia's Orion border router + * + * Implements a simple IP64 router with a webserver + * + * @{ + * + * \file + * Configuration file for the Zolertia's Orion IP64 router + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +/* Prevent the router from dropping below LPM2 to avoid RAM overflow */ +#define LPM_CONF_MAX_PM 0 + +/* Use either the cc1200_driver for sub-1GHz, or cc2538_rf_driver (default) + * for 2.4GHz built-in radio interface + */ +#undef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc2538_rf_driver + +/* Disable RDC */ +#define NETSTACK_CONF_RDC nullrdc_driver + +/* USe DHCP */ +#define IP64_CONF_DHCP 1 + +/* Webserver settings */ +#define WEBSERVER_CONF_ROUTE_LINKS 0 +#define UIP_CONF_RECEIVE_WINDOW 128 +#define WEBSERVER_CONF_CFS_CONNS 2 +#define UIP_CONF_BUFFER_SIZE 900 +#define UIP_CONF_TCP_MSS 128 + +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/Makefile.zoul b/platform/zoul/Makefile.zoul index 102876bb2..de0622cd3 100644 --- a/platform/zoul/Makefile.zoul +++ b/platform/zoul/Makefile.zoul @@ -50,10 +50,14 @@ endif CONTIKI_CPU=$(CONTIKI)/cpu/cc2538 include $(CONTIKI_CPU)/Makefile.cc2538 -MODULES += core/net core/net/mac \ +MODULES += core/net core/net/mac core/net/ip \ core/net/mac/contikimac \ core/net/llsec core/net/llsec/noncoresec dev/cc1200 +ifeq ($(WITH_IP64),1) + MODULES += core/net/ip64 +endif + BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py ### Use the specific Zoul subplatform to query for connected devices diff --git a/platform/zoul/images/orion-pinout.png b/platform/zoul/images/orion-pinout.png new file mode 100755 index 000000000..bb11265b7 Binary files /dev/null and b/platform/zoul/images/orion-pinout.png differ diff --git a/platform/zoul/images/orion-router-front.png b/platform/zoul/images/orion-router-front.png new file mode 100755 index 000000000..1cb0c2b9b Binary files /dev/null and b/platform/zoul/images/orion-router-front.png differ diff --git a/platform/zoul/orion/Makefile.orion b/platform/zoul/orion/Makefile.orion new file mode 100644 index 000000000..684ce6d0f --- /dev/null +++ b/platform/zoul/orion/Makefile.orion @@ -0,0 +1,6 @@ +MOTELIST_ZOLERTIA = orion +MODULES += dev/enc28j60 +CC2538_ENC28J60_ARCH ?= gpio +WITH_IP64 ?= 1 +CFLAGS += -DUIP_FALLBACK_INTERFACE=ip64_uip_fallback_interface +BOARD_SOURCEFILES += board.c enc28j60-arch-$(CC2538_ENC28J60_ARCH).c leds-arch.c diff --git a/platform/zoul/orion/README.md b/platform/zoul/orion/README.md new file mode 100644 index 000000000..4875b6594 --- /dev/null +++ b/platform/zoul/orion/README.md @@ -0,0 +1,44 @@ +Zolertia Orion Ethernet Router +============================================ + +![Zolertia Orion Ethernet Router][zolertia-orion-router] + +The Zolertia Orion Ethernet Router allows to create IoT applications out-of-the-box, connecting any IPv4/IPv6 service or application to 6LoWPAN wireless networks. + +The Orion Router is a capable IPv4/IPv6 routing device, with an Ethernet interface and dual wireless radio, powered either via micro-USB or Power Over Ethernet (POE). The device integrates the ENC28J60 ethernet module, and an external POE module, supporting up to 48VDC. + +Orion is compatible with [6lbr](https://github.com/cetic/6lbr/wiki), more information is available at our [Wiki](https://github.com/Zolertia/Resources/wiki/6lbr). + +In a nutshell the Orion Router packs the following features: + +* ARM Cortex-M3 with 512KB flash and 32KB RAM (16KB retention), 32MHz. +* ISM 2.4-GHz IEEE 802.15.4 & Zigbee compliant. +* ISM 868-, 915-, 920-, 950-MHz ISM/SRD Band. +* RP-SMA connector for a 2.4GHz external antenna +* SMA connector for a 868/915MHz external antenna +* RJ45 ethernet connector +* Ethernet 10BASE-T IPv4/IP64 +* AES-128/256, SHA2 Hardware Encryption Engine. +* ECC-128/256, RSA Hardware Acceleration Engine for Secure Key Exchange. +* On-board CP2104/PIC to flash over its micro-USB connector +* User and reset buttons. +* Power on/off button and LED to show power state +* RGB LED to allow more than 7 colour combinations. +* Indoor enclosure +* Layout 40.29 x 73.75 mm + +There are ready-to-use examples at `examples/zolertia/zoul/orion`, showing how to deploy an IP64 border router, and connect to services such as [IFTTT (If This Then That)](https://ifttt.com). + +Orion Technical documentation +============= + +* [Datasheet](https://github.com/Zolertia/Resources/tree/master/Orion%20Ethernet%20Router/Hardware/Revision%20A/Datasheets) +* [Schematics](https://github.com/Zolertia/Resources/tree/master/Orion%20Ethernet%20Router/Hardware/Revision%20A/Schematics) + +Orion Ethernet Router pin-out +============= + +![Zolertia Orion Ethernet Router pin-out][zolertia-orion-pinout] + +[zolertia-orion-pinout]: ../images/orion-pinout.png "Zolertia Orion Router pin-out" +[zolertia-orion-router]: ../images/orion-router-front.png "Zolertia Orion Ethernet Router" diff --git a/platform/zoul/orion/board.c b/platform/zoul/orion/board.c new file mode 100644 index 000000000..a68b23bfc --- /dev/null +++ b/platform/zoul/orion/board.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2016, Zolertia + * 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 holder nor the names of its + * 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 HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zolertia-orion-ethernet-router + * @{ + * + * \file + * Board-initialisation for the Zolertia Orion Ethernet Router + * + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include +#include +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + // FIXME +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + configure_unused_pins(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ + diff --git a/platform/zoul/orion/board.h b/platform/zoul/orion/board.h new file mode 100644 index 000000000..f0e7ba452 --- /dev/null +++ b/platform/zoul/orion/board.h @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2016, Zolertia + * 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 holder nor the names of its + * 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 HOLDER 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. + */ +/** + * \addtogroup zoul-platforms + * @{ + * + * \defgroup zolertia-orion-ethernet-router Zolertia IoT Orion Ethernet Router + * + * The Zolertia Orion Router includes an Ethernet ENC28J60 controller with + * active POE (power over ethernet), operating over IPv4/IP64. It features a + * dual RF interface (2.4GHz and 863-950MHz) with external antenna connectors, + * a power on/off switch and programable user button. + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the Zolertia's + * Orion Ethernet Router, Zoul-based + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "dev/gpio.h" +#include "dev/nvic.h" +/*---------------------------------------------------------------------------*/ +/** \name Orion Ethernet Router LED configuration + * + * LEDs on the eth-gw are connected as follows: + * - LED1 (Red) -> PD5 + * - LED2 (Green) -> PD4 + * - LED3 (Blue) -> PD3 + * @{ + */ +/*---------------------------------------------------------------------------*/ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_BLUE +#undef LEDS_RED +#undef LEDS_CONF_ALL + +/* In leds.h the LEDS_BLUE is defined by LED_YELLOW definition */ +#define LEDS_GREEN (1 << 4) /**< LED1 (Green) -> PD4 */ +#define LEDS_BLUE (1 << 3) /**< LED2 (Blue) -> PD3 */ +#define LEDS_RED (1 << 5) /**< LED3 (Red) -> PD5 */ + +#define LEDS_CONF_ALL (LEDS_GREEN | LEDS_BLUE | LEDS_RED) + +#define LEDS_LIGHT_BLUE (LEDS_GREEN | LEDS_BLUE) /**< Green + Blue (24) */ +#define LEDS_YELLOW (LEDS_GREEN | LEDS_RED) /**< Green + Red (48) */ +#define LEDS_PURPLE (LEDS_BLUE | LEDS_RED) /**< Blue + Red (40) */ +#define LEDS_WHITE LEDS_ALL /**< Green + Blue + Red (56) */ + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name USB configuration + * + * The USB pullup for D+ is not included in this platform + */ +#ifdef USB_PULLUP_PORT +#undef USB_PULLUP_PORT +#endif +#ifdef USB_PULLUP_PIN +#undef USB_PULLUP_PIN +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name UART configuration + * + * On the eth-gw, the UARTs are connected to the following ports/pins: + * + * - UART0: + * - RX: PA0, connected to CP2104 serial-to-usb converter TX pin + * - TX: PA1, connected to CP2104 serial-to-usb converter RX pin + * - UART1: + * - RX: PC1 + * - TX: PC0 + * - CTS: not used + * - RTS: not used + * + * We configure the port to use UART0 and UART1, CTS/RTS only for UART1, + * both without a HW pull-up resistor. + * UART0 is not exposed anywhere, UART1 pins are exposed over the JP9 connector. + * @{ + */ +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 + +#define UART1_RX_PORT GPIO_C_NUM +#define UART1_RX_PIN 1 +#define UART1_TX_PORT GPIO_C_NUM +#define UART1_TX_PIN 0 +#define UART1_CTS_PORT (-1) +#define UART1_CTS_PIN (-1) +#define UART1_RTS_PORT (-1) +#define UART1_RTS_PIN (-1) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Zolertia Orion Router button configuration + * + * Buttons on the eth-gw are connected as follows: + * - BUTTON_USER -> PA3, S1 user button, shared with bootloader + * - BUTTON_RESET -> RESET_N line + * @{ + */ +/** BUTTON_USER -> PA3 */ +#define BUTTON_USER_PORT GPIO_A_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR GPIO_A_IRQn + +/* Notify various examples that we have Buttons */ +#define PLATFORM_HAS_BUTTON 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ADC configuration + * + * These values configure which CC2538 pins and ADC channels to use for the ADC + * inputs. There pins are suggested as they can be changed, but note that only + * pins from PA can be configured as ADC. + * + * The Zolertia eth-gw, as it is, only allows 3.3VDC sensors. + * + * The internal ADC reference is 1190mV, use either a voltage divider as input, + * or a different voltage reference, like AVDD5 or other externally (AIN7 or + * AIN6). + * + * The ADC1 is exposed over the JP9 connector + * @{ + */ +#define ADC_SENSORS_PORT GPIO_A_NUM /**< ADC GPIO control port */ +#define ADC_SENSORS_ADC1_PIN 2 /**< ADC1 to PA2, 3V3 */ +#define ADC_SENSORS_ADC2_PIN 4 /**< ADC2 to PA4, 3V3 */ +#define ADC_SENSORS_ADC3_PIN 5 /**< ADC3 to PA5, 3V3 */ +#define ADC_SENSORS_ADC4_PIN 6 /**< ADC4 to PA6, 3V3 */ +#define ADC_SENSORS_ADC5_PIN (-1) /**< Not used */ +#define ADC_SENSORS_ADC6_PIN (-1) /**< Not used */ +#define ADC_SENSORS_MAX 4 /**< PA2, PA4, PA5, PA6 */ + + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI0) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI0) lines, + * reserved exclusively for the CC1200 RF transceiver. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI0_CLK_PORT GPIO_B_NUM +#define SPI0_CLK_PIN 2 +#define SPI0_TX_PORT GPIO_B_NUM +#define SPI0_TX_PIN 1 +#define SPI0_RX_PORT GPIO_B_NUM +#define SPI0_RX_PIN 3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI1) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI1) lines, + * reserved exclusively for the ENC28J60 ethernet module. These pins should not + * be used for other use, unless you really know what you are doing + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI1_CLK_PORT GPIO_C_NUM +#define SPI1_CLK_PIN 4 +#define SPI1_TX_PORT GPIO_C_NUM +#define SPI1_TX_PIN 5 +#define SPI1_RX_PORT GPIO_C_NUM +#define SPI1_RX_PIN 6 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C configuration + * + * As default there is not a default pin assignment for I2C, change this values + * accordingly if mapping either pin to the I2C controller. + * @{ + */ +#define I2C_SCL_PORT GPIO_C_NUM +#define I2C_SCL_PIN 3 +#define I2C_SDA_PORT GPIO_C_NUM +#define I2C_SDA_PIN 2 +#define I2C_INT_PORT GPIO_D_NUM +#define I2C_INT_PIN 2 +#define I2C_INT_VECTOR GPIO_D_IRQn +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Dual RF interface support + * + * Enables support for dual band operation (both CC1200 and 2.4GHz enabled). + * @{ + */ +#define REMOTE_DUAL_RF_ENABLED 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name CC1200 configuration + * + * These values configure the required pins to drive the CC1200 + * None of the following pins are exposed to any connector, kept for internal + * use only + * @{ + */ +#define CC1200_SPI_INSTANCE 0 +#define CC1200_SPI_SCLK_PORT SPI0_CLK_PORT +#define CC1200_SPI_SCLK_PIN SPI0_CLK_PIN +#define CC1200_SPI_MOSI_PORT SPI0_TX_PORT +#define CC1200_SPI_MOSI_PIN SPI0_TX_PIN +#define CC1200_SPI_MISO_PORT SPI0_RX_PORT +#define CC1200_SPI_MISO_PIN SPI0_RX_PIN +#define CC1200_SPI_CSN_PORT GPIO_B_NUM +#define CC1200_SPI_CSN_PIN 5 +#define CC1200_GDO0_PORT GPIO_B_NUM +#define CC1200_GDO0_PIN 4 +#define CC1200_GDO2_PORT GPIO_B_NUM +#define CC1200_GDO2_PIN 0 +#define CC1200_RESET_PORT GPIO_C_NUM +#define CC1200_RESET_PIN 7 +#define CC1200_GPIOx_VECTOR GPIO_B_IRQn +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Ethernet ENC28J60 configuration + * + * These values configure the required pins to drive an external Ethernet + * module. The implementation can be SPI or GPIO-based, for the first the SPI1 + * controller should be used + * @{ + */ +#define ETH_SPI_INSTANCE 1 +#define ETH_SPI_CLK_PORT SPI1_CLK_PORT +#define ETH_SPI_CLK_PIN SPI1_CLK_PIN +#define ETH_SPI_MOSI_PORT SPI1_TX_PORT +#define ETH_SPI_MOSI_PIN SPI1_TX_PIN +#define ETH_SPI_MISO_PORT SPI1_RX_PORT +#define ETH_SPI_MISO_PIN SPI1_RX_PIN +#define ETH_SPI_CSN_PORT GPIO_A_NUM +#define ETH_SPI_CSN_PIN 7 +#define ETH_INT_PORT GPIO_D_NUM +#define ETH_INT_PIN 0 +#define ETH_RESET_PORT GPIO_D_NUM +#define ETH_RESET_PIN 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name On-board external WDT + * The Orion Ethernet Router has an external WDT and battery monitor, which + * adds more robustness and prevents the mote to run wild if any unexpected + * problem shows-up. + * The external WDT requires a short pulse (<1ms) to be sent before a 2-second + * period. The battery monitor keeps the device in Reset if the voltage input + * is lower than 2.5V. + * @{ + */ +#define EXT_WDT_PORT GPIO_D_NUM +#define EXT_WDT_PIN 5 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "Zolertia Orion Ethernet Router" +/** @} */ + +#endif /* BOARD_H_ */ + +/** + * @} + * @} + */ + diff --git a/platform/zoul/orion/enc28j60-arch-gpio.c b/platform/zoul/orion/enc28j60-arch-gpio.c new file mode 100644 index 000000000..4a35e2723 --- /dev/null +++ b/platform/zoul/orion/enc28j60-arch-gpio.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2012-2013, Thingsquare, http://www.thingsquare.com/. + * Copyright (c) 2016, Zolertia + * 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 holder nor the names of its + * 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 HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zolertia-orion-ethernet-router + * @{ + * + * \defgroup zolertia-eth-arch-gpio Zolertia ENC28J60 GPIO arch + * + * ENC28J60 eth-gw GPIO arch specifics + * @{ + * + * \file + * eth-gw GPIO arch specifics + */ +/*---------------------------------------------------------------------------*/ +#include "clock.h" +#include "dev/gpio.h" +/*---------------------------------------------------------------------------*/ +#define CLK_PORT GPIO_PORT_TO_BASE(ETH_SPI_CLK_PORT) +#define CLK_BIT GPIO_PIN_MASK(ETH_SPI_CLK_PIN) +#define MOSI_PORT GPIO_PORT_TO_BASE(ETH_SPI_MOSI_PORT) +#define MOSI_BIT GPIO_PIN_MASK(ETH_SPI_MOSI_PIN) +#define MISO_PORT GPIO_PORT_TO_BASE(ETH_SPI_MISO_PORT) +#define MISO_BIT GPIO_PIN_MASK(ETH_SPI_MISO_PIN) +#define CSN_PORT GPIO_PORT_TO_BASE(ETH_SPI_CSN_PORT) +#define CSN_BIT GPIO_PIN_MASK(ETH_SPI_CSN_PIN) +#define RESET_PORT GPIO_PORT_TO_BASE(ETH_RESET_PORT) +#define RESET_BIT GPIO_PIN_MASK(ETH_RESET_PIN) +/*---------------------------------------------------------------------------*/ +/* Delay in us */ +#define DELAY 10 +/*---------------------------------------------------------------------------*/ +static void +delay(void) +{ + clock_delay_usec(DELAY); +} +/*---------------------------------------------------------------------------*/ +void +enc28j60_arch_spi_select(void) +{ + GPIO_CLR_PIN(CSN_PORT, CSN_BIT); + delay(); +} +/*---------------------------------------------------------------------------*/ +void +enc28j60_arch_spi_deselect(void) +{ + GPIO_SET_PIN(CSN_PORT, CSN_BIT); +} +/*---------------------------------------------------------------------------*/ +void +enc28j60_arch_spi_init(void) +{ + /* Set all pins to GPIO mode */ + GPIO_SOFTWARE_CONTROL(CLK_PORT, CLK_BIT); + GPIO_SOFTWARE_CONTROL(MOSI_PORT, MOSI_BIT); + GPIO_SOFTWARE_CONTROL(MISO_PORT, MISO_BIT); + GPIO_SOFTWARE_CONTROL(CSN_PORT, CSN_BIT); + GPIO_SOFTWARE_CONTROL(RESET_PORT, RESET_BIT); + + /* CSN, MOSI, CLK and RESET are output pins */ + GPIO_SET_OUTPUT(CSN_PORT, CSN_BIT); + GPIO_SET_OUTPUT(MOSI_PORT, MOSI_BIT); + GPIO_SET_OUTPUT(CLK_PORT, CLK_BIT); + GPIO_SET_OUTPUT(RESET_PORT, RESET_BIT); + + /* MISO is an input pin */ + GPIO_SET_INPUT(MISO_PORT, MISO_BIT); + + /* Enable the device */ + GPIO_SET_INPUT(RESET_PORT, RESET_BIT); + + /* The CS pin is active low, so we set it high when we haven't + selected the chip. */ + enc28j60_arch_spi_deselect(); + + /* The CLK is active low, we set it high when we aren't using it. */ + GPIO_CLR_PIN(CLK_PORT, CLK_BIT); +} +/*---------------------------------------------------------------------------*/ +uint8_t +enc28j60_arch_spi_write(uint8_t output) +{ + int i; + uint8_t input; + input = 0; + + for(i=0; i < 8; i++) { + /* Write data on MOSI pin */ + if(output & 0x80) { + GPIO_SET_PIN(MOSI_PORT, MOSI_BIT); + } else { + GPIO_CLR_PIN(MOSI_PORT, MOSI_BIT); + } + output <<= 1; + + /* Set clock high */ + GPIO_SET_PIN(CLK_PORT, CLK_BIT); + delay(); + + /* Read data from MISO pin */ + input <<= 1; + if(GPIO_READ_PIN(MISO_PORT, MISO_BIT) != 0) { + input |= 0x1; + } + + /* Set clock low */ + GPIO_CLR_PIN(CLK_PORT, CLK_BIT); + delay(); + } + return input; +} +/*---------------------------------------------------------------------------*/ +uint8_t +enc28j60_arch_spi_read(void) +{ + return enc28j60_arch_spi_write(0); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/orion/enc28j60-arch-spi.c b/platform/zoul/orion/enc28j60-arch-spi.c new file mode 100644 index 000000000..59e6e4260 --- /dev/null +++ b/platform/zoul/orion/enc28j60-arch-spi.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, CETIC. + * Copyright (c) 2016, Zolertia + * 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 holder nor the names of its + * 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 HOLDER 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zolertia-orion-ethernet-router + * @{ + * + * \defgroup zolertia-eth-arch-spi Zolertia ENC28J60 SPI arch + * + * ENC28J60 eth-gw SPI arch specifics + * @{ + * + * \file + * eth-gw SPI arch specifics + */ +/*---------------------------------------------------------------------------*/ +#include "spi-arch.h" +#include "spi.h" +#include "dev/gpio.h" +/*---------------------------------------------------------------------------*/ +#define RESET_PORT GPIO_PORT_TO_BASE(ETH_RESET_PORT) +#define RESET_BIT GPIO_PIN_MASK(ETH_RESET_PIN) +/*---------------------------------------------------------------------------*/ +void +enc28j60_arch_spi_init(void) +{ + spix_init(ETH_SPI_INSTANCE); + spix_cs_init(ETH_SPI_CSN_PORT, ETH_SPI_CSN_PIN); + spix_set_mode(ETH_SPI_INSTANCE, SSI_CR0_FRF_MOTOROLA, 0, 0, 8); + GPIO_SOFTWARE_CONTROL(RESET_PORT, RESET_BIT); + GPIO_SET_OUTPUT(RESET_PORT, RESET_BIT); + GPIO_SET_INPUT(RESET_PORT, RESET_BIT); +} +/*---------------------------------------------------------------------------*/ +void +enc28j60_arch_spi_select(void) +{ + SPIX_CS_CLR(ETH_SPI_CSN_PORT, ETH_SPI_CSN_PIN); +} +/*---------------------------------------------------------------------------*/ +void +enc28j60_arch_spi_deselect(void) +{ + SPIX_CS_SET(ETH_SPI_CSN_PORT, ETH_SPI_CSN_PIN); +} +/*---------------------------------------------------------------------------*/ +void +enc28j60_arch_spi_write(uint8_t output) +{ + SPIX_WAITFORTxREADY(ETH_SPI_INSTANCE); + SPIX_BUF(ETH_SPI_INSTANCE) = output; + SPIX_WAITFOREOTx(ETH_SPI_INSTANCE); + SPIX_WAITFOREORx(ETH_SPI_INSTANCE); + uint32_t dummy = SPIX_BUF(ETH_SPI_INSTANCE); + (void) dummy; +} +/*---------------------------------------------------------------------------*/ +uint8_t +enc28j60_arch_spi_read(void) +{ + SPIX_WAITFORTxREADY(ETH_SPI_INSTANCE); + SPIX_BUF(ETH_SPI_INSTANCE) = 0; + SPIX_WAITFOREOTx(ETH_SPI_INSTANCE); + SPIX_WAITFOREORx(ETH_SPI_INSTANCE); + return SPIX_BUF(ETH_SPI_INSTANCE); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/orion/ip64-conf.h b/platform/zoul/orion/ip64-conf.h new file mode 100644 index 000000000..c4052dfda --- /dev/null +++ b/platform/zoul/orion/ip64-conf.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * Copyright (c) 2016, Zolertia + * 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 holder nor the names of its + * 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 HOLDER 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. + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef IP64_CONF_H +#define IP64_CONF_H +/*---------------------------------------------------------------------------*/ +#include "ip64-eth-interface.h" +/*---------------------------------------------------------------------------*/ +#define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_eth_interface +#define IP64_CONF_INPUT ip64_eth_interface_input +#include "enc28j60-ip64-driver.h" +#define IP64_CONF_ETH_DRIVER enc28j60_ip64_driver +/*---------------------------------------------------------------------------*/ +#endif /* IP64_CONF_H */ diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index a5bbb1e34..debdbd53d 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -32,6 +32,7 @@ cc2538-common/crypto/zoul \ cc2538-common/pka/zoul \ zolertia/zoul/zoul \ zolertia/zoul/cc1200-demo/zoul \ +zolertia/zoul/orion/ip64-router/zoul:BOARD=orion \ openmote-cc2538/openmote-cc2538 \ er-rest-example/zoul \ ipso-objects/zoul \ diff --git a/tools/zolertia/motelist-zolertia b/tools/zolertia/motelist-zolertia index 75b95b3b9..e720b6868 100755 --- a/tools/zolertia/motelist-zolertia +++ b/tools/zolertia/motelist-zolertia @@ -59,6 +59,8 @@ if( $Opt{board} eq "z1" ) { $Opt{board} = "Zolertia RE-Mote platform"; } elsif( $Opt{board} eq "firefly" ) { $Opt{board} = "Zolertia Firefly platform"; +} elsif( $Opt{board} eq "orion" ) { + $Opt{board} = "Zolertia Orion Router"; } my @devs = $Opt{method} eq "procfs" ? scan_procfs() : scan_sysfs();