Reincarnate the sensinode/cc2430 port

This commit is contained in:
George Oikonomou 2012-03-05 16:28:06 +00:00
parent c78b5bad5c
commit b7674c3636
114 changed files with 10044 additions and 3068 deletions

View file

@ -2,7 +2,17 @@ ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740
# These examples don't need code banking so we turn it off
#HAVE_BANKING=1
CONTIKI_PROJECT = hello_world clock_test rf_test_rx rf_test_tx
# New examples added by George Oikonomou - Loughborough University
CONTIKI_PROJECT += timer-test blink-hello broadcast-rime
all: $(CONTIKI_PROJECT)
CONTIKI = ../..

View file

@ -1,6 +1,11 @@
Sensinode platform example and test applications
- by Zach Shelby (zach@sensinode.com)
Some more examples by George Oikonomou - Loughborough University
cc2431-location-engine, udp-ipv6, broadcast-rime
blink-hello, event-post, timer-test
<oikonomou@users.sourceforge.net>
This directory contains example and test applications for
Sensinode CC2430 based devices. By default it is set to use the
sensinode platform:
@ -32,8 +37,21 @@ These make options are defined in /platform/sensinode/Makefile.sensinode
Descriptions of applications:
hello_world A simple hello world app.
clock_test Test and example of sys/clock.h related features.
rf_test_tx Test for transmitting packets
rf_test_rc Test for receiving packets
hello_world A simple hello world app.
clock_test Test and example of sys/clock.h related features.
rf_test_tx Test for transmitting packets
rf_test_rc Test for receiving packets
Recent Additions:
udp-ipv6 UDP client-server example over uIPv6. Uses link-local and global
addresses. Button 1 on the client will send an echo request.
broadcast-rime Just a broadcast rime example, slightly modified
sensors Demonstrating button and ADC functionality
cc2431-location-engine
Example demonstrating the usage cc2431 location engine (blind node)
N.B. Not all sensinode devides have a cc2431
event-post Demonstrating the interaction between two processes with custom events
blink-hello Hello World with LED blinking.
timer-test Same as clock_test above + testing the rtimer-arch code
border-router 802.15.4 to SLIP bridge example. The node will forward packets
from the 15.4 network to its UART (and thus a connected PC over SLIP)

View file

@ -0,0 +1,91 @@
/* This is a very simple hello_world program.
* It aims to demonstrate the co-existence of two processes:
* One of them prints a hello world message and the other blinks the LEDs
*
* It is largely based on hello_world in $(CONTIKI)/examples/sensinode
*
* Author: George Oikonomou <G.Oikonomou@lboro.ac.uk>
*/
#include "contiki.h"
#include "dev/leds.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
/* We declare the two processes */
PROCESS(hello_world_process, "Hello world process");
PROCESS(blink_process, "LED blink process");
/* We require the processes to be started automatically */
AUTOSTART_PROCESSES(&hello_world_process, &blink_process);
/*---------------------------------------------------------------------------*/
/* Implementation of the first process */
PROCESS_THREAD(hello_world_process, ev, data)
{
/* variables are declared static to ensure their values are maintained
between subsequent calls.
All the code between PROCESS_THREAD and PROCESS_BEGIN() runs each time
the process is invoked. */
static struct etimer timer;
static int count;
/* any process must start with this. */
PROCESS_BEGIN();
/* set the etimer module to generate an event in one second.
CLOCK_CONF_SECOND is #define as 128 */
etimer_set(&timer, CLOCK_CONF_SECOND * 4);
count = 0;
/* Don't declare variables after PROCESS_BEGIN.
* While it will compile fine with TARGET=native (gcc is happy),
* SDCC doesn't like it. Soon as you try TARGET=sensinode you will get:
* syntax error: token -> 'int' ;
* Try uncommenting the line below and observe the results */
/* int whoops = 0;
* whoops = 0; */
while (1)
{
/* wait here for an event to happen */
PROCESS_WAIT_EVENT();
/* This achieves the same
* PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); */
/* if the event is the timer event as expected... */
if(ev == PROCESS_EVENT_TIMER)
{
/* do the process work */
printf("Sensor says no... #%d\r\n", count);
count ++;
/* reset the timer so it will generate an other event
* the exact same time after it expired (periodicity guaranteed) */
etimer_reset(&timer);
}
/* and loop */
}
/* any process must end with this, even if it is never reached. */
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/* Implementation of the second process */
PROCESS_THREAD(blink_process, ev, data)
{
static struct etimer timer;
PROCESS_BEGIN();
while (1)
{
/* we set the timer from here every time */
etimer_set(&timer, CLOCK_CONF_SECOND);
/* and wait until the event we receive is the one we're waiting for */
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
printf("Blink... (state %0.2X).\r\n", leds_get());
/* update the LEDs */
leds_toggle(LEDS_GREEN);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,19 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N601,PROJECT_CONF_H
# We need uIPv6, therefore we also need banking
HAVE_BANKING=1
UIP_CONF_IPV6=1
PROJECT_SOURCEFILES += slip-bridge.c
CONTIKI_PROJECT = border-router
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,16 @@
border-router example for sensinode devices.
This example is meant to be used with tunslip6 in tools/
- Build the code and load it onto your node
- Connect your node to your PC over USB
- run:
sudo ./tunslip6 <address v6>/<prefix>
This will setup tun0 on your PC over device /dev/ttyUSBx. The address
argument should contain the v6 address that you want to assign to tun0
The node will use this address to obtain the network prefix
for example:
sudo ./tunslip6 aaaa::1/64
This will use aaaa:: / 64 as the prefix for the 15.4 network.

View file

@ -0,0 +1,134 @@
/*
* 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.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include <string.h>
#define DEBUG DEBUG_PRINT
#include "net/uip-debug.h"
#include "net/rpl/rpl.h"
#include "dev/watchdog.h"
#include "dev/slip.h"
#include "dev/leds.h"
#ifndef CC2430_RF_CONF_CHANNEL
#define CC2430_RF_CONF_CHANNEL 0xFF
#endif
static uint8_t prefix_set;
/*---------------------------------------------------------------------------*/
PROCESS(border_router_process, "Border Router process");
AUTOSTART_PROCESSES(&border_router_process);
/*---------------------------------------------------------------------------*/
static void
print_local_addresses(void)
{
int i;
uint8_t state;
PRINTF("Router's IPv6 addresses:\n");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state
== ADDR_PREFERRED)) {
PRINTF(" ");
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF("\n");
if (state == ADDR_TENTATIVE) {
uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
}
}
}
}
/*---------------------------------------------------------------------------*/
void
request_prefix(void) {
/* mess up uip_buf with a dirty request... */
uip_buf[0] = '?';
uip_buf[1] = 'P';
uip_len = 2;
slip_send();
uip_len = 0;
}
/*---------------------------------------------------------------------------*/
/* Set our prefix when we receive one over SLIP */
void
set_prefix_64(uip_ipaddr_t *prefix_64) {
rpl_dag_t *dag;
uip_ipaddr_t ipaddr;
memcpy(&ipaddr, prefix_64, 16);
prefix_set = 1;
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
/* Become root of a new DODAG with ID our global v6 address */
dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr);
if(dag != NULL) {
rpl_set_prefix(dag, &ipaddr, 64);
PRINTF("Created a new RPL dag with ID: ");
PRINT6ADDR(&dag->dag_id);
PRINTF("\n");
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(border_router_process, ev, data)
{
static struct etimer et;
PROCESS_BEGIN();
PRINTF("Border Router started\n");
prefix_set = 0;
leds_on(LEDS_RED);
/* Request prefix until it has been received */
while(!prefix_set) {
leds_on(LEDS_GREEN);
PRINTF("Prefix request.\n");
etimer_set(&et, CLOCK_SECOND);
request_prefix();
leds_off(LEDS_GREEN);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
}
/* We have created a new DODAG when we reach here */
PRINTF("On Channel %u\n", CC2430_RF_CONF_CHANNEL);
print_local_addresses();
leds_off(LEDS_RED);
PROCESS_EXIT();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Project specific configuration defines for the border router /
* slip bridge example.
*
* We make sure that SLIP is turned on
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#define VIZTOOL_MAX_PAYLOAD_LEN 120
#define SLIP_ARCH_CONF_ENABLE 1
#define LPM_CONF_MODE 0
#endif /* PROJECT_CONF_H_ */

View file

@ -0,0 +1,104 @@
/*
* 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.
*
* $Id: slip-bridge.c,v 1.3 2010/06/08 19:53:49 nifi Exp $
*/
/**
* \file
* Slip fallback interface
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
*/
#include "net/uip.h"
#include "net/uip-ds6.h"
#include "net/rpl/rpl.h"
#include "dev/slip.h"
#include "dev/uart1.h"
#include <string.h>
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
void set_prefix_64(uip_ipaddr_t *);
static uip_ipaddr_t last_sender;
/*---------------------------------------------------------------------------*/
static void
slip_input_callback(void)
{
PRINTF("SIN: %u\n", uip_len);
if((char) uip_buf[0] == '!') {
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
uip_len = 0;
if((char)uip_buf[1] == 'P') {
uip_ipaddr_t prefix;
/* Here we set a prefix !!! */
memset(&prefix, 0, 16);
memcpy(&prefix, &uip_buf[2], 8);
PRINTF("Setting prefix ");
PRINT6ADDR(&prefix);
PRINTF("\n");
set_prefix_64(&prefix);
}
}
/* Save the last sender received over SLIP to avoid bouncing the
packet back if no route is found */
uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
process_start(&slip_process, NULL);
slip_set_input_callback(slip_input_callback);
}
/*---------------------------------------------------------------------------*/
static void
output(void)
{
if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) {
/* Do not bounce packets back over SLIP if the packet was received
over SLIP */
PRINTF("slip-bridge: Destination off-link but no route\n");
} else {
PRINTF("SUT: %u\n", uip_len);
slip_send();
}
}
/*---------------------------------------------------------------------------*/
const struct uip_fallback_interface slip_interface = {
init, output
};
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2007, 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.
*
* This file is part of the Contiki operating system.
*
* $Id: example-broadcast.c,v 1.2 2009/11/19 17:29:41 nifi Exp $
*/
/**
* \file
* Testing the broadcast layer in Rime
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "net/rime.h"
#include "lib/random.h"
#include "net/rime/rimestats.h"
#include "dev/leds.h"
#include "dev/models.h"
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#define BROADCAST_CHANNEL 129
/*---------------------------------------------------------------------------*/
PROCESS(example_broadcast_process, "BROADCAST example");
AUTOSTART_PROCESSES(&example_broadcast_process);
/*---------------------------------------------------------------------------*/
static void broadcast_recv(struct broadcast_conn *c, const rimeaddr_t *from)
{
leds_toggle(LEDS_RED);
PRINTF("broadcast message received from %02x.%02x\n", from->u8[0], from->u8[1]);
PRINTF("Size=0x%02x: '0x%04x'\n", packetbuf_datalen(), *(uint16_t *) packetbuf_dataptr());
}
static void print_rime_stats()
{
PRINTF("\nNetwork Stats\n");
PRINTF(" TX=%lu , RX=%lu\n", rimestats.tx, rimestats.rx);
PRINTF("LL-TX=%lu , LL-RX=%lu\n", rimestats.lltx, rimestats.llrx);
PRINTF(" Long=%lu , Short=%lu\n", rimestats.toolong, rimestats.tooshort);
PRINTF("T/Out=%lu , CCA-Err=%lu\n", rimestats.timedout,
rimestats.contentiondrop);
}
static const struct broadcast_callbacks bc_rx = { broadcast_recv };
static struct broadcast_conn broadcast;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(example_broadcast_process, ev, data)
{
static struct etimer et;
static uint16_t counter;
PROCESS_EXITHANDLER(broadcast_close(&broadcast);)
PROCESS_BEGIN();
PRINTF("Start\n");
broadcast_open(&broadcast, BROADCAST_CHANNEL, &bc_rx);
PRINTF("Open Broadcast Connection, channel %u\n", BROADCAST_CHANNEL);
// leds_off(LEDS_ALL);
while(1) {
/* Delay 2-4 seconds */
etimer_set(&et, CLOCK_SECOND * 2);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
leds_on(LEDS_GREEN);
packetbuf_copyfrom(&counter, sizeof(counter));
PRINTF("Sending %u bytes: 0x%04x\n", packetbuf_datalen(), *(uint16_t *) packetbuf_dataptr());
if (broadcast_send(&broadcast) == 0) {
PRINTF("Error Sending\n");
}
print_rime_stats();
PRINTF("===================================\n");
counter++;
leds_off(LEDS_GREEN);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,17 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740
# This example doesn't need code banking so we turn it off
#HAVE_BANKING=1
CONTIKI_PROJECT = blind-node
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,276 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Example demonstrating the cc2431 location engine.
*
* This file contains code for the blind node. The blind node must be
* equipped with a cc2431 SoC (as opposed to reference nodes which
* don't need to have a Loc. Eng.)
*
* The blind node receives co-ordinates of reference nodes over
* broadcast rime. Once it has enough data (3+ reference nodes), it
* will calculate its own position.
*
* We calculate with all potential values for parameter 'n' to
* demonstrate how 'n' influences the result of the calculation.
*
* Optionally, send the result of the calculation to a collection node
*
* More information on the cc2431 Location Engine can be found in:
* - cc2431 Datasheet
* - Texas Instruments Application Note 42
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki.h"
#include "net/rime.h"
#include "cc2431_loc_eng.h"
#include "cc2430_sfr.h"
#include <string.h>
#include <stdio.h>
#define MAX_REF_NODES 16 /* Do not change */
#define SAMPLE_RSSI 100 /* Used for testing */
#define SAMPLE_ALPHA 101
static struct meas_params parameters;
static struct refcoords ref_coords[MAX_REF_NODES];
/* Store our current location here to be transmitted to a collector node */
static uint8_t coords[2];
/*---------------------------------------------------------------------------*/
PROCESS(blindnode_bcast_rec, "Blind Node");
AUTOSTART_PROCESSES(&blindnode_bcast_rec);
/*---------------------------------------------------------------------------*/
/*
* This handles the calculation cycle. Returns non-zero on error, 0 on success.
*
* When we move this outside the example, we will perhaps want to pass
* struct refcoords *, struct meas_params *
* instead of exposing our own data structures. If this happens, we will need
* to add checks to our code to detect non-sane values
*/
static uint8_t
calculate()
{
static int j, x;
uint8_t valid_rssi = 0;
/* Turn on the Engine */
LOCENG = LOCENG_EN;
while(!(LOCENG & LOCENG_EN));
/* Reference Coordinate Load Stage */
LOCENG |= LOCENG_REFLD;
while(!(LOCENG & LOCENG_REFLD));
for(j = 0; j < MAX_REF_NODES; j++) {
/* Write the Reference Node x,y into the engine */
REFCOORD = ref_coords[j].x;
REFCOORD = ref_coords[j].y;
}
/* Reference Coordinate Load Stage Done. Proceed with measured params */
LOCENG &= ~LOCENG_REFLD;
LOCENG |= LOCENG_PARLD;
/* Load Parameters */
MEASPARM = parameters.alpha;
MEASPARM = parameters.n;
MEASPARM = parameters.x_min;
MEASPARM = parameters.x_delta;
MEASPARM = parameters.y_min;
MEASPARM = parameters.y_delta;
/* Load Neighbor RSSIs */
for(j = 0; j < MAX_REF_NODES; j++) {
if(parameters.rssi[j] != 0) {
/* Range-check for the RSSI here, can only be in [-95 dBm , -40 dBm]
* so we only accept 80 <= rssi <= 190*/
if(parameters.rssi[j] >= 80 && parameters.rssi[j] <= 190) {
valid_rssi++;
}
}
/* Write the value, even if it's zero */
MEASPARM = parameters.rssi[j];
}
/* Done with measured parameters too */
LOCENG &= ~LOCENG_PARLD;
/* Only Calculate if we have 3+ reference nodes (non-zero RSSIs) */
if(valid_rssi >= 3) {
LOCENG |= LOCENG_RUN;
} else {
LOCENG = 0;
printf("some error\n");
return 1;
}
/* Block on the calculation, between 50us and 13ms */
while(!(LOCENG & LOCENG_DONE));
/*
* LOCX contains an offset. Remove it to obtain our actual X value.
* cc2431 datasheet, section 2.1.3
*/
x = (LOCX - parameters.x_min + 1) % (parameters.x_delta + 1)
+ parameters.x_min;
coords[0] = x;
coords[1] = LOCY; /* No offset here */
printf("n=%2u: X=%3u, Y=%3u\n", parameters.n, LOCX, LOCY);
/* Turn it off */
LOCENG = 0;
return 0;
}
/*---------------------------------------------------------------------------*/
/*
* We receive X, Y from reference nodes.
* We store this in location J of the ref_coords array, where J is the LSB
* of the reference node's rime address. So we can only accept data from nodes
* with rime address ending in [0 , 15]
*/
static void
broadcast_recv(struct broadcast_conn *c, const rimeaddr_t *from)
{
packetbuf_attr_t rssi; /* Careful here, this is uint16_t */
if(from->u8[1] < MAX_REF_NODES) {
memset(&ref_coords[from->u8[1] - 1], 0, sizeof(struct refcoords));
/* Obtain incoming message's RSSI from contiki */
rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI);
/* Convert RSSI to the loc. eng. format */
parameters.rssi[from->u8[1] - 1] = (-2 * rssi);
/* Raw dump the packetbuf into the ref_coords struct */
memcpy(&ref_coords[from->u8[1] - 1], packetbuf_dataptr(), 2 * sizeof(uint8_t));
}
return;
}
/*
* Imaginary nodes to test functionality
* All nodes at 1 meter distance, rssi = -40 (80)
* Since the rssi at 1 meter = -40 (A), the blind node should think it's at
* 5,5
*/
/*---------------------------------------------------------------------------*/
static void
set_imaginary_ref_nodes() {
ref_coords[0].x = 1;
ref_coords[0].y = 5;
parameters.rssi[0] = SAMPLE_RSSI;
ref_coords[1].x = 5;
ref_coords[1].y = 1;
parameters.rssi[1] = SAMPLE_RSSI;
ref_coords[2].x = 5;
ref_coords[2].y = 9;
parameters.rssi[2] = SAMPLE_RSSI;
ref_coords[3].x = 9;
ref_coords[3].y = 5;
parameters.rssi[3] = SAMPLE_RSSI;
}
/*---------------------------------------------------------------------------*/
static const struct broadcast_callbacks broadcast_call = { broadcast_recv };
static struct broadcast_conn broadcast;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(blindnode_bcast_rec, ev, data)
{
static struct etimer et;
static uint8_t n;
int i;
PROCESS_EXITHANDLER(broadcast_close(&broadcast));
PROCESS_BEGIN();
printf("Reading Chip ID: 0x%02x\n", CHIPID);
/* Read our chip ID. If we are not cc2431, bail out */
if(CHIPID != CC2431_CHIP_ID) {
printf("Hardware does not have a location engine. Exiting.\n");
PROCESS_EXIT();
}
/* OK, we are cc2431. Do stuff */
n = 0;
/* Initalise our structs and parameters */
memset(ref_coords, 0, sizeof(struct refcoords) * MAX_REF_NODES);
memset(&parameters, 0, sizeof(struct meas_params));
/*
* Just hard-coding measurement parameters here.
* Ideally, this should be part of a calibration mechanism
*/
parameters.alpha=SAMPLE_ALPHA;
parameters.x_min=0;
parameters.x_delta=255;
parameters.y_min=0;
parameters.y_delta=255;
set_imaginary_ref_nodes();
broadcast_open(&broadcast, 129, &broadcast_call);
while(1) {
etimer_set(&et, CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
/*
* With the hard-coded parameters and locations, we will calculate
* for all possible values of n [0 , 31]
*/
parameters.n=n;
calculate();
n++;
if(n==32) { n=0; }
/* Send our calculated location to some monitoring node */
packetbuf_copyfrom(&coords, 2*sizeof(uint8_t));
broadcast_send(&broadcast);
}
PROCESS_END();
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Header file used by the example demonstrating the cc2431 location
* engine.
*
* This file contains declarations of the location engine registers and
* the LOCENG register bits. It also contains some data structures used
* to store calculation parameters and reference node coordinates.
*
* This file only needs to be included bye the blind node code file.
*
* More information on the cc2431 Location Engine can be found in:
* - cc2431 Datasheet
* - K. Aamodt, "CC2431 Location Engine", Texas Instruments Application
* Note 42.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "8051def.h"
#include <lint.h> /* For syntax parsers */
/* Location Engine Registers on the cc2431 */
__xdata __at (0xDF55) unsigned char REFCOORD;
__xdata __at (0xDF56) unsigned char MEASPARM;
__xdata __at (0xDF57) unsigned char LOCENG;
__xdata __at (0xDF58) unsigned char LOCX;
__xdata __at (0xDF59) unsigned char LOCY;
/* LOCENG Register Bits */
#define LOCENG_RUN 0x01
#define LOCENG_REFLD 0x02
#define LOCENG_PARLD 0x04
#define LOCENG_DONE 0x08
#define LOCENG_EN 0x10
/* cc2431 chips report 0x89 when the CHIPID register is read */
#define CC2431_CHIP_ID 0x89
/*
* Struct for the Calculation Parameters.
* Values stored here feed the MEASPARM register.
*
* Values should be stored here in Location Engine format:
* RSSI: 0.5 Precision, without the minus sign. All 16 must be used. Use 0
* to reduce the number of ref. nodes used in the calculation.
* Value range [-95 dBm , -40 dBm]
* A: 0.5 Precision. Value range [30.0 , 50.0] (Thus [60 , 100] decimal)
* n: Use the n Index value [0 , 31] - See cc2431 datasheet, Table 2.
* delta: Must be present. If we want the calculation to be unrestricted,
* use 0xFF
*
*/
struct meas_params {
uint8_t alpha;
uint8_t n;
uint8_t x_min;
uint8_t x_delta;
uint8_t y_min;
uint8_t y_delta;
uint8_t rssi[16];
};
/*
* Store the reference node coordinates here.
* This will feed REFCOORD.
*
* Values should be stored here in Location Engine format:
* 2 LS bits for the fractional part, 0.25 precision
* 6 MS bits for the integral part.
* Value range [0 , 63.75] (thus [0 , 255])
*/
struct refcoords {
uint8_t x;
uint8_t y;
};

View file

@ -19,7 +19,7 @@ PROCESS_THREAD(clock_test_process, ev, data)
static struct etimer et;
static clock_time_t count, start_count, end_count, diff;
static unsigned long sec;
static uint8_t i;
static u8_t i;
PROCESS_BEGIN();
@ -56,7 +56,7 @@ PROCESS_THREAD(clock_test_process, ev, data)
etimer_reset(&et);
sec = clock_seconds();
printf("%u seconds\n", (uint16_t) sec);
printf("%u seconds\n", (u16_t) sec);
leds_toggle(LEDS_GREEN);
i++;

View file

@ -0,0 +1,18 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740
HAVE_BANKING=1
UIP_CONF_IPV6=1
OFFSET_FIRMWARE=1
CONTIKI_PROJECT = disco-example
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Stub project source file. We just need to build contiki with
* OFFSET_FIRMWARE, Makefile does so.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki.h"
/*---------------------------------------------------------------------------*/
PROCESS(stub_process, "Stub process");
AUTOSTART_PROCESSES(&stub_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(stub_process, ev, data)
{
PROCESS_BEGIN();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,16 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740,PROJECT_CONF_H
PROJECT_SOURCEFILES += stub-rdc.c
CONTIKI_PROJECT = energy-scan
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Minimalistic channel energy detection.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki.h"
#include "cc2430_sfr.h"
#include "sensinode-debug.h"
#include "dev/cc2430_rf.h"
#include <stdio.h>
static uint8_t channel;
static int8_t j;
static int8_t cmax;
static int8_t rssi;
static struct etimer et;
static rtimer_clock_t t0;
#define RSSI_BASE -50
#define RSSI_SAMPLES 30
#define SAMPLE_INTERVAL (CLOCK_SECOND)
#define CHANNEL_MIN 11
#define CHANNEL_MAX 26
/* ToDo: Do this in infinite RX. Take more samples */
/*---------------------------------------------------------------------------*/
PROCESS(energy_scan, "Energy Scanner");
AUTOSTART_PROCESSES(&energy_scan);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(energy_scan, ev, data)
{
PROCESS_BEGIN();
printf("Energy Scanner\n");
printf("CCA Threshold: %d\n", (int8_t)RSSIH);
printf("Channel scan range: [%u , %u]\n", CHANNEL_MIN, CHANNEL_MAX);
printf("%u samples per channel, interval %u ticks\n",
RSSI_SAMPLES, SAMPLE_INTERVAL);
channel = CHANNEL_MIN;
while(1) {
cmax = RSSI_BASE;
cc2430_rf_channel_set(channel);
clock_delay(200);
for(j = 0; j < RSSI_SAMPLES; j++) {
t0 = RTIMER_NOW();
rssi = RSSIL;
if(rssi > cmax) {
cmax = rssi;
}
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + 25));
}
printf("%u [%3d]: ", channel, cmax);
for(j = RSSI_BASE; j <= cmax; j++) {
printf("#");
}
printf("\n");
if(channel == CHANNEL_MAX) {
printf("===============\n");
channel = CHANNEL_MIN;
} else {
channel++;
}
etimer_set(&et, SAMPLE_INTERVAL);
PROCESS_YIELD();
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Stub file overriding core/net/netstack.c. What we want to achieve
* here is call netstack_init from main without initialising the RDC,
* MAC and Network layers. It will just turn on the radio instead.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "netstack.h"
/*---------------------------------------------------------------------------*/
void
netstack_init(void)
{
NETSTACK_RADIO.init();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Project specific configuration defines for the sniffer example.
*
* We make sure that the radio driver outputs all packets in hexdump
* format.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#define NETSTACK_CONF_RDC stub_rdc_driver
#define ADC_SENSOR_CONF_ON 0
#define LPM_CONF_MODE 0
#endif /* PROJECT_CONF_H_ */

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Definition of a fake RDC driver to be used with passive
* examples. The code will never send packets and it will never
* push incoming packets up the stack. We do this by defining this
* driver as our RDC. We then drop everything
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "net/mac/mac.h"
#include "net/mac/rdc.h"
/*---------------------------------------------------------------------------*/
static void
send(mac_callback_t sent, void *ptr)
{
if(sent) {
sent(ptr, MAC_TX_OK, 1);
}
}
/*---------------------------------------------------------------------------*/
static void
input(void)
{
}
/*---------------------------------------------------------------------------*/
static int
on(void)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static int
off(int keep_radio_on)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static unsigned short
cca(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
}
/*---------------------------------------------------------------------------*/
const struct rdc_driver stub_rdc_driver = {
"stub-rdc",
init,
send,
input,
on,
off,
cca,
};
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,17 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740
# This example doesn't need code banking so we turn it off
#HAVE_BANKING=1
CONTIKI_PROJECT = event-post
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,132 @@
/* This file demonstrates the interaction between two processes via events.
*
* - "Sensor process": Throws an event periodically. This can be for example a
* sensor value.
* - "Print process" : Waits for events from "Sensor" and prints a message when
* an event occurs (e.g. prints the sensor value)
*
* This example is derived from the contiki code examples for the WSN430
* (SensTools - Inria: http://senstools.gforge.inria.fr/)
*
* Author: George Oikonomou <G.Oikonomou@lboro.ac.uk>
*/
#include "contiki.h"
//#include "dev/leds.h"
#include <limits.h>
#include <stdio.h> /* For printf() */
#include "event-post.h"
/* This is our event type */
static process_event_t event_data_ready;
/*---------------------------------------------------------------------------*/
/* Declare the two processes here */
PROCESS(sensor_process, "Sensor process");
PROCESS(print_process, "Print process");
/* Tell Contiki that we want them to start automatically */
AUTOSTART_PROCESSES(&sensor_process, &print_process);
/*---------------------------------------------------------------------------*/
/* Implementation "Sensor Process" */
PROCESS_THREAD(sensor_process, ev, data)
{
/* static variables to preserve values across consecutive calls of this
* process. */
/* Set an etimer */
static struct etimer timer;
/* And the 'sensor' monitoring variable */
static struct event_struct es;
PROCESS_BEGIN();
/* Set some near-the-limit initial values */
/* signed primitives */
es.s_val = SHRT_MAX-2;
es.i_val = INT_MAX-2;
es.l_val = LONG_MAX-2;
/* sizeof(long long) == sizeof(long) on sensinodes - see other examples*/
es.ll_val = LONG_MAX-2;
/* and some typedef-ed unsigned variables */
es.u8_val = UCHAR_MAX-2;
es.u16_val = USHRT_MAX-2;
es.u32_val = ULONG_MAX-2;
/* allocate the required event */
event_data_ready = process_alloc_event();
/* process_event_t is actually a u_char. What did the OS allocate for us? */
printf("Contiki allocated event ID %d.\r\n", event_data_ready);
/* Set a timer here. We will generate an event every times this timer expires
* etimer_set accepts clock ticks as its 2nd argument.
* CLOCK_CONF_SECOND is the number of ticks per second.
* This CLOCK_CONF_SECOND * N = N seconds */
etimer_set(&timer, CLOCK_CONF_SECOND * 2);
while (1)
{
printf("Sensor process: Wait for timer event...\r\n");
/* Wait on our timer */
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
/* blip */
/* leds_toggle(LEDS_BLUE); */
/* Set the 'sensor' value before throwing the event */
printf("Sensor Process: Incrementing values...\r\n");
es.s_val++;
es.i_val++;
es.l_val++;
es.ll_val++;
es.u8_val++;
es.u16_val++;
es.u32_val++;
/* Post our event.
* N.B. es is declared static.
* Try passing a volatile variable and observe the results... */
printf("Sensor Process: Generating 'Data Ready' event.\r\n");
process_post(&print_process, event_data_ready, &es);
/* reset the timer so we can wait on it again */
etimer_reset(&timer);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/* Implementation of "Print Process" */
PROCESS_THREAD(print_process, ev, data)
{
struct event_struct * sd;
PROCESS_BEGIN();
while (1)
{
/* Stop here and wait until "event_data_ready" occurs */
PROCESS_WAIT_EVENT_UNTIL(ev == event_data_ready);
/* When the event occurs, the incoming data will be stored in
* process_data_t data (careful, this is void *)
*
* Print away...
* es is volatile, we need to set it = data again and dereference it. */
sd = data;
printf("Print Process - Data Ready:\r\n");
printf(" s: %d\r\n", sd->s_val);
printf(" i: %d\r\n", sd->i_val);
printf(" l: %ld\r\n", sd->l_val);
printf(" ll: %lld\r\n", sd->ll_val);
printf(" u8: %u\r\n", sd->u8_val);
printf(" u16: %u\r\n", sd->u16_val);
printf(" u32: %lu\r\n", sd->u32_val);
/* aaaaand back to waiting for the next event */
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,22 @@
/*
* event-post.h
* Header file for the event_post example
*
* Created on: 30 Mar 2010
* Author: George Oikonomou <oikonomou@users.sourceforge.net>
*/
#ifndef EVENT_POST_H_
#define EVENT_POST_H_
struct event_struct {
short s_val;
int i_val;
long l_val;
long long ll_val;
u8_t u8_val;
u16_t u16_val;
u32_t u32_val;
};
#endif /* EVENT_POST_H_ */

View file

@ -0,0 +1,19 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740,PROJECT_CONF_H
# This example won't fit in flash without banking so we turn it on
HAVE_BANKING=1
UIP_CONF_IPV6=1
CONTIKI_SOURCEFILES += sensors-driver.c
CONTIKI_PROJECT = sensors-ipv6
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Project specific configuration defines for the UDP client/server
* example.
*
* We make sure that buttons and ADC are on. We also demonstrate the
* new LPM functionality
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#define BUTTON_SENSOR_CONF_ON 1
#define ADC_SENSOR_CONF_ON 1
#define LPM_CONF_MODE 1
#endif /* PROJECT_CONF_H_ */

View file

@ -0,0 +1,246 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* This file handles the sensor readings and float conversions
* for sensors-example. We keep this separate in order to place it
* to a higher BANK.
*
* Bankable
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki-conf.h"
#include "uip.h" /* for htons / htonl */
#include "dev/leds.h"
#if CONTIKI_TARGET_SENSINODE
#include "dev/sensinode-sensors.h"
#include "sensinode-debug.h"
#endif
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#include <stdio.h>
#include <ctype.h>
#define SENSOR_OK 0
#define SENSOR_ADC_OFF -1
#define SENSOR_UNKNOWN -2
/* Request Bits */
#define REQUEST_BIT_P0_GET 0x0400
#define REQUEST_BIT_L2_SET 0x0200
#define REQUEST_BIT_L1_SET 0x0100
#define REQUEST_BIT_LED_GET 0x0080
#define REQUEST_BIT_ACC 0x0040
#define REQUEST_BIT_BAT 0x0020
#define REQUEST_BIT_VDD 0x0010
#define REQUEST_BIT_TEMP 0x0008
#define REQUEST_BIT_LIGHT 0x0004
#define REQUEST_BIT_UPTIME 0x0002
#define REQUEST_BIT_CHIPID 0x0001
/*---------------------------------------------------------------------------*/
int8_t
read_sensor(char * rs)
{
/* Sensor Values */
static int rv;
static struct sensors_sensor * sensor;
/* Those 3 variables are only used for debugging */
#if DEBUG
static float sane = 0;
static int dec;
static float frac;
#endif
uint16_t r;
uint8_t len = 0;
sensor = sensors_find(ADC_SENSOR);
if (!sensor) {
PRINTF("ADC not found\n");
return (SENSOR_ADC_OFF);
}
/* Fetch the request bytes */
memcpy(&r, rs, 2);
r = uip_ntohs(r);
PRINTF("R=%u\n", r);
if (r & REQUEST_BIT_CHIPID) {
uint8_t chipid = CHIPID;
memcpy(rs + len, &chipid, sizeof(chipid));
len += sizeof(chipid);
PRINTF("ChipID=0x%02x\n", chipid);
}
if (r & REQUEST_BIT_UPTIME) {
/* Uptime */
unsigned long l;
l = uip_htonl(clock_seconds());
memcpy(rs + len, &l, sizeof(l));
len += sizeof(l);
PRINTF("Uptime=%lu secs\n", uip_ntohl(l));
}
if (r & REQUEST_BIT_LIGHT) {
rv = sensor->value(ADC_SENSOR_TYPE_LIGHT);
if(rv != -1) {
#if DEBUG
sane = (float)(rv * 0.4071);
dec = sane;
frac = sane - dec;
PRINTF(" Light=%d.%02ulux (%d)\n", dec, (unsigned int)(frac*100), rv);
#endif
memcpy(rs + len, &rv, sizeof(rv));
len += sizeof(rv);
}
}
if (r & REQUEST_BIT_TEMP) {
rv = sensor->value(ADC_SENSOR_TYPE_TEMP);
if(rv != -1) {
#if DEBUG
sane = ((rv * 0.61065 - 773) / 2.45);
dec = sane;
frac = sane - dec;
PRINTF(" Temp=%d.%02u C (%d)\n", dec, (unsigned int)(frac*100), rv);
#endif
memcpy(rs + len, &rv, sizeof(rv));
len += sizeof(rv);
}
}
if (r & (REQUEST_BIT_VDD | REQUEST_BIT_BAT)) {
/* We want VDD for both cases */
rv = sensor->value(ADC_SENSOR_TYPE_VDD);
if(rv != -1) {
#if DEBUG
sane = rv * 3.75 / 2047;
dec = sane;
frac = sane - dec;
PRINTF("Supply=%d.%02uV (%d)\n", dec, (unsigned int)(frac*100), rv);
/* Store rv temporarily in dec so we can use it for the battery */
dec = rv;
#endif
memcpy(rs + len, &rv, sizeof(rv));
len += sizeof(rv);
}
/* And then carry on with battery if needed */
if (r & REQUEST_BIT_BAT) {
rv = sensor->value(ADC_SENSOR_TYPE_BATTERY);
if(rv != -1) {
#if DEBUG
sane = (11.25 * rv * dec) / (0x7FE002);
dec = sane;
frac = sane - dec;
PRINTF(" Batt.=%d.%02uV (%d)\n", dec, (unsigned int)(frac*100), rv);
#endif
memcpy(rs + len, &rv, sizeof(rv));
len += sizeof(rv);
}
}
}
if (r & REQUEST_BIT_ACC) {
rv = sensor->value(ADC_SENSOR_TYPE_ACC_X);
if(rv != -1) {
#if DEBUG
sane = ((rv * 3.75 / 2047) - 1.65) / 0.44;
dec = sane;
frac = sane - dec;
frac = (frac < 0) ? -frac : frac;
PRINTF(" AccX=");
if(sane < 0 && dec == 0) {
PRINTF('-');
}
PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac*100), rv);
#endif
memcpy(rs + len, &rv, sizeof(rv));
len += sizeof(rv);
}
rv = sensor->value(ADC_SENSOR_TYPE_ACC_Y);
if(rv != -1) {
#if DEBUG
sane = ((rv * 3.75 / 2047) - 1.65) / 0.44;
dec = sane;
frac = sane - dec;
frac = (frac < 0) ? -frac : frac;
PRINTF(" AccY=");
if(sane < 0 && dec == 0) {
PRINTF('-');
}
PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac*100), rv);
#endif
memcpy(rs + len, &rv, sizeof(rv));
len += sizeof(rv);
}
rv = sensor->value(ADC_SENSOR_TYPE_ACC_Z);
if(rv != -1) {
#if DEBUG
sane = ((rv * 3.75 / 2047) - 1.65) / 0.44;
dec = sane;
frac = sane - dec;
frac = (frac < 0) ? -frac : frac;
PRINTF(" AccZ=");
if(sane < 0 && dec == 0) {
PRINTF('-');
}
PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac*100), rv);
#endif
memcpy(rs + len, &rv, sizeof(rv));
len += sizeof(rv);
}
}
if (r & REQUEST_BIT_L1_SET) {
leds_toggle(LEDS_GREEN);
}
if (r & REQUEST_BIT_L2_SET) {
leds_toggle(LEDS_RED);
}
if (r & REQUEST_BIT_LED_GET) {
uint8_t leds = leds_get();
memcpy(rs + len, &leds, sizeof(leds));
len += sizeof(leds);
PRINTF(" LED 2=%u\n", leds);
}
if (r & REQUEST_BIT_P0_GET) {
uint8_t p0 = P0_3;
memcpy(rs + len, &p0, sizeof(p0));
len += sizeof(p0);
}
return len;
}

View file

@ -0,0 +1,154 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Example to demonstrate-test the sensors functionality on
* sensinode/cc2430 devices.
*
* A UDP/IPv6 process waits for requests from a monitoring station
* and responds with sensor values.
*
* The message exchange is based on a custom protocol.
* Check sensors-driver.c for protocol details.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include <string.h>
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#include "dev/watchdog.h"
#include "dev/leds.h"
#include "net/rpl/rpl.h"
#include <stdio.h>
#if CONTIKI_TARGET_SENSINODE
#include "sensinode-debug.h"
#include "dev/sensinode-sensors.h"
#else
#define putstring(s)
#endif
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
#define MAX_PAYLOAD_LEN 120
static struct uip_udp_conn *server_conn;
static char buf[MAX_PAYLOAD_LEN];
static uint16_t len;
#define SERVER_PORT 60000
#define SENSOR_OK 0
#define SENSOR_ADC_OFF 1
#define SENSOR_UNKNOWN 2
int8_t read_sensor(char * rs);
/*---------------------------------------------------------------------------*/
extern const struct sensors_sensor adc_sensor;
/*---------------------------------------------------------------------------*/
PROCESS(udp_server_process, "UDP server process");
AUTOSTART_PROCESSES(&udp_server_process);
/*---------------------------------------------------------------------------*/
static void
tcpip_handler(void)
{
memset(buf, 0, MAX_PAYLOAD_LEN);
if(uip_newdata()) {
len = uip_datalen();
memcpy(buf, uip_appdata, len);
PRINTF("%u bytes from [", len);
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport));
len = read_sensor(buf);
if( len ) {
server_conn->rport = UIP_UDP_BUF->srcport;
uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);
uip_udp_packet_send(server_conn, buf, len);
PRINTF("Sent %u bytes\n", len);
}
/* Restore server connection to allow data from any node */
uip_create_unspecified(&server_conn->ripaddr);
server_conn->rport = 0;
}
return;
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_server_process, ev, data)
{
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
static struct sensors_sensor *b1;
static struct sensors_sensor *b2;
#endif
PROCESS_BEGIN();
putstring("Starting UDP server\n");
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
putstring("Button X: Toggle LED X\n");
#endif
server_conn = udp_new(NULL, UIP_HTONS(0), NULL);
udp_bind(server_conn, UIP_HTONS(SERVER_PORT));
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
b1 = sensors_find(BUTTON_1_SENSOR);
b2 = sensors_find(BUTTON_2_SENSOR);
#endif
while(1) {
PROCESS_YIELD();
if(ev == tcpip_event) {
tcpip_handler();
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
} else if(ev == sensors_event && data != NULL) {
if(data == b1) {
leds_toggle(LEDS_GREEN);
} else if(data == b2) {
leds_toggle(LEDS_RED);
}
#endif /* (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) */
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,17 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740
# This example doesn't need code banking so we turn it off
#HAVE_BANKING=1
CONTIKI_PROJECT = sensors-example
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,372 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Example to demonstrate-test the sensors functionality on
* sensinode/cc2430 devices.
*
* B1 turns L2 on and off.
* B2 reboots the node via the watchdog.
*
* The node takes readings from the various sensors every x seconds and
* prints out the results.
*
* We use floats here to translate the AD conversion results to
* meaningful values. However, our printf does not have %f support so
* we use an ugly hack to print out the value by extracting the integral
* part and then the fractional part. Don't try this at home.
*
* Temperature:
* Math is correct, the sensor needs calibration per device.
* I currently use default values for the math which may result in
* very incorrect values in degrees C.
* See TI Design Note DN102 about the offset calibration.
*
* Supply Voltage (VDD) and Battery Sensor:
* For VDD, math is correct, conversion is correct. See DN101 for details if
* interested.
* Battery reports different values when we run it many times
* in succession. The cause is unknown.
* I am fairly confident that I have captured the connections on the
* device correctly. I am however accepting input/feedback
*
* Light Sensor (Vishay Semiconductors TEPT4400):
* I am uncertain about the math. This needs testing. All I know is
* that 600lux = 0.9V and that the relation is linear. See inline for
* more details
*
* Accelerometer (Freescale Semiconductor MMA7340L):
* Math is correct but the sensor needs calibration. I've not
* attempted one cause the reported values differ per device.
* Place the N740 with the logo facing down to get 1g on the Z axis.
* Place the antenna side facing down to get 1g on the Y axis
* Place the N740 on its longer side while looking at the antenna and
* the D connector. Antenna on the bottom, D connector on the top.
* This should give you 1g on the X axis.
*
* Make sure you enable/disable things in contiki-conf.h
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki.h"
#include "contiki-conf.h"
#include "net/rime.h"
#include "dev/leds.h"
#include "dev/watchdog.h"
#include "lib/random.h"
#if CONTIKI_TARGET_SENSINODE
#include "dev/sensinode-sensors.h"
#else
#include "lib/sensors.h"
#endif
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#if CONTIKI_TARGET_SENSINODE
#include "sensinode-debug.h"
#endif /* CONTIKI_TARGET_SENSINODE */
#define PRINTF(...) printf(__VA_ARGS__)
#else /* DEBUG */
/* We overwrite (read as annihilate) all output functions here */
#define PRINTF(...)
#define putstring(...)
#define putchar(...)
#endif /* DEBUG */
#define SEND_BATTERY_INFO 0
#if SEND_BATTERY_INFO
#include "sensors-example.h"
static void bc_rx(struct broadcast_conn *c, const rimeaddr_t *from) {
return;
}
static const struct broadcast_callbacks bc_cb = { bc_rx };
static struct broadcast_conn bc_con;
#endif
#if BUTTON_SENSOR_ON
extern const struct sensors_sensor button_1_sensor, button_2_sensor;
#endif
/*---------------------------------------------------------------------------*/
PROCESS(sensors_test_process, "Sensor Test Process");
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
PROCESS(buttons_test_process, "Button Test Process");
AUTOSTART_PROCESSES(&sensors_test_process, &buttons_test_process);
#else
AUTOSTART_PROCESSES(&sensors_test_process);
#endif
/*---------------------------------------------------------------------------*/
#if BUTTON_SENSOR_ON
PROCESS_THREAD(buttons_test_process, ev, data)
{
struct sensors_sensor *sensor;
PROCESS_BEGIN();
while (1) {
PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event);
/* If we woke up after a sensor event, inform what happened */
sensor = (struct sensors_sensor *)data;
if(sensor == &button_1_sensor) {
leds_toggle(LEDS_GREEN);
} else if(sensor == &button_2_sensor) {
watchdog_reboot();
}
}
PROCESS_END();
}
#endif
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(sensors_test_process, ev, data)
{
static struct etimer et;
#if SEND_BATTERY_INFO
/* Node Time */
static struct sensor_data sd;
#endif
/* Sensor Values */
static int rv;
static struct sensors_sensor * sensor;
static float sane = 0;
static int dec;
static float frac;
#if SEND_BATTERY_INFO
PROCESS_EXITHANDLER(broadcast_close(&bc_con);)
#endif
PROCESS_BEGIN();
putstring("========================\n");
putstring("Starting Sensor Example.\n");
putstring("========================\n");
#if SEND_BATTERY_INFO
broadcast_open(&bc_con, BATTERY_RIME_CHANNEL, &bc_cb);
#endif
/* Set an etimer. We take sensor readings when it expires and reset it. */
etimer_set(&et, CLOCK_SECOND * 2);
while (1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
/*
* Request some ADC conversions
* Return value -1 means sensor not available or turned off in conf
*/
sensor = sensors_find(ADC_SENSOR);
if (sensor) {
putstring("------------------\n");
leds_on(LEDS_RED);
/*
* Temperature:
* Using 1.25V ref. voltage (1250mV).
* Typical Voltage at 0°C : 743 mV
* Typical Co-efficient : 2.45 mV/°C
* Offset at 25°C : 30 (this varies and needs calibration)
*
* Thus, at 12bit resolution:
*
* ADC x 1250 / 2047 - (743 + 30) 0.61065 x ADC - 773
* T = ------------------------------ ~= ------------------- °C
* 2.45 2.45
*/
rv = sensor->value(ADC_SENSOR_TYPE_TEMP);
if(rv != -1) {
sane = ((rv * 0.61065 - 773) / 2.45);
dec = sane;
frac = sane - dec;
PRINTF(" Temp=%d.%02u C (%d)\n", dec, (unsigned int)(frac*100), rv);
}
/*
* Accelerometer: Freescale Semiconductor MMA7340L
* Using 1.25V ref. voltage.
* Sensitivity: 0.44 mV/g in ±3g mode.
* 0.1175 mV/g in ±11g mode.
* Typical 0g Vout = 1.65V (both modes, Vdd=3.3V, T=25°C)
* ADC Input Voltage is 1/3 Accelerometer Output Voltage
*
* +3g -> 2.97V Acc Out -> 0.9900V ADC Input -> 1621
* +1g -> 2.09V Acc Out -> 0.6967V ADC Input -> 1141
* 0g -> 1.65V Acc Out -> 0.5500V ADC Input -> 901
* -1g -> 1.21V Acc Out -> 0.4033V ADC Input -> 660
* -3g -> 0.33V Acc Out -> 0.1100V ADC Input -> 180
*
* Thus, at 12bit resolution, ±3g mode:
* ADC x 1.25 x 3
* Vout = -------------- V
* 2047
*
* Vout - 0g Vout - 1.65
* Acc = ----------- = ----------- g
* Sensitivity 0.44
*
* Similar calc. for ±11g with 0.1175V increments
*
* This is only valid if you set ACC_SENSOR_CONF_GSEL 0 in contiki-conf.h
*/
rv = sensor->value(ADC_SENSOR_TYPE_ACC_X);
if(rv != -1) {
sane = ((rv * 3.75 / 2047) - 1.65) / 0.44;
dec = sane;
frac = sane - dec;
frac = (frac < 0) ? -frac : frac;
/*
* This will fail for numbers like -0.xyz (since there is no such thing
* as -0. We manually add a minus sign in the printout if sane is neg
* and dec is 0.
* This is the wrong way to do it...
*/
putstring(" AccX=");
if(sane < 0 && dec == 0) {
putchar('-');
}
PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac*100), rv);
}
rv = sensor->value(ADC_SENSOR_TYPE_ACC_Y);
if(rv != -1) {
sane = ((rv * 3.75 / 2047) - 1.65) / 0.44;
dec = sane;
frac = sane - dec;
frac = (frac < 0) ? -frac : frac;
putstring(" AccY=");
if(sane < 0 && dec == 0) {
putchar('-');
}
PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac*100), rv);
}
rv = sensor->value(ADC_SENSOR_TYPE_ACC_Z);
if(rv != -1) {
sane = ((rv * 3.75 / 2047) - 1.65) / 0.44;
dec = sane;
frac = sane - dec;
frac = (frac < 0) ? -frac : frac;
putstring(" AccZ=");
if(sane < 0 && dec == 0) {
putchar('-');
}
PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac*100), rv);
}
/*
* Light: Vishay Semiconductors TEPT4400
* Using 1.25V ref. voltage.
* For 600 Lux illuminance, the sensor outputs 1mA current (0.9V ADC In)
* 600 lux = 1mA output => 1473 ADC value at 12 bit resolution)
*
* Thus, at 12bit resolution:
* 600 x 1.25 x ADC
* Lux = ---------------- ~= ADC * 0.4071
* 2047 x 0.9
*/
rv = sensor->value(ADC_SENSOR_TYPE_LIGHT);
if(rv != -1) {
sane = (float)(rv * 0.4071);
dec = sane;
frac = sane - dec;
PRINTF(" Light=%d.%02ulux (%d)\n", dec, (unsigned int)(frac*100), rv);
}
/*
* Power Supply Voltage.
* Using 1.25V ref. voltage.
* AD Conversion on VDD/3
*
* Thus, at 12bit resolution:
*
* ADC x 1.25 x 3
* Supply = -------------- V
* 2047
*/
rv = sensor->value(ADC_SENSOR_TYPE_VDD);
#if SEND_BATTERY_INFO
sd.vdd = rv;
#endif
if(rv != -1) {
sane = rv * 3.75 / 2047;
dec = sane;
frac = sane - dec;
PRINTF("Supply=%d.%02uV (%d)\n", dec, (unsigned int)(frac*100), rv);
/* Store rv temporarily in dec so we can use it for the battery */
dec = rv;
}
/*
* Battery Voltage - Only 2/3 of the actual voltage reach the ADC input
* Using 1.25V ref. voltage would result in 2047 AD conversions all the
* time since ADC-in would be gt 1.25. We thus use AVDD_SOC as ref.
*
* Thus, at 12bit resolution (assuming VDD is 3.3V):
*
* ADC x 3.3 x 3 ADC x 4.95
* Battery = ------------- = ---------- V
* 2047 x 2 2047
*
* Replacing the 3.3V with an ADC reading of the actual VDD would yield
* better accuracy. See monitor-node.c for an example.
*
* 3 x ADC x VDD x 3.75 ADC x VDD x 11.25
* Battery = -------------------- = ----------------- V
* 2 x 2047 x 2047 0x7FE002
*
*/
rv = sensor->value(ADC_SENSOR_TYPE_BATTERY);
if(rv != -1) {
/* Instead of hard-coding 3.3 here, use the latest VDD (stored in dec)
* (slightly inaccurate still, but better than crude 3.3) */
sane = (11.25 * rv * dec) / (0x7FE002);
dec = sane;
frac = sane - dec;
PRINTF(" Batt.=%d.%02uV (%d)\n", dec, (unsigned int)(frac*100), rv);
#if SEND_BATTERY_INFO
sd.bat = rv;
packetbuf_copyfrom(&sd, sizeof(sd));
broadcast_send(&bc_con);
#endif
}
leds_off(LEDS_RED);
}
etimer_reset(&et);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Header file for the sensors example. Must be included by the
* sensing node as well as the monitor node.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef SENSORSTEST_H_
#define SENSORSTEST_H_
#define BATTERY_RIME_CHANNEL 222
/* This is what our PDU looks like */
struct sensor_data {
int vdd;
int bat;
};
#endif /* SENSORSTEST_H_ */

View file

@ -0,0 +1,13 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740
CONTIKI_PROJECT = flash
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,268 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
*
* Example demonstrating the flash memory functionality on
* sensinode N740s
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki.h"
#include "dev/leds.h"
#include "cc2430_sfr.h"
#include "8051def.h"
#include "dev/m25p16.h"
#include "dev/n740.h"
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#include "sensinode-debug.h"
#define PRINTF(...) printf(__VA_ARGS__)
#define PUTBIN(b) putbin(b)
#else
#define PRINTF(...)
#define PUTBIN(b)
#endif
static struct m25p16_rdid id;
#define USE_SECTOR 0x10
#define MAX_READ_CHUNK 10
static uint8_t r_addr[3]; /* Read address: {USE_SECTOR, 0, 0} */
static uint8_t d_buf[MAX_READ_CHUNK];
static uint8_t rv;
static uint8_t counter;
/*---------------------------------------------------------------------------*/
PROCESS(serial_flash_process, "Serial Flash example");
AUTOSTART_PROCESSES(&serial_flash_process);
/*---------------------------------------------------------------------------*/
static void
rdsr()
{
rv = 0;
n740_analog_deactivate();
rv = m25p16_rdsr();
n740_analog_activate();
PRINTF("RDSR: ");
putbin(rv);
PRINTF("\n");
}
/*---------------------------------------------------------------------------*/
static void
rdid()
{
uint8_t i;
memset(&id, 0, sizeof(struct m25p16_rdid));
n740_analog_deactivate();
m25p16_rdid(&id);
n740_analog_activate();
PRINTF("RDID: 0x%02x\n", id.man_id);
PRINTF("Type: 0x%02x\n", id.mem_type);
PRINTF("Size: 0x%02x\n", id.mem_size);
PRINTF("ULen: 0x%02x\n", id.uid_len);
PRINTF(" UID:");
for(i = 0; i < id.uid_len; i++) {
PRINTF(" %02x", id.uid[i]);
}
PRINTF("\n");
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(serial_flash_process, ev, data)
{
static struct etimer et;
uint8_t i;
PROCESS_BEGIN();
PRINTF("Start\n");
memset(r_addr, 0, 3);
r_addr[0] = USE_SECTOR;
counter = 1;
while(1) {
/* Delay */
etimer_set(&et, CLOCK_SECOND * 2);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
leds_on(LEDS_GREEN);
if(counter == 0) {
n740_analog_deactivate();
rv = m25p16_rdsr();
n740_analog_activate();
/* If counter==0, we started Bulk Erasing earlier. Check if we still are */
if(rv & M25P16_SR_WIP) {
PRINTF("Yield [%02x]\n", rv);
} else {
counter = 1;
}
}
if(counter) {
/*
* Take us out of Deep Power Down - On first power-on, the device will
* go to stand by mode (which is not DP). However, we drop to DP at the
* end of every loop. RES must be 0x14. This is the old style signature
* and is only still there for backward compatibility.
*/
n740_analog_deactivate();
rv = m25p16_res_res();
n740_analog_activate();
PRINTF(" RES: 0x%02x\n", rv);
n740_analog_deactivate();
rv = M25P16_WIP();
n740_analog_activate();
PRINTF("========\n");
memset(d_buf, 0, MAX_READ_CHUNK);
/*
* Read Device ID: Return values must be:
* man_id: 0x20 (Numonyx)
* mem_type: 0x20
* mem_size: 0x15 (2 ^ 0x15 bytes = 2MB)
* uid_len: number of bytes in UID
* uid: Either all zeroes or a customized factory data content
* */
rdid();
/* Check the value of our Status Register (SR) */
rdsr();
/* Enable Write: Set Bit 1 in the SR to 1 (bit WEL) */
PRINTF("WREN\n");
n740_analog_deactivate();
m25p16_wren();
n740_analog_activate();
/* Confirm: SR & 0x02 must be 1 */
rdsr();
/* Disable the WEL bit */
PRINTF("WRDI\n");
n740_analog_deactivate();
m25p16_wrdi();
n740_analog_activate();
/* Confirm: SR & 0x02 must be 0 */
rdsr();
/* Write something to the SR. We don't need to explicitly set WEL, wrsr()
* will do it for us. When the cycle ends, WEL will go low */
PRINTF("WRSR\n");
n740_analog_deactivate();
/* For instance, let's protect sector 31 (that's the highest one) */
m25p16_wrsr(M25P16_SR_BP0);
/*
* While this is running, WEL should remain high and WIP (bit 0) should
* also be high. When this ends, WIP and WEL will go low.
*
* While the write is in ongoing, we can still read the SR to check the
* cycle's progress
*/
while(M25P16_WIP());
n740_analog_activate();
/* Confirm: SR & 0x02 must be 0 */
rdsr();
/* Read MAX_READ_CHUNK bytes from Page 0x000000 */
memset(d_buf, 0, MAX_READ_CHUNK);
n740_analog_deactivate();
m25p16_read(r_addr, d_buf, MAX_READ_CHUNK);
n740_analog_activate();
PRINTF("READ:");
for(i = 0; i < MAX_READ_CHUNK; i++) {
PRINTF(" %02x", d_buf[i]);
}
PRINTF("\n");
/* Write MAX_READ_CHUNK bytes to the same Page */
PRINTF("WRITE\n");
for(i = 0; i < MAX_READ_CHUNK; i++) {
d_buf[i] = i;
}
n740_analog_deactivate();
/* We don't need to wren() explicitly, pp() will do that for us */
m25p16_pp(r_addr, d_buf, MAX_READ_CHUNK);
/* Wait for the cycle */
while(M25P16_WIP());
/* Trash our data buffer */
memset(d_buf, 0, MAX_READ_CHUNK);
PRINTF("ERASE\n");
n740_analog_deactivate();
/* Bulk erase every 4 loops, sector erase otherwise */
/* Bulk Erase: This takes a few seconds so we can't really block on it.
* It'd be a bad thing to do and the watchdog would bark anyway.
* Bulk Erase will only be accepted if all SR_BP[2:0] == 0 */
if((counter % 4) == 0) {
m25p16_wrsr(0);
while(M25P16_WIP());
m25p16_be();
counter = 0;
} else {
m25p16_se(USE_SECTOR);
while(M25P16_WIP());
/* Drop to Deep Power Down */
m25p16_dp();
counter ++;
}
n740_analog_activate();
}
leds_off(LEDS_GREEN);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,16 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N601,PROJECT_CONF_H
PROJECT_SOURCEFILES += stub-rdc.c
CONTIKI_PROJECT = sniffer
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,14 @@
A very simple sniffer for sensinode devices.
The cc2430 RF driver supports outputting all captured packets in hexdump
format. We turn this on, and turn everything else off. We use a stub RDC
driver to make sure no incoming packet ever goes up the stack and no packet is
ever sent out.
We only initialise the radio driver instead of the entire stack by over-riding
the default netstack.c with the one in this directory.
You can then pipe the sniffer's output to the n601-cap util, which will convert
the hexdumps to pcap format, which can in turn be piped to wireshark. This is
handy if we want live capture of the lowpan traffic from wireshark. See the
README in n601-cap for more details

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Stub file overriding core/net/netstack.c. What we want to achieve
* here is call netstack_init from main without initialising the RDC,
* MAC and Network layers. It will just turn on the radio instead.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "netstack.h"
/*---------------------------------------------------------------------------*/
void
netstack_init(void)
{
NETSTACK_RADIO.init();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Project specific configuration defines for the sniffer example.
*
* We make sure that the radio driver outputs all packets in hexdump
* format.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#define CC2430_RF_CONF_HEXDUMP 1
#define CC2430_RF_CONF_AUTOACK 0
#define NETSTACK_CONF_RDC stub_rdc_driver
#define ADC_SENSOR_CONF_ON 0
#define LPM_CONF_MODE 0
#endif /* PROJECT_CONF_H_ */

View file

@ -0,0 +1,54 @@
/*
* 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.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "cc2430_sfr.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
/*---------------------------------------------------------------------------*/
PROCESS(sniffer_process, "Sniffer process");
AUTOSTART_PROCESSES(&sniffer_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(sniffer_process, ev, data)
{
PROCESS_BEGIN();
PRINTF("Sniffer started\n");
/* Turn off cc2430 Address Recognition - We need to accept all frames */
MDMCTRL0H &= ~0x08;
PROCESS_EXIT();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Definition of a fake RDC driver to be used with passive
* examples. The sniffer will never send packets and it will never
* push incoming packets up the stack. We do this by defining this
* driver as our RDC. We then drop everything
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "net/mac/mac.h"
#include "net/mac/rdc.h"
/*---------------------------------------------------------------------------*/
static void
send(mac_callback_t sent, void *ptr)
{
if(sent) {
sent(ptr, MAC_TX_OK, 1);
}
}
/*---------------------------------------------------------------------------*/
static void
input(void)
{
}
/*---------------------------------------------------------------------------*/
static int
on(void)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static int
off(int keep_radio_on)
{
return keep_radio_on;
}
/*---------------------------------------------------------------------------*/
static unsigned short
cca(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
}
/*---------------------------------------------------------------------------*/
const struct rdc_driver stub_rdc_driver = {
"stub-rdc",
init,
send,
input,
on,
off,
cca,
};
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,123 @@
/**
* \file
* Tests related to clocks and timers
*
* This is clock_test.c plus a small addition by George Oikonomou
* (Loughborough University)in order to test the rtimer
*
* \author
* Zach Shelby <zach@sensinode.com> (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net> (rtimer code)
*
*/
#include "contiki.h"
#include "sys/clock.h"
#include "sys/rtimer.h"
#include "dev/leds.h"
#include <stdio.h>
/*---------------------------------------------------------------------------*/
#define TEST_CLOCK_DELAY 1
#define TEST_RTIMER 1
#define TEST_ETIMER 1
#define TEST_CLOCK_SECONDS 1
/*---------------------------------------------------------------------------*/
PROCESS(clock_test_process, "Clock test process");
AUTOSTART_PROCESSES(&clock_test_process);
/*---------------------------------------------------------------------------*/
#if TEST_RTIMER
void
rt_callback(struct rtimer *t, void *ptr) {
printf("Task called at %u\n", RTIMER_NOW());
}
#endif
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(clock_test_process, ev, data)
{
static struct etimer et;
#if TEST_CLOCK_DELAY
static clock_time_t start_count, end_count, diff;
#endif
#if TEST_CLOCK_SECONDS
static unsigned long sec;
#endif
#if TEST_ETIMER
static clock_time_t count;
#endif
#if TEST_RTIMER
uint16_t rt_now, rt_for;
static struct rtimer rt;
#endif
static uint8_t i;
PROCESS_BEGIN();
#if TEST_CLOCK_DELAY
printf("Clock delay test (10 x (10,000xi) cycles):\n");
i = 1;
while(i < 6) {
start_count = clock_time();
clock_delay(10000 * i);
end_count = clock_time();
diff = end_count - start_count;
printf("Delayed %u = %u ticks = ~%u ms\n", 10000 * i, diff, diff * 8);
i++;
}
#endif
#if TEST_RTIMER
printf("Rtimer Test (10 x 1s):\n");
i = 0;
while(i < 10) {
etimer_set(&et, 2*CLOCK_SECOND);
puts("=======================");
rt_now = RTIMER_NOW();
rt_for = rt_now + RTIMER_SECOND;
printf("%Now=%u - For=%u\n", rt_now, rt_for);
if (rtimer_set(&rt, rt_for, 1,
(void (*)(struct rtimer *, void *))rt_callback, NULL) != RTIMER_OK) {
printf("Error setting\n");
}
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
i++;
}
#endif
#if TEST_ETIMER
printf("Clock tick and etimer test (10 x 1s):\n");
i = 0;
while(i < 10) {
etimer_set(&et, CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
etimer_reset(&et);
count = clock_time();
printf("%u ticks\n", count);
leds_toggle(LEDS_RED);
i++;
}
#endif
#if TEST_CLOCK_SECONDS
printf("Clock seconds test (10 x 5s):\n");
i = 0;
while(i < 10) {
etimer_set(&et, 5 * CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
etimer_reset(&et);
sec = clock_seconds();
printf("%u seconds\n", (u16_t) sec);
leds_toggle(LEDS_GREEN);
i++;
}
#endif
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,19 @@
ifndef TARGET
TARGET=sensinode
endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740,PROJECT_CONF_H
# This example won't fit in flash without banking so we turn it on
HAVE_BANKING=1
UIP_CONF_IPV6=1
CONTIKI_SOURCEFILES += ping6.c
CONTIKI_PROJECT = client server
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,212 @@
/*
* 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.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include <string.h>
#include "dev/leds.h"
#if CONTIKI_TARGET_SENSINODE
#include "dev/sensinode-sensors.h"
#include "sensinode-debug.h"
#else
#define putstring(s)
#define puthex(s)
#define putchar(s)
#endif
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#define SEND_INTERVAL 2 * CLOCK_SECOND
#define MAX_PAYLOAD_LEN 40
static char buf[MAX_PAYLOAD_LEN];
/* Our destinations and udp conns. One link-local and one global */
#define LOCAL_CONN_PORT 3001
static struct uip_udp_conn *l_conn;
#if UIP_CONF_ROUTER
#define GLOBAL_CONN_PORT 3002
static struct uip_udp_conn *g_conn;
#endif
/*---------------------------------------------------------------------------*/
PROCESS(udp_client_process, "UDP client process");
#if BUTTON_SENSOR_ON
PROCESS_NAME(ping6_process);
AUTOSTART_PROCESSES(&udp_client_process, &ping6_process);
#else
AUTOSTART_PROCESSES(&udp_client_process);
#endif
/*---------------------------------------------------------------------------*/
static void
tcpip_handler(void)
{
leds_on(LEDS_GREEN);
if(uip_newdata()) {
putstring("0x");
puthex(uip_datalen());
putstring(" bytes response=0x");
puthex((*(uint16_t *) uip_appdata) >> 8);
puthex((*(uint16_t *) uip_appdata) & 0xFF);
putchar('\n');
}
leds_off(LEDS_GREEN);
return;
}
/*---------------------------------------------------------------------------*/
static void
timeout_handler(void)
{
static int seq_id;
struct uip_udp_conn * this_conn;
leds_on(LEDS_RED);
memset(buf, 0, MAX_PAYLOAD_LEN);
seq_id++;
#if UIP_CONF_ROUTER
/* evens / odds */
if(seq_id & 0x01) {
this_conn = l_conn;
} else {
this_conn = g_conn;
}
#else
this_conn = l_conn;
#endif
PRINTF("Client to: ");
PRINT6ADDR(&this_conn->ripaddr);
memcpy(buf, &seq_id, sizeof(seq_id));
PRINTF(" Remote Port %u,", UIP_HTONS(this_conn->rport));
PRINTF(" (msg=0x%04x), %u bytes\n", *(uint16_t *) buf, sizeof(seq_id));
#if SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION
uip_udp_packet_send(this_conn, buf, UIP_APPDATA_SIZE);
#else /* SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION */
uip_udp_packet_send(this_conn, buf, sizeof(seq_id));
#endif /* SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION */
leds_off(LEDS_RED);
}
/*---------------------------------------------------------------------------*/
static void
print_local_addresses(void)
{
int i;
uint8_t state;
PRINTF("Client IPv6 addresses:\n");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state
== ADDR_PREFERRED)) {
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
if (state == ADDR_TENTATIVE) {
uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
}
PRINTF(" state: %u.\n", uip_ds6_if.addr_list[i].state);
}
}
return;
}
/*---------------------------------------------------------------------------*/
#if UIP_CONF_ROUTER
static void
set_global_address(void)
{
uip_ipaddr_t ipaddr;
uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
}
#endif /* UIP_CONF_ROUTER */
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_client_process, ev, data)
{
static struct etimer et;
uip_ipaddr_t ipaddr;
PROCESS_BEGIN();
PRINTF("UDP client process started\n");
#if UIP_CONF_ROUTER
set_global_address();
#endif
print_local_addresses();
uip_ip6addr(&ipaddr,0xfe80,0,0,0,0x0215,0x2000,0x0002,0x0302);
/* new connection with remote host */
l_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL);
if(!l_conn) {
PRINTF("udp_new l_conn error.\n");
}
udp_bind(l_conn, UIP_HTONS(LOCAL_CONN_PORT));
PRINTF("Link-Local connection with ");
PRINT6ADDR(&l_conn->ripaddr);
PRINTF(" local/remote port %u/%u\n",
UIP_HTONS(l_conn->lport), UIP_HTONS(l_conn->rport));
#if UIP_CONF_ROUTER
uip_ip6addr(&ipaddr,0x2001,0x630,0x301,0x6453,0x0215,0x2000,0x0002,0x0302);
g_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL);
if(!g_conn) {
PRINTF("udp_new g_conn error.\n");
}
udp_bind(g_conn, UIP_HTONS(GLOBAL_CONN_PORT));
PRINTF("Global connection with ");
PRINT6ADDR(&g_conn->ripaddr);
PRINTF(" local/remote port %u/%u\n",
UIP_HTONS(g_conn->lport), UIP_HTONS(g_conn->rport));
#endif
etimer_set(&et, SEND_INTERVAL);
while(1) {
PROCESS_YIELD();
if(etimer_expired(&et)) {
timeout_handler();
etimer_restart(&et);
} else if(ev == tcpip_event) {
tcpip_handler();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,147 @@
/*
* 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.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include <string.h>
#include <stdio.h>
#if CONTIKI_TARGET_SENSINODE
#include "dev/sensinode-sensors.h"
#include "sensinode-debug.h"
#endif
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15])
#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",lladdr->addr[0], lladdr->addr[1], lladdr->addr[2], lladdr->addr[3],lladdr->addr[4], lladdr->addr[5])
#else
#define PRINTF(...)
#define PRINT6ADDR(addr)
#endif
#define PING6_NB 5
#define PING6_DATALEN 16
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
static struct etimer ping6_periodic_timer;
static u8_t count = 0;
static u16_t addr[8];
static uip_ipaddr_t dest_addr;
PROCESS(ping6_process, "PING6 process");
/*---------------------------------------------------------------------------*/
static void
ping6handler()
{
if(count < PING6_NB) {
UIP_IP_BUF->vtc = 0x60;
UIP_IP_BUF->tcflow = 1;
UIP_IP_BUF->flow = 0;
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &dest_addr);
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST;
UIP_ICMP_BUF->icode = 0;
/* set identifier and sequence number to 0 */
memset((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
/* put one byte of data */
memset((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN,
count, PING6_DATALEN);
uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN + PING6_DATALEN;
UIP_IP_BUF->len[0] = (u8_t)((uip_len - 40) >> 8);
UIP_IP_BUF->len[1] = (u8_t)((uip_len - 40) & 0x00FF);
UIP_ICMP_BUF->icmpchksum = 0;
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
PRINTF("Echo Request to");
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
PRINTF("from");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF("\n");
UIP_STAT(++uip_stat.icmp.sent);
tcpip_ipv6_output();
count++;
etimer_set(&ping6_periodic_timer, 3 * CLOCK_SECOND);
} else {
count = 0;
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(ping6_process, ev, data)
{
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
static struct sensors_sensor * btn;
#endif
PROCESS_BEGIN();
PRINTF("ping6 running.\n");
PRINTF("Button 1: 5 pings 16 byte payload.\n");
uip_ip6addr(&dest_addr,0x2001,0x470,0x55,0,0x0215,0x2000,0x0002,0x0302);
count = 0;
/* Check if we have buttons */
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
btn = sensors_find(BUTTON_1_SENSOR);
#endif
while(1) {
PROCESS_YIELD();
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
if(ev == sensors_event) {
if(data == btn && count == 0) {
ping6handler();
}
}
#endif
if(etimer_expired(&ping6_periodic_timer)) {
ping6handler();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*
* This file is part of the Contiki operating system.
*
* $Id$
*/
/**
* \file
* Project specific configuration defines for the UDP client/server
* example.
*
* We just turn on buttons
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#define BUTTON_SENSOR_CONF_ON 1
#endif /* PROJECT_CONF_H_ */

View file

@ -0,0 +1,197 @@
/*
* 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.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include <string.h>
#define DEBUG DEBUG_PRINT
#include "net/uip-debug.h"
#include "dev/watchdog.h"
#include "dev/leds.h"
#include "net/rpl/rpl.h"
#if CONTIKI_TARGET_SENSINODE
#include "dev/sensinode-sensors.h"
#include "sensinode-debug.h"
#else
#define putstring(s)
#endif
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
#define MAX_PAYLOAD_LEN 120
static struct uip_udp_conn *server_conn;
static char buf[MAX_PAYLOAD_LEN];
static uint16_t len;
#if UIP_CONF_ROUTER
static uip_ipaddr_t ipaddr;
#endif
#define SERVER_REPLY 1
/* Should we act as RPL root? */
#define SERVER_RPL_ROOT 1
/*---------------------------------------------------------------------------*/
extern const struct sensors_sensor adc_sensor;
/*---------------------------------------------------------------------------*/
PROCESS(udp_server_process, "UDP server process");
AUTOSTART_PROCESSES(&udp_server_process);
/*---------------------------------------------------------------------------*/
static void
tcpip_handler(void)
{
memset(buf, 0, MAX_PAYLOAD_LEN);
if(uip_newdata()) {
leds_on(LEDS_RED);
len = uip_datalen();
memcpy(buf, uip_appdata, len);
PRINTF("%u bytes from [", len, *(uint16_t *)buf);
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF("]:%u", UIP_HTONS(UIP_UDP_BUF->srcport));
PRINTF(" V=%u", *buf);
PRINTF(" I=%u", *(buf + 1));
PRINTF(" T=%u", *(buf + 2));
PRINTF(" Val=%u\n", *(uint16_t *)(buf + 3));
#if SERVER_REPLY
uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);
server_conn->rport = UIP_UDP_BUF->srcport;
uip_udp_packet_send(server_conn, buf, len);
/* Restore server connection to allow data from any node */
uip_create_unspecified(&server_conn->ripaddr);
server_conn->rport = 0;
#endif
}
leds_off(LEDS_RED);
PRINTF("sent\n");
return;
}
/*---------------------------------------------------------------------------*/
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON && (DEBUG==DEBUG_PRINT))
static void
print_stats()
{
PRINTF("tl=%lu, ts=%lu, bs=%lu, bc=%lu\n",
rimestats.toolong, rimestats.tooshort, rimestats.badsynch, rimestats.badcrc);
PRINTF("llrx=%lu, lltx=%lu, rx=%lu, tx=%lu\n",
rimestats.llrx, rimestats.lltx, rimestats.rx, rimestats.tx);
}
#else
#define print_stats()
#endif
/*---------------------------------------------------------------------------*/
static void
print_local_addresses(void)
{
int i;
uint8_t state;
PRINTF("Server IPv6 addresses:\n");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state
== ADDR_PREFERRED)) {
PRINTF(" ");
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF("\n");
if (state == ADDR_TENTATIVE) {
uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
}
}
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_server_process, ev, data)
{
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
static struct sensors_sensor *b1;
static struct sensors_sensor *b2;
#endif
#if SERVER_RPL_ROOT
rpl_dag_t *dag;
#endif
PROCESS_BEGIN();
putstring("Starting UDP server\n");
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
putstring("Button 1: Print RIME stats\n");
putstring("Button 2: Reboot\n");
#endif
#if SERVER_RPL_ROOT
uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
print_local_addresses();
dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &uip_ds6_get_global(ADDR_PREFERRED)->ipaddr);
if(dag != NULL) {
uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0);
rpl_set_prefix(dag, &ipaddr, 64);
PRINTF("Created a new RPL dag with ID: ");
PRINT6ADDR(&dag->dag_id);
PRINTF("\n");
}
#endif /* SERVER_RPL_ROOT */
server_conn = udp_new(NULL, UIP_HTONS(0), NULL);
udp_bind(server_conn, UIP_HTONS(3000));
PRINTF("Listen port: 3000, TTL=%u\n", server_conn->ttl);
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
b1 = sensors_find(BUTTON_1_SENSOR);
b2 = sensors_find(BUTTON_2_SENSOR);
#endif
while(1) {
PROCESS_YIELD();
if(ev == tcpip_event) {
tcpip_handler();
#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON)
} else if(ev == sensors_event && data != NULL) {
if(data == b1) {
print_stats();
} else if(data == b2) {
watchdog_reboot();
}
#endif /* (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) */
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/