Merge branch 'contiki' into osd

This commit is contained in:
harald42 2016-02-25 08:18:55 +01:00
commit 98e4451518
311 changed files with 14993 additions and 18471 deletions

2
.gitignore vendored
View file

@ -61,7 +61,6 @@ tools/cooja/apps/avrora/lib/cooja_avrora.jar
tools/cooja/apps/collect-view/cooja-collect-view.jar
# sdcc build artifacts
contiki-sensinode.lib
contiki-cc2530dk.lib
*.ihx
*.hex
@ -70,7 +69,6 @@ contiki-cc2530dk.lib
*.omf
*.cdb
*.banks
*.sensinode
*.cc2530dk
# VC++ build artifacts

View file

@ -44,9 +44,9 @@ before_script:
## in Ubuntu >= 14.04, but this external PPA is needed for 12.04.
## Install srecord
- if [ ${BUILD_ARCH:-0} = arm-aapcs ] ; then
sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded &&
sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa &&
sudo apt-get -qq update &&
sudo apt-get -qq install gcc-arm-none-eabi srecord &&
sudo apt-get -qq install gcc-arm-embedded=5-2015q4-1~precise1 srecord &&
arm-none-eabi-gcc --version ;
fi

View file

@ -0,0 +1,3 @@
ipso-objects_src = ipso-temperature.c ipso-button.c ipso-leds-control.c \
ipso-light-control.c ipso-objects.c
CFLAGS += -DWITH_IPSO=1

View file

@ -0,0 +1,163 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO button as a digital input
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "contiki.h"
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "er-coap-engine.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#if PLATFORM_HAS_BUTTON
#include "dev/button-sensor.h"
PROCESS(ipso_button_process, "ipso-button");
#endif /* PLATFORM_HAS_BUTTON */
static int input_state = 0;
static int polarity = 0;
static int32_t counter = 0;
static int32_t edge_selection = 3;
static int32_t debounce_time = 10;
/*---------------------------------------------------------------------------*/
static int
read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
int value;
if(polarity == 0) {
value = input_state ? 1 : 0;
} else {
value = input_state ? 0 : 1;
}
PRINTF("Read button state (polarity=%d, state=%d): %d\n",
polarity, input_state, value);
return ctx->writer->write_boolean(ctx, outbuf, outsize, value);
}
/*---------------------------------------------------------------------------*/
static int
reset_counter(lwm2m_context_t *ctx, const uint8_t *arg, size_t len,
uint8_t *outbuf, size_t outlen)
{
counter = 0;
return 0;
}
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(button_resources,
LWM2M_RESOURCE_CALLBACK(5500, { read_state, NULL, NULL }),
LWM2M_RESOURCE_INTEGER_VAR(5501, &counter),
LWM2M_RESOURCE_BOOLEAN_VAR(5502, &polarity),
LWM2M_RESOURCE_INTEGER_VAR(5503, &debounce_time),
LWM2M_RESOURCE_INTEGER_VAR(5504, &edge_selection),
LWM2M_RESOURCE_CALLBACK(5505, { NULL, NULL, reset_counter }),
LWM2M_RESOURCE_STRING(5751, "Button")
);
LWM2M_INSTANCES(button_instances,
LWM2M_INSTANCE(0, button_resources));
LWM2M_OBJECT(button, 3200, button_instances);
/*---------------------------------------------------------------------------*/
void
ipso_button_init(void)
{
/* register this device and its handlers - the handlers automatically
sends in the object to handle */
lwm2m_engine_register_object(&button);
#if PLATFORM_HAS_BUTTON
process_start(&ipso_button_process, NULL);
#endif /* PLATFORM_HAS_BUTTON */
}
/*---------------------------------------------------------------------------*/
#if PLATFORM_HAS_BUTTON
PROCESS_THREAD(ipso_button_process, ev, data)
{
static struct etimer timer;
int32_t time;
PROCESS_BEGIN();
SENSORS_ACTIVATE(button_sensor);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == sensors_event && data == &button_sensor) {
if(!input_state) {
input_state = 1;
counter++;
if((edge_selection & 2) != 0) {
lwm2m_object_notify_observers(&button, "/0/5500");
}
lwm2m_object_notify_observers(&button, "/0/5501");
time = (debounce_time * CLOCK_SECOND / 1000);
if(time < 1) {
time = 1;
}
etimer_set(&timer, (clock_time_t)time);
}
} else if(ev == PROCESS_EVENT_TIMER && data == &timer) {
if(!input_state) {
/* Button is not in pressed state */
} else if(button_sensor.value(0) != 0) {
/* Button is still pressed */
etimer_reset(&timer);
} else {
input_state = 0;
if((edge_selection & 1) != 0) {
lwm2m_object_notify_observers(&button, "/0/5500");
}
}
}
}
PROCESS_END();
}
#endif /* PLATFORM_HAS_BUTTON */
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,236 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO Light Control for LEDs
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "er-coap-engine.h"
#include "dev/leds.h"
#include <stdint.h>
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#if LEDS_ALL & LEDS_BLUE || LEDS_ALL & LEDS_RED || LEDS_ALL & LEDS_BLUE
#define LEDS_CONTROL_NUMBER (((LEDS_ALL & LEDS_BLUE) ? 1 : 0) + ((LEDS_ALL & LEDS_RED) ? 1 : 0) + ((LEDS_ALL & LEDS_GREEN) ? 1 : 0))
#else
#define LEDS_CONTROL_NUMBER 1
#endif
struct led_state {
unsigned long last_on_time;
uint32_t total_on_time;
uint8_t is_on;
uint8_t led_value;
};
static struct led_state states[LEDS_CONTROL_NUMBER];
static lwm2m_instance_t leds_control_instances[LEDS_CONTROL_NUMBER];
/*---------------------------------------------------------------------------*/
static int
read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
return ctx->writer->write_boolean(ctx, outbuf, outsize,
states[idx].is_on ? 1 : 0);
}
/*---------------------------------------------------------------------------*/
static int
write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int value;
size_t len;
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
len = ctx->reader->read_boolean(ctx, inbuf, insize, &value);
if(len > 0) {
if(value) {
if(!states[idx].is_on) {
states[idx].is_on = 1;
states[idx].last_on_time = clock_seconds();
#if PLATFORM_HAS_LEDS
leds_on(states[idx].led_value);
#endif /* PLATFORM_HAS_LEDS */
}
} else if(states[idx].is_on) {
states[idx].total_on_time += clock_seconds() - states[idx].last_on_time;
states[idx].is_on = 0;
#if PLATFORM_HAS_LEDS
leds_off(states[idx].led_value);
#endif /* PLATFORM_HAS_LEDS */
}
} else {
PRINTF("IPSO leds control - ignored illegal write to on/off\n");
}
return len;
}
/*---------------------------------------------------------------------------*/
static char *
get_color(int value) {
switch(value) {
case LEDS_GREEN:
return "Green";
case LEDS_RED:
return "Red";
case LEDS_BLUE:
return "Blue";
}
return "None";
}
static int
read_color(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
char *value;
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
value = get_color(states[idx].led_value);
return ctx->writer->write_string(ctx, outbuf, outsize,
value, strlen(value));
}
/*---------------------------------------------------------------------------*/
static int
read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
unsigned long now;
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
if(states[idx].is_on) {
/* Update the on time */
now = clock_seconds();
states[idx].total_on_time += now - states[idx].last_on_time;
states[idx].last_on_time = now;
}
return ctx->writer->write_int(ctx, outbuf, outsize,
(int32_t)states[idx].total_on_time);
}
/*---------------------------------------------------------------------------*/
static int
write_on_time(lwm2m_context_t *ctx,
const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int32_t value;
size_t len;
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
len = ctx->reader->read_int(ctx, inbuf, insize, &value);
if(len > 0 && value == 0) {
PRINTF("IPSO leds control - reset On Time\n");
states[idx].total_on_time = 0;
if(states[idx].is_on) {
states[idx].last_on_time = clock_seconds();
}
} else {
PRINTF("IPSO leds control - ignored illegal write to On Time\n");
}
return len;
}
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(leds_control_resources,
LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }),
LWM2M_RESOURCE_CALLBACK(5706, { read_color, NULL, NULL }),
LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL })
);
LWM2M_OBJECT(leds_control, 3311, leds_control_instances);
/*---------------------------------------------------------------------------*/
static int
bit_no(int bit)
{
int i;
for(i = 0; i < 8; i++) {
if(LEDS_ALL & (1 << i)) {
if(bit == 0) {
/* matching bit */
return 1 << i;
} else {
/* matching but used */
bit--;
}
}
}
return 0;
}
void
ipso_leds_control_init(void)
{
lwm2m_instance_t template = LWM2M_INSTANCE(0, leds_control_resources);
int i;
/* Initialize the instances */
for(i = 0; i < LEDS_CONTROL_NUMBER; i++) {
leds_control_instances[i] = template;
leds_control_instances[i].id = i;
states[i].led_value = bit_no(i);
}
/* register this device and its handlers - the handlers automatically
sends in the object to handle */
lwm2m_engine_register_object(&leds_control);
PRINTF("IPSO leds control initialized with %u instances\n",
LEDS_CONTROL_NUMBER);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,202 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO Light Control
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "ipso-objects.h"
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#ifdef IPSO_LIGHT_CONTROL
extern const struct ipso_objects_actuator IPSO_LIGHT_CONTROL;
#endif /* IPSO_LIGHT_CONTROL */
/*---------------------------------------------------------------------------*/
static unsigned long last_on_time;
static uint32_t total_on_time;
static int dim_level = 0;
static uint8_t is_on = 0;
/*---------------------------------------------------------------------------*/
static int
read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
return ctx->writer->write_boolean(ctx, outbuf, outsize, is_on ? 1 : 0);
}
/*---------------------------------------------------------------------------*/
static int
write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int value;
size_t len;
len = ctx->reader->read_boolean(ctx, inbuf, insize, &value);
if(len > 0) {
if(value) {
if(!is_on) {
is_on = 1;
last_on_time = clock_seconds();
}
} else {
if(is_on) {
total_on_time += clock_seconds() - last_on_time;
is_on = 0;
}
}
#ifdef IPSO_LIGHT_CONTROL
if(IPSO_LIGHT_CONTROL.set_on) {
IPSO_LIGHT_CONTROL.set_on(value);
} else if(IPSO_LIGHT_CONTROL.set_dim_level) {
dim_level = value ? 100 : 0;
IPSO_LIGHT_CONTROL.set_dim_level(dim_level);
}
#endif /* IPSO_LIGHT_CONTROL */
}
return len;
}
/*---------------------------------------------------------------------------*/
static int
read_dim(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
return ctx->writer->write_int(ctx, outbuf, outsize, dim_level);
}
/*---------------------------------------------------------------------------*/
static int
write_dim(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int32_t value;
size_t len;
len = ctx->reader->read_int(ctx, inbuf, insize, &value);
if(len > 0) {
if(value < 0) {
value = 0;
} else if(value > 100) {
value = 100;
}
dim_level = value;
if(value > 0) {
if(!is_on) {
is_on = 1;
last_on_time = clock_seconds();
}
} else {
if(is_on) {
total_on_time += clock_seconds() - last_on_time;
is_on = 0;
}
}
#ifdef IPSO_LIGHT_CONTROL
if(IPSO_LIGHT_CONTROL.set_dim_level) {
IPSO_LIGHT_CONTROL.set_dim_level(dim_level);
} else if(IPSO_LIGHT_CONTROL.set_on) {
IPSO_LIGHT_CONTROL.set_on(is_on);
}
#endif /* IPSO_LIGHT_CONTROL */
}
return len;
}
/*---------------------------------------------------------------------------*/
static int
read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
unsigned long now;
if(is_on) {
/* Update the on time */
now = clock_seconds();
total_on_time += now - last_on_time;
last_on_time = now;
}
return ctx->writer->write_int(ctx, outbuf, outsize, (int32_t)total_on_time);
}
/*---------------------------------------------------------------------------*/
static int
write_on_time(lwm2m_context_t *ctx,
const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int32_t value;
size_t len;
len = ctx->reader->read_int(ctx, inbuf, insize, &value);
if(len > 0 && value == 0) {
total_on_time = 0;
if(is_on) {
last_on_time = clock_seconds();
}
}
return len;
}
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(light_control_resources,
LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }),
LWM2M_RESOURCE_CALLBACK(5851, { read_dim, write_dim, NULL }),
LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL }),
);
LWM2M_INSTANCES(light_control_instances,
LWM2M_INSTANCE(0, light_control_resources));
LWM2M_OBJECT(light_control, 3311, light_control_instances);
/*---------------------------------------------------------------------------*/
void
ipso_light_control_init(void)
{
#ifdef IPSO_LIGHT_CONTROL
if(IPSO_LIGHT_CONTROL.init) {
IPSO_LIGHT_CONTROL.init();
}
if(IPSO_LIGHT_CONTROL.is_on) {
is_on = IPSO_LIGHT_CONTROL.is_on();
}
if(IPSO_LIGHT_CONTROL.get_dim_level) {
dim_level = IPSO_LIGHT_CONTROL.get_dim_level();
if(dim_level > 0 && IPSO_LIGHT_CONTROL.is_on == NULL) {
is_on = 1;
}
}
#endif /* IPSO_LIGHT_CONTROL */
last_on_time = clock_seconds();
lwm2m_engine_register_object(&light_control);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Implementation of the IPSO Objects
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "contiki.h"
#include "ipso-objects.h"
/*---------------------------------------------------------------------------*/
void
ipso_objects_init(void)
{
/* initialize any relevant object for the IPSO Objects */
#ifdef IPSO_TEMPERATURE
ipso_temperature_init();
#endif
#if PLATFORM_HAS_BUTTON
ipso_button_init();
#endif
#ifdef IPSO_LIGHT_CONTROL
ipso_light_control_init();
#elif PLATFORM_HAS_LEDS
ipso_leds_control_init();
#endif
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup ipso-objects An implementation of IPSO Objects
* @{
*
* This application is an implementation of IPSO Objects for
* OMA Lightweight M2M.
*/
/**
* \file
* Header file for the Contiki IPSO Objects for OMA LWM2M
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef IPSO_OBJECTS_H_
#define IPSO_OBJECTS_H_
#include "contiki-conf.h"
void ipso_temperature_init(void);
void ipso_button_init(void);
void ipso_light_control_init(void);
void ipso_leds_control_init(void);
/* the init function to register the IPSO objects */
void ipso_objects_init(void);
struct ipso_objects_actuator {
/**
* \brief Initialize the driver.
*/
void (* init)(void);
/**
* \brief Check if the actuator is on or off.
*
* \return Zero if the actuator is off and non-zero otherwise.
*/
int (* is_on)(void);
/**
* \brief Set the actuator to on or off.
*
* \param onoroff Zero to set the actuator to off and non-zero otherwise.
* \return Zero if ok and a non-zero error code otherwise.
*/
int (* set_on)(int onoroff);
/**
* \brief Set the actuator to on or off.
*
* \param onoroff Zero to set the actuator to off and non-zero otherwise.
* \return Zero if ok and a non-zero error code otherwise.
*/
int (* get_dim_level)(void);
/**
* \brief Set the dim level of the actuator.
*
* \param level The dim level between 0% and 100%.
* \return Zero if ok and a non-zero error code otherwise.
*/
int (* set_dim_level)(int level);
};
struct ipso_objects_sensor {
/**
* \brief Initialize the driver.
*/
void (* init)(void);
/**
* \brief Read the sensor value in 1/1000 units.
*
* \param value A pointer to the variable to hold the sensor value.
* \return Zero if ok and a non-zero error code otherwise.
*/
int (* read_value)(int32_t *value);
};
#endif /* IPSO_OBJECTS_H_ */
/**
* @}
* @}
*/

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO Temperature
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <stdint.h>
#include "ipso-objects.h"
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "er-coap-engine.h"
#ifdef IPSO_TEMPERATURE
extern const struct ipso_objects_sensor IPSO_TEMPERATURE;
#endif /* IPSO_TEMPERATURE */
#ifndef IPSO_TEMPERATURE_MIN
#define IPSO_TEMPERATURE_MIN (-50 * LWM2M_FLOAT32_FRAC)
#endif
#ifndef IPSO_TEMPERATURE_MAX
#define IPSO_TEMPERATURE_MAX (80 * LWM2M_FLOAT32_FRAC)
#endif
static struct ctimer periodic_timer;
static int32_t min_temp;
static int32_t max_temp;
static int read_temp(int32_t *value);
/*---------------------------------------------------------------------------*/
static int
temp(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
int32_t value;
if(read_temp(&value)) {
return ctx->writer->write_float32fix(ctx, outbuf, outsize,
value, LWM2M_FLOAT32_BITS);
}
return 0;
}
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(temperature_resources,
/* Temperature (Current) */
LWM2M_RESOURCE_CALLBACK(5700, { temp, NULL, NULL }),
/* Units */
LWM2M_RESOURCE_STRING(5701, "Celcius"),
/* Min Range Value */
LWM2M_RESOURCE_FLOATFIX(5603, IPSO_TEMPERATURE_MIN),
/* Max Range Value */
LWM2M_RESOURCE_FLOATFIX(5604, IPSO_TEMPERATURE_MAX),
/* Min Measured Value */
LWM2M_RESOURCE_FLOATFIX_VAR(5601, &min_temp),
/* Max Measured Value */
LWM2M_RESOURCE_FLOATFIX_VAR(5602, &max_temp),
);
LWM2M_INSTANCES(temperature_instances,
LWM2M_INSTANCE(0, temperature_resources));
LWM2M_OBJECT(temperature, 3303, temperature_instances);
/*---------------------------------------------------------------------------*/
static int
read_temp(int32_t *value)
{
#ifdef IPSO_TEMPERATURE
int32_t temp;
if(IPSO_TEMPERATURE.read_value == NULL ||
IPSO_TEMPERATURE.read_value(&temp) != 0) {
return 0;
}
/* Convert milliCelsius to fix float */
*value = (temp * LWM2M_FLOAT32_FRAC) / 1000;
if(*value < min_temp) {
min_temp = *value;
lwm2m_object_notify_observers(&temperature, "/0/5601");
}
if(*value > max_temp) {
max_temp = *value;
lwm2m_object_notify_observers(&temperature, "/0/5602");
}
return 1;
#else /* IPSO_TEMPERATURE */
return 0;
#endif /* IPSO_TEMPERATURE */
}
/*---------------------------------------------------------------------------*/
static void
handle_periodic_timer(void *ptr)
{
static int32_t last_value = IPSO_TEMPERATURE_MIN;
int32_t v;
/* Only notify when the value has changed since last */
if(read_temp(&v) && v != last_value) {
last_value = v;
lwm2m_object_notify_observers(&temperature, "/0/5700");
}
ctimer_reset(&periodic_timer);
}
/*---------------------------------------------------------------------------*/
void
ipso_temperature_init(void)
{
int32_t v;
min_temp = IPSO_TEMPERATURE_MAX;
max_temp = IPSO_TEMPERATURE_MIN;
#ifdef IPSO_TEMPERATURE
if(IPSO_TEMPERATURE.init) {
IPSO_TEMPERATURE.init();
}
#endif /* IPSO_TEMPERATURE */
/* register this device and its handlers - the handlers automatically
sends in the object to handle */
lwm2m_engine_register_object(&temperature);
/* update temp and min/max + notify any listeners */
read_temp(&v);
ctimer_set(&periodic_timer, CLOCK_SECOND * 10, handle_periodic_timer, NULL);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -45,6 +45,7 @@
#define JSON_TYPE_PAIR ':'
#define JSON_TYPE_PAIR_NAME 'N' /* for N:V pairs */
#define JSON_TYPE_STRING '"'
#define JSON_TYPE_UINT 'U'
#define JSON_TYPE_INT 'I'
#define JSON_TYPE_NUMBER '0'
#define JSON_TYPE_ERROR 0
@ -56,6 +57,14 @@
#define JSON_TYPE_CALLBACK 'C'
/* integer pointer types */
#define JSON_TYPE_S8PTR 'b'
#define JSON_TYPE_U8PTR 'B'
#define JSON_TYPE_S16PTR 'w'
#define JSON_TYPE_U16PTR 'W'
#define JSON_TYPE_S32PTR 'd'
#define JSON_TYPE_U32PTR 'D'
enum {
JSON_ERROR_OK,
JSON_ERROR_SYNTAX,

View file

@ -79,16 +79,11 @@ jsontree_write_string(const struct jsontree_context *js_ctx, const char *text)
}
/*---------------------------------------------------------------------------*/
void
jsontree_write_int(const struct jsontree_context *js_ctx, int value)
jsontree_write_uint(const struct jsontree_context *js_ctx, unsigned int value)
{
char buf[10];
int l;
if(value < 0) {
js_ctx->putchar('-');
value = -value;
}
l = sizeof(buf) - 1;
do {
buf[l--] = '0' + (value % 10);
@ -101,6 +96,17 @@ jsontree_write_int(const struct jsontree_context *js_ctx, int value)
}
/*---------------------------------------------------------------------------*/
void
jsontree_write_int(const struct jsontree_context *js_ctx, int value)
{
if(value < 0) {
js_ctx->putchar('-');
value = -value;
}
jsontree_write_uint(js_ctx, value);
}
/*---------------------------------------------------------------------------*/
void
jsontree_setup(struct jsontree_context *js_ctx, struct jsontree_value *root,
int (* putchar)(int))
{
@ -132,6 +138,9 @@ jsontree_print_next(struct jsontree_context *js_ctx)
{
struct jsontree_value *v;
int index;
#if JSONTREE_PRETTY
int indent;
#endif
v = js_ctx->values[js_ctx->depth];
@ -145,10 +154,19 @@ jsontree_print_next(struct jsontree_context *js_ctx)
index = js_ctx->index[js_ctx->depth];
if(index == 0) {
js_ctx->putchar(v->type);
#if JSONTREE_PRETTY
js_ctx->putchar('\n');
#endif
}
if(index >= o->count) {
#if JSONTREE_PRETTY
js_ctx->putchar('\n');
indent = js_ctx->depth;
while (indent--) {
js_ctx->putchar(' ');
js_ctx->putchar(' ');
}
#endif
js_ctx->putchar(v->type + 2);
/* Default operation: back up one level! */
break;
@ -156,12 +174,26 @@ jsontree_print_next(struct jsontree_context *js_ctx)
if(index > 0) {
js_ctx->putchar(',');
#if JSONTREE_PRETTY
js_ctx->putchar('\n');
#endif
}
#if JSONTREE_PRETTY
indent = js_ctx->depth + 1;
while (indent--) {
js_ctx->putchar(' ');
js_ctx->putchar(' ');
}
#endif
if(v->type == JSON_TYPE_OBJECT) {
jsontree_write_string(js_ctx,
((struct jsontree_object *)o)->pairs[index].name);
js_ctx->putchar(':');
#if JSONTREE_PRETTY
js_ctx->putchar(' ');
#endif
ov = ((struct jsontree_object *)o)->pairs[index].value;
} else {
ov = o->values[index];
@ -177,6 +209,10 @@ jsontree_print_next(struct jsontree_context *js_ctx)
jsontree_write_string(js_ctx, ((struct jsontree_string *)v)->value);
/* Default operation: back up one level! */
break;
case JSON_TYPE_UINT:
jsontree_write_uint(js_ctx, ((struct jsontree_uint *)v)->value);
/* Default operation: back up one level! */
break;
case JSON_TYPE_INT:
jsontree_write_int(js_ctx, ((struct jsontree_int *)v)->value);
/* Default operation: back up one level! */
@ -198,6 +234,30 @@ jsontree_print_next(struct jsontree_context *js_ctx)
}
/* Default operation: back up one level! */
break;
case JSON_TYPE_S8PTR:
jsontree_write_int(js_ctx, *((int8_t *)((struct jsontree_ptr *)v)->value));
/* Default operation: back up one level! */
break;
case JSON_TYPE_U8PTR:
jsontree_write_uint(js_ctx, *((uint8_t *)((struct jsontree_ptr *)v)->value));
/* Default operation: back up one level! */
break;
case JSON_TYPE_S16PTR:
jsontree_write_int(js_ctx, *((int16_t *)((struct jsontree_ptr *)v)->value));
/* Default operation: back up one level! */
break;
case JSON_TYPE_U16PTR:
jsontree_write_uint(js_ctx, *((uint16_t *)((struct jsontree_ptr *)v)->value));
/* Default operation: back up one level! */
break;
case JSON_TYPE_S32PTR:
jsontree_write_int(js_ctx, *((int32_t *)((struct jsontree_ptr *)v)->value));
/* Default operation: back up one level! */
break;
case JSON_TYPE_U32PTR:
jsontree_write_uint(js_ctx, *((uint32_t *)((struct jsontree_ptr *)v)->value));
/* Default operation: back up one level! */
break;
}
default:
PRINTF("\nError: Illegal json type:'%c'\n", v->type);

View file

@ -49,6 +49,12 @@
#define JSONTREE_MAX_DEPTH 10
#endif /* JSONTREE_CONF_MAX_DEPTH */
#ifdef JSONTREE_CONF_PRETTY
#define JSONTREE_PRETTY JSONTREE_CONF_PRETTY
#else
#define JSONTREE_PRETTY 0
#endif /* JSONTREE_CONF_PRETTY */
struct jsontree_context {
struct jsontree_value *values[JSONTREE_MAX_DEPTH];
uint16_t index[JSONTREE_MAX_DEPTH];
@ -68,6 +74,11 @@ struct jsontree_string {
const char *value;
};
struct jsontree_uint {
uint8_t type;
unsigned int value;
};
struct jsontree_int {
uint8_t type;
int value;
@ -98,6 +109,11 @@ struct jsontree_array {
struct jsontree_value **values;
};
struct jsontree_ptr {
uint8_t type;
const void *value;
};
#define JSONTREE_STRING(text) {JSON_TYPE_STRING, (text)}
#define JSONTREE_PAIR(name, value) {(name), (struct jsontree_value *)(value)}
#define JSONTREE_CALLBACK(output, set) {JSON_TYPE_CALLBACK, (output), (set)}
@ -130,6 +146,8 @@ void jsontree_reset(struct jsontree_context *js_ctx);
const char *jsontree_path_name(const struct jsontree_context *js_ctx,
int depth);
void jsontree_write_uint(const struct jsontree_context *js_ctx,
unsigned int value);
void jsontree_write_int(const struct jsontree_context *js_ctx, int value);
void jsontree_write_atom(const struct jsontree_context *js_ctx,
const char *text);

View file

@ -0,0 +1,5 @@
oma-lwm2m_src = lwm2m-object.c lwm2m-engine.c \
lwm2m-device.c lwm2m-server.c lwm2m-security.c \
oma-tlv.c oma-tlv-reader.c oma-tlv-writer.c \
lwm2m-plain-text.c
CFLAGS += -DHAVE_OMA_LWM2M=1

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M device
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "lwm2m-device.h"
#include "lwm2m-engine.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
static int32_t time_offset = 0;
/*---------------------------------------------------------------------------*/
static int
read_lwtime(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
return ctx->writer->write_int(ctx, outbuf, outsize,
time_offset + clock_seconds());
}
/*---------------------------------------------------------------------------*/
static int
set_lwtime(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
/* assume that this only read one TLV value */
int32_t lw_time;
size_t len = ctx->reader->read_int(ctx, inbuf, insize, &lw_time);
if(len == 0) {
PRINTF("FAIL: could not read time '%*.s'\n", (int)insize, inbuf);
} else {
PRINTF("Got: time: %*.s => %" PRId32 "\n", (int)insize, inbuf, lw_time);
time_offset = lw_time - clock_seconds();
PRINTF("Write time...%" PRId32 " => offset = %" PRId32 "\n",
lw_time, time_offset);
}
/* return the number of bytes read */
return len;
}
/*---------------------------------------------------------------------------*/
#ifdef PLATFORM_REBOOT
static struct ctimer reboot_timer;
static void
do_the_reboot(void *ptr)
{
PLATFORM_REBOOT();
}
static int
reboot(lwm2m_context_t *ctx, const uint8_t *arg, size_t argsize,
uint8_t *outbuf, size_t outsize)
{
PRINTF("Device will reboot!\n");
ctimer_set(&reboot_timer, CLOCK_SECOND / 2, do_the_reboot, NULL);
return 0;
}
#endif /* PLATFORM_REBOOT */
/*---------------------------------------------------------------------------*/
#ifdef PLATFORM_FACTORY_DEFAULT
static int
factory_reset(lwm2m_context_t *ctx, const uint8_t *arg, size_t arg_size,
uint8_t *outbuf, size_t outsize)
{
PRINTF("Device will do factory default!\n");
PLATFORM_FACTORY_DEFAULT();
return 0;
}
#endif /* PLATFORM_FACTORY_DEFAULT */
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(device_resources,
#ifdef LWM2M_DEVICE_MANUFACTURER
LWM2M_RESOURCE_STRING(0, LWM2M_DEVICE_MANUFACTURER),
#endif /* LWM2M_DEVICE_MANUFACTURER */
#ifdef LWM2M_DEVICE_TYPE
LWM2M_RESOURCE_STRING(17, LWM2M_DEVICE_TYPE),
#endif /* LWM2M_DEVICE_TYPE */
#ifdef LWM2M_DEVICE_MODEL_NUMBER
LWM2M_RESOURCE_STRING(1, LWM2M_DEVICE_MODEL_NUMBER),
#endif /* LWM2M_DEVICE_MODEL_NUMBER */
#ifdef LWM2M_DEVICE_SERIAL_NO
LWM2M_RESOURCE_STRING(2, LWM2M_DEVICE_SERIAL_NO),
#endif /* LWM2M_DEVICE_SERIAL_NO */
#ifdef LWM2M_DEVICE_FIRMWARE_VERSION
LWM2M_RESOURCE_STRING(3, LWM2M_DEVICE_FIRMWARE_VERSION),
#endif /* LWM2M_DEVICE_FIRMWARE_VERSION */
#ifdef PLATFORM_REBOOT
LWM2M_RESOURCE_CALLBACK(4, { NULL, NULL, reboot }),
#endif /* PLATFORM_REBOOT */
#ifdef PLATFORM_FACTORY_DEFAULT
LWM2M_RESOURCE_CALLBACK(5, { NULL, NULL, factory_reset }),
#endif /* PLATFORM_FACTORY_DEFAULT */
/* Current Time */
LWM2M_RESOURCE_CALLBACK(13, { read_lwtime, set_lwtime, NULL }),
);
LWM2M_INSTANCES(device_instances, LWM2M_INSTANCE(0, device_resources));
LWM2M_OBJECT(device, 3, device_instances);
/*---------------------------------------------------------------------------*/
void
lwm2m_device_init(void)
{
/**
* Register this device and its handlers - the handlers
* automatically sends in the object to handle.
*/
PRINTF("*** Init lwm2m-device\n");
lwm2m_engine_register_object(&device);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Header file for the Contiki OMA LWM2M device
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef LWM2M_DEVICE_H_
#define LWM2M_DEVICE_H_
#include "contiki-conf.h"
#ifndef LWM2M_DEVICE_MODEL_NUMBER
#ifdef BOARD_STRING
#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING
#endif /* BOARD_STRING */
#endif /* LWM2M_DEVICE_MODEL_NUMBER */
#ifndef LWM2M_DEVICE_FIRMWARE_VERSION
#define LWM2M_DEVICE_FIRMWARE_VERSION CONTIKI_VERSION_STRING
#endif /* LWM2M_DEVICE_FIRMWARE_VERSION */
void lwm2m_device_init(void);
#endif /* LWM2M_DEVICE_H_ */
/** @} */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Header file for the Contiki OMA LWM2M engine
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef LWM2M_ENGINE_H
#define LWM2M_ENGINE_H
#include "lwm2m-object.h"
#define LWM2M_FLOAT32_BITS 10
#define LWM2M_FLOAT32_FRAC (1L << LWM2M_FLOAT32_BITS)
/* LWM2M / CoAP Content-Formats */
typedef enum {
LWM2M_TEXT_PLAIN = 1541,
LWM2M_TLV = 1542,
LWM2M_JSON = 1543,
LWM2M_OPAQUE = 1544
} lwm2m_content_format_t;
void lwm2m_engine_init(void);
void lwm2m_engine_register_default_objects(void);
void lwm2m_engine_use_bootstrap_server(int use);
void lwm2m_engine_use_registration_server(int use);
void lwm2m_engine_register_with_server(const uip_ipaddr_t *server, uint16_t port);
void lwm2m_engine_register_with_bootstrap_server(const uip_ipaddr_t *server, uint16_t port);
const lwm2m_object_t *lwm2m_engine_get_object(uint16_t id);
int lwm2m_engine_register_object(const lwm2m_object_t *object);
void lwm2m_engine_handler(const lwm2m_object_t *object,
void *request, void *response,
uint8_t *buffer, uint16_t preferred_size,
int32_t *offset);
void lwm2m_engine_delete_handler(const lwm2m_object_t *object,
void *request, void *response,
uint8_t *buffer, uint16_t preferred_size,
int32_t *offset);
#endif /* LWM2M_ENGINE_H */
/** @} */

View file

@ -0,0 +1,336 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M object API
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include <string.h>
/*---------------------------------------------------------------------------*/
int
lwm2m_object_is_resource_string(const lwm2m_resource_t *resource)
{
if(resource == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE ||
resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE ||
resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
const uint8_t *
lwm2m_object_get_resource_string(const lwm2m_resource_t *resource,
const lwm2m_context_t *context)
{
if(resource == NULL || context == NULL) {
return NULL;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE) {
return resource->value.string.value;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) {
return *(resource->value.stringvar.var);
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.stringvararr.count) {
return resource->value.stringvararr.var +
resource->value.stringvararr.size * context->object_instance_index;
}
return NULL;
}
/* Not a string */
return NULL;
}
/*---------------------------------------------------------------------------*/
uint16_t
lwm2m_object_get_resource_strlen(const lwm2m_resource_t *resource,
const lwm2m_context_t *context)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE) {
return resource->value.string.len;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) {
return *(resource->value.stringvar.len);
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.stringvararr.count) {
return resource->value.stringvararr.len[context->object_instance_index];
}
return 0;
}
/* Not a string */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_set_resource_string(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
uint16_t len, const uint8_t *string)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) {
if(len > resource->value.stringvar.size) {
/* Too large */
return 0;
}
memcpy(resource->value.stringvar.var, string, len);
*(resource->value.stringvar.len) = len;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.stringvararr.count &&
len <= resource->value.stringvararr.size) {
memcpy(resource->value.stringvararr.var +
resource->value.stringvararr.size * context->object_instance_index,
string, len);
resource->value.stringvararr.len[context->object_instance_index] = len;
return 1;
}
return 0;
}
/* Not a string variable */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_is_resource_int(const lwm2m_resource_t *resource)
{
if(resource == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VALUE ||
resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE ||
resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_get_resource_int(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t *value)
{
if(resource == NULL || context == NULL || value == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VALUE) {
*value = resource->value.integer.value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE) {
*value = *(resource->value.integervar.var);
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.integervararr.count) {
*value = resource->value.integervararr.var[context->object_instance_index];
return 1;
}
return 0;
}
/* Not an integer */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_set_resource_int(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t value)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE) {
*(resource->value.integervar.var) = value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.integervararr.count) {
resource->value.integervararr.var[context->object_instance_index] =
value;
return 1;
}
return 0;
}
/* Not an integer variable */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_is_resource_floatfix(const lwm2m_resource_t *resource)
{
if(resource == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE ||
resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE ||
resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_get_resource_floatfix(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t *value)
{
if(resource == NULL || context == NULL || value == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE) {
*value = resource->value.floatfix.value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE) {
*value = *(resource->value.floatfixvar.var);
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.floatfixvararr.count) {
*value = resource->value.floatfixvararr.var[context->object_instance_index];
return 1;
}
return 0;
}
/* Not an float */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_set_resource_floatfix(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t value)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE) {
*(resource->value.floatfixvar.var) = value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.floatfixvararr.count) {
resource->value.floatfixvararr.var[context->object_instance_index] =
value;
return 1;
}
return 0;
}
/* Not an float variable */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_is_resource_boolean(const lwm2m_resource_t *resource)
{
if(resource == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE ||
resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE ||
resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_get_resource_boolean(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int *value)
{
if(resource == NULL || context == NULL || value == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE) {
*value = resource->value.boolean.value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE) {
*value = *(resource->value.booleanvar.var);
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.booleanvararr.count) {
*value = resource->value.booleanvararr.var[context->object_instance_index];
return 1;
}
return 0;
}
/* Not a boolean */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_set_resource_boolean(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int value)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE) {
*(resource->value.booleanvar.var) = value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.booleanvararr.count) {
resource->value.booleanvararr.var[context->object_instance_index] =
value;
return 1;
}
return 0;
}
/* Not a boolean variable */
return 0;
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,359 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup oma-lwm2m An implementation of OMA LWM2M
* @{
*
* This application is an implementation of OMA Lightweight M2M.
*/
/**
* \file
* Header file for the Contiki OMA LWM2M object API
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef LWM2M_OBJECT_H_
#define LWM2M_OBJECT_H_
#include "rest-engine.h"
#include "er-coap-observe.h"
#define LWM2M_OBJECT_SECURITY_ID 0
#define LWM2M_OBJECT_SERVER_ID 1
#define LWM2M_OBJECT_ACCESS_CONTROL_ID 2
#define LWM2M_OBJECT_DEVICE_ID 3
#define LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID 4
#define LWM2M_OBJECT_FIRMWARE_ID 5
#define LWM2M_OBJECT_LOCATION_ID 6
#define LWM2M_OBJECT_CONNECTIVITY_STATISTICS_ID 7
#define LWM2M_SECURITY_SERVER_URI 0
#define LWM2M_SECURITY_BOOTSTRAP_SERVER 1
#define LWM2M_SECURITY_MODE 2
#define LWM2M_SECURITY_CLIENT_PKI 3
#define LWM2M_SECURITY_SERVER_PKI 4
#define LWM2M_SECURITY_KEY 5
#define LWM2M_SECURITY_SHORT_SERVER_ID 10
/* Pre-shared key mode */
#define LWM2M_SECURITY_MODE_PSK 0
/* Raw Public Key mode */
#define LWM2M_SECURITY_MODE_RPK 1
/* Certificate mode */
#define LWM2M_SECURITY_MODE_CERTIFICATE 2
/* NoSec mode */
#define LWM2M_SECURITY_MODE_NOSEC 3
#define LWM2M_OBJECT_STR_HELPER(x) (uint8_t *) #x
#define LWM2M_OBJECT_STR(x) LWM2M_OBJECT_STR_HELPER(x)
#define LWM2M_OBJECT_PATH_STR_HELPER(x) #x
#define LWM2M_OBJECT_PATH_STR(x) LWM2M_OBJECT_PATH_STR_HELPER(x)
struct lwm2m_reader;
struct lwm2m_writer;
/* Data model for OMA LWM2M objects */
typedef struct lwm2m_context {
uint16_t object_id;
uint16_t object_instance_id;
uint16_t resource_id;
uint8_t object_instance_index;
uint8_t resource_index;
/* TODO - add uint16_t resource_instance_id */
const struct lwm2m_reader *reader;
const struct lwm2m_writer *writer;
} lwm2m_context_t;
/* LWM2M format writer for the various formats supported */
typedef struct lwm2m_writer {
size_t (* write_int)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int32_t value);
size_t (* write_string)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, const char *value, size_t strlen);
size_t (* write_float32fix)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int32_t value, int bits);
size_t (* write_boolean)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int value);
} lwm2m_writer_t;
typedef struct lwm2m_reader {
size_t (* read_int)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int32_t *value);
size_t (* read_string)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, uint8_t *value, size_t strlen);
size_t (* read_float32fix)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int32_t *value, int bits);
size_t (* read_boolean)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int *value);
} lwm2m_reader_t;
typedef struct lwm2m_value_callback {
int (* read)(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen);
int (* write)(lwm2m_context_t *ctx,
const uint8_t *buffer, size_t len,
uint8_t *outbuf, size_t outlen);
int (* exec)(lwm2m_context_t *ctx, const uint8_t *arg, size_t len,
uint8_t *outbuf, size_t outlen);
} lwm2m_value_callback_t;
#define LWM2M_RESOURCE_TYPE_STR_VALUE 1
#define LWM2M_RESOURCE_TYPE_STR_VARIABLE 2
#define LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY 3
#define LWM2M_RESOURCE_TYPE_INT_VALUE 4
#define LWM2M_RESOURCE_TYPE_INT_VARIABLE 5
#define LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY 6
#define LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE 7
#define LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE 8
#define LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY 9
#define LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE 10
#define LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE 11
#define LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY 12
#define LWM2M_RESOURCE_TYPE_CALLBACK 16
#define LWM2M_RESOURCE_TYPE_INSTANCES 17
typedef struct lwm2m_resource {
uint16_t id;
uint8_t type; /* indicate value type and multi-instance resource */
union {
struct {
uint16_t len;
const uint8_t *value;
} string;
struct {
uint16_t size;
uint16_t *len;
uint8_t **var;
} stringvar;
struct {
uint16_t count;
uint16_t size;
/* string var array with counting entries */
uint16_t *len;
uint8_t *var;
} stringvararr;
struct {
int32_t value;
} integer;
struct {
int32_t *var;
} integervar;
struct {
/* used for multiple instances (dynamic) NOTE: this is an index into
the instance so having two instances means that there is need for
allocation of two ints here */
uint16_t count;
int32_t *var; /* used as an array? */
} integervararr;
struct {
int32_t value;
} floatfix;
struct {
int32_t *var;
} floatfixvar;
struct {
uint16_t count;
int32_t *var;
} floatfixvararr;
struct {
int value;
} boolean;
struct {
int *var;
} booleanvar;
struct {
uint16_t count;
int *var;
} booleanvararr;
lwm2m_value_callback_t callback;
/* lwm2m_resource *resources[]; TO BE ADDED LATER*/
} value;
} lwm2m_resource_t;
#define LWM2M_INSTANCE_FLAG_USED 1
typedef struct lwm2m_instance {
uint16_t id;
uint16_t count;
uint16_t flag;
const lwm2m_resource_t *resources;
} lwm2m_instance_t;
typedef struct lwm2m_object {
uint16_t id;
uint16_t count;
const char *path;
resource_t *coap_resource;
lwm2m_instance_t *instances;
} lwm2m_object_t;
#define LWM2M_RESOURCES(name, ...) \
static const lwm2m_resource_t name[] = { __VA_ARGS__ }
#define LWM2M_RESOURCE_STRING(id, s) \
{ id, LWM2M_RESOURCE_TYPE_STR_VALUE, .value.string.len = sizeof(s) - 1, .value.string.value = (uint8_t *) s }
#define LWM2M_RESOURCE_STRING_VAR(id, s, l, v) \
{ id, LWM2M_RESOURCE_TYPE_STR_VARIABLE, .value.stringvar.size = (s), .value.stringvar.len = (l), .value.stringvar.var = (v) }
#define LWM2M_RESOURCE_STRING_VAR_ARR(id, c, s, l, v) \
{ id, LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY, .value.stringvararr.count = c, .value.stringvararr.size = s, .value.stringvararr.len = l, .value.stringvararr.var = (uint8_t *) v }
#define LWM2M_RESOURCE_INTEGER(id, v) \
{ id, LWM2M_RESOURCE_TYPE_INT_VALUE, .value.integer.value = (v) }
#define LWM2M_RESOURCE_INTEGER_VAR(id, v) \
{ id, LWM2M_RESOURCE_TYPE_INT_VARIABLE, .value.integervar.var = (v) }
#define LWM2M_RESOURCE_INTEGER_VAR_ARR(id, c, v) \
{ id, LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY, .value.integervararr.count = (c), .value.integervararr.var = (v) }
#define LWM2M_RESOURCE_FLOATFIX(id, v) \
{ id, LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE, .value.floatfix.value = (v) }
#define LWM2M_RESOURCE_FLOATFIX_VAR(id, v) \
{ id, LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE, .value.floatfixvar.var = (v) }
#define LWM2M_RESOURCE_FLOATFIX_VAR_ARR(id, c, v) \
{ id, LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY, .value.floatfixvararr.count = (c), .value.floatfixvararr.var = (v) }
#define LWM2M_RESOURCE_BOOLEAN(id, v) \
{ id, LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE, .value.boolean.value = (v) }
#define LWM2M_RESOURCE_BOOLEAN_VAR(id, v) \
{ id, LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE, .value.booleanvar.var = (v) }
#define LWM2M_RESOURCE_BOOLEAN_VAR_ARR(id, c, v) \
{ id, LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY, .value.booleanvararr.count = (c), .value.booleanvararr.var = (v) }
#define LWM2M_RESOURCE_CALLBACK(id, ...) \
{ id, LWM2M_RESOURCE_TYPE_CALLBACK, .value.callback = __VA_ARGS__ }
#define LWM2M_INSTANCE(id, resources) \
{ id, sizeof(resources)/sizeof(lwm2m_resource_t), LWM2M_INSTANCE_FLAG_USED, resources }
#define LWM2M_INSTANCE_UNUSED(id, resources) \
{ id, sizeof(resources)/sizeof(lwm2m_resource_t), 0, resources }
#define LWM2M_INSTANCES(name, ...) \
static lwm2m_instance_t name[] = { __VA_ARGS__ }
#define LWM2M_OBJECT(name, id, instances) \
static void lwm2m_get_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \
static void lwm2m_put_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \
static void lwm2m_post_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \
static void lwm2m_delete_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \
static resource_t rest_rsc_##name = { NULL, NULL, HAS_SUB_RESOURCES | IS_OBSERVABLE, NULL, lwm2m_get_h_##name, lwm2m_post_h_##name, lwm2m_put_h_##name, lwm2m_delete_h_##name, { NULL } }; \
static const lwm2m_object_t name = { id, sizeof(instances)/sizeof(lwm2m_instance_t), LWM2M_OBJECT_PATH_STR(id), &rest_rsc_##name, instances}; \
static void lwm2m_get_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \
lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \
static void lwm2m_put_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \
lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \
static void lwm2m_post_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \
lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \
static void lwm2m_delete_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \
lwm2m_engine_delete_handler(&name, request, response, buffer, preferred_size, offset); }
/* how do we register attributes in the above resource here ??? */
int lwm2m_object_is_resource_string(const lwm2m_resource_t *resource);
int lwm2m_object_is_resource_int(const lwm2m_resource_t *resource);
int lwm2m_object_is_resource_floatfix(const lwm2m_resource_t *resource);
int lwm2m_object_is_resource_boolean(const lwm2m_resource_t *resource);
static inline int
lwm2m_object_is_resource_callback(const lwm2m_resource_t *resource)
{
return resource != NULL && resource->type == LWM2M_RESOURCE_TYPE_CALLBACK;
}
const uint8_t *
lwm2m_object_get_resource_string(const lwm2m_resource_t *resource,
const lwm2m_context_t *context);
uint16_t
lwm2m_object_get_resource_strlen(const lwm2m_resource_t *resource,
const lwm2m_context_t *context);
int
lwm2m_object_set_resource_string(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
uint16_t len, const uint8_t *string);
int
lwm2m_object_get_resource_int(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t *value);
int
lwm2m_object_set_resource_int(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t value);
int
lwm2m_object_get_resource_floatfix(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t *value);
int
lwm2m_object_set_resource_floatfix(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t value);
int
lwm2m_object_get_resource_boolean(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int *value);
int
lwm2m_object_set_resource_boolean(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int value);
static inline resource_t *
lwm2m_object_get_coap_resource(const lwm2m_object_t *object)
{
return (resource_t *)object->coap_resource;
}
static inline void
lwm2m_object_notify_observers(const lwm2m_object_t *object, char *path)
{
coap_notify_observers_sub(lwm2m_object_get_coap_resource(object), path);
}
#include "lwm2m-engine.h"
#endif /* LWM2M_OBJECT_H_ */
/**
* @}
* @}
*/

View file

@ -0,0 +1,248 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M plain text reader / writer
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "lwm2m-plain-text.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
size_t
lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len, int32_t *value)
{
int i, neg = 0;
*value = 0;
for(i = 0; i < len; i++) {
if(inbuf[i] >= '0' && inbuf[i] <= '9') {
*value = *value * 10 + (inbuf[i] - '0');
} else if(inbuf[i] == '-' && i == 0) {
neg = 1;
} else {
break;
}
}
if(neg) {
*value = -*value;
}
return i;
}
/*---------------------------------------------------------------------------*/
size_t
lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len,
int32_t *value, int bits)
{
int i, dot = 0, neg = 0;
int32_t counter, integerpart, frac;
integerpart = 0;
counter = 0;
frac = 0;
for(i = 0; i < len; i++) {
if(inbuf[i] >= '0' && inbuf[i] <= '9') {
counter = counter * 10 + (inbuf[i] - '0');
frac = frac * 10;
} else if(inbuf[i] == '.' && dot == 0) {
integerpart = counter;
counter = 0;
frac = 1;
dot = 1;
} else if(inbuf[i] == '-' && i == 0) {
neg = 1;
} else {
break;
}
}
*value = integerpart << bits;
if(frac > 1) {
*value += ((counter << bits) / frac);
}
PRINTF("READ FLOATFIX: \"%.*s\" => int(%ld) frac(%ld) f=%ld Value=%ld\n",
(int)len, (char *)inbuf,
(long)integerpart,
(long)counter,
(long)frac,
(long)*value);
if(neg) {
*value = -*value;
}
return i;
}
/*---------------------------------------------------------------------------*/
size_t
lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen,
int32_t value, int bits)
{
int64_t v;
unsigned long integer_part;
unsigned long frac_part;
int n, o = 0;
if(outlen == 0) {
return 0;
}
if(value < 0) {
*outbuf++ = '-';
outlen--;
o = 1;
value = -value;
}
integer_part = (unsigned long)(value >> bits);
v = value - (integer_part << bits);
v = (v * 100) >> bits;
frac_part = (unsigned long)v;
n = snprintf((char *)outbuf, outlen, "%lu.%02lu", integer_part, frac_part);
if(n < 0 || n >= outlen) {
return 0;
}
return n + o;
}
/*---------------------------------------------------------------------------*/
static size_t
write_boolean(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int value)
{
if(outlen > 0) {
if(value) {
*outbuf = '1';
} else {
*outbuf = '0';
}
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static size_t
write_int(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int32_t value)
{
int n = snprintf((char *)outbuf, outlen, "%ld", (long)value);
if(n < 0 || n >= outlen) {
return 0;
}
return n;
}
/*---------------------------------------------------------------------------*/
static size_t
write_float32fix(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int32_t value, int bits)
{
return lwm2m_plain_text_write_float32fix(outbuf, outlen, value, bits);
}
/*---------------------------------------------------------------------------*/
static size_t
write_string(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
const char *value, size_t stringlen)
{
int n = snprintf((char *)outbuf, outlen, "%.*s", (int) stringlen, value);
if(n < 0 || n >= outlen) {
return 0;
}
return n;
}
/*---------------------------------------------------------------------------*/
const lwm2m_writer_t lwm2m_plain_text_writer = {
write_int,
write_string,
write_float32fix,
write_boolean
};
/*---------------------------------------------------------------------------*/
static size_t
read_int(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int32_t *value)
{
return lwm2m_plain_text_read_int(inbuf, len, value);
}
/*---------------------------------------------------------------------------*/
static size_t
read_string(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
uint8_t *value, size_t stringlen)
{
if(stringlen <= len) {
/* The outbuffer can not contain the full string including ending zero */
return 0;
}
memcpy(value, inbuf, len);
value[len] = '\0';
return len;
}
/*---------------------------------------------------------------------------*/
static size_t
read_float32fix(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int32_t *value, int bits)
{
return lwm2m_plain_text_read_float32fix(inbuf, len, value, bits);
}
/*---------------------------------------------------------------------------*/
static size_t
read_boolean(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int *value)
{
if(len > 0) {
if(*inbuf == '1' || *inbuf == '0') {
*value = *inbuf == '1' ? 1 : 0;
return 1;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
const lwm2m_reader_t lwm2m_plain_text_reader = {
read_int,
read_string,
read_float32fix,
read_boolean
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Header file for the Contiki OMA LWM2M plain text reader / writer
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef LWM2M_PLAIN_TEXT_H_
#define LWM2M_PLAIN_TEXT_H_
#include "lwm2m-object.h"
extern const lwm2m_reader_t lwm2m_plain_text_reader;
extern const lwm2m_writer_t lwm2m_plain_text_writer;
size_t lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len,
int32_t *value);
size_t lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len,
int32_t *value, int bits);
size_t lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen,
int32_t value, int bits);
#endif /* LWM2M_PLAIN_TEXT_H_ */
/** @} */

View file

@ -0,0 +1,112 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M security
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <stdint.h>
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#ifdef LWM2M_CONF_SERVER_MAX_COUNT
#define MAX_COUNT LWM2M_CONF_SERVER_MAX_COUNT
#else
#define MAX_COUNT 2
#endif
/* hoping that we do not get more than 64 bytes... */
#define MAX_SIZE 64
static int32_t bs_arr[MAX_COUNT];
static int32_t secmode_arr[MAX_COUNT];
static int32_t sid_arr[MAX_COUNT];
static char server_uri[MAX_COUNT][MAX_SIZE];
static uint16_t su_len[MAX_COUNT];
static char client_id[MAX_COUNT][MAX_SIZE];
static uint16_t client_id_len[MAX_COUNT];
static char server_id[MAX_COUNT][MAX_SIZE];
static uint16_t server_id_len[MAX_COUNT];
static char psk_key[MAX_COUNT][MAX_SIZE];
static uint16_t psk_key_len[MAX_COUNT];
static lwm2m_instance_t security_instances[MAX_COUNT];
LWM2M_RESOURCES(security_resources,
LWM2M_RESOURCE_STRING_VAR_ARR(0, MAX_COUNT, MAX_SIZE, su_len, server_uri),
LWM2M_RESOURCE_INTEGER_VAR_ARR(1, MAX_COUNT, bs_arr),
LWM2M_RESOURCE_INTEGER_VAR_ARR(2, MAX_COUNT, secmode_arr),
LWM2M_RESOURCE_STRING_VAR_ARR(3, MAX_COUNT, MAX_SIZE, client_id_len, client_id),
LWM2M_RESOURCE_STRING_VAR_ARR(4, MAX_COUNT, MAX_SIZE, server_id_len, server_id),
/* TODO This should not be readable! */
LWM2M_RESOURCE_STRING_VAR_ARR(5, MAX_COUNT, MAX_SIZE, psk_key_len, psk_key),
LWM2M_RESOURCE_INTEGER_VAR_ARR(10, MAX_COUNT, sid_arr)
);
LWM2M_OBJECT(security, 0, security_instances);
/*---------------------------------------------------------------------------*/
void
lwm2m_security_init(void)
{
lwm2m_instance_t template = LWM2M_INSTANCE_UNUSED(0, security_resources);
int i;
/* Initialize the instances */
for(i = 0; i < MAX_COUNT; i++) {
security_instances[i] = template;
security_instances[i].id = i;
}
/**
* Register this device and its handlers - the handlers
* automatically sends in the object to handle.
*/
PRINTF("*** Init lwm2m-security\n");
lwm2m_engine_register_object(&security);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M server
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <stdint.h>
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#ifdef LWM2M_CONF_SERVER_MAX_COUNT
#define MAX_COUNT LWM2M_CONF_SERVER_MAX_COUNT
#else
#define MAX_COUNT 2
#endif
static int32_t sid_arr[MAX_COUNT];
static int32_t lifetime_arr[MAX_COUNT];
static lwm2m_instance_t server_instances[MAX_COUNT];
LWM2M_RESOURCES(server_resources,
LWM2M_RESOURCE_INTEGER_VAR_ARR(0, MAX_COUNT, sid_arr),
LWM2M_RESOURCE_INTEGER_VAR_ARR(1, MAX_COUNT, lifetime_arr),
);
LWM2M_OBJECT(server, 1, server_instances);
/*---------------------------------------------------------------------------*/
void
lwm2m_server_init(void)
{
lwm2m_instance_t template = LWM2M_INSTANCE_UNUSED(0, server_resources);
int i;
/* Initialize the instances */
for(i = 0; i < MAX_COUNT; i++) {
server_instances[i] = template;
server_instances[i].id = i;
}
/**
* Register this device and its handlers - the handlers
* automatically sends in the object to handle
*/
PRINTF("*** Init lwm2m-server\n");
lwm2m_engine_register_object(&server);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M TLV reader
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "oma-tlv-reader.h"
#include "oma-tlv.h"
/*---------------------------------------------------------------------------*/
static size_t
read_int(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int32_t *value)
{
oma_tlv_t tlv;
size_t size;
size = oma_tlv_read(&tlv, inbuf, len);
if(size > 0) {
*value = oma_tlv_get_int32(&tlv);
}
return size;
}
/*---------------------------------------------------------------------------*/
static size_t
read_string(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
uint8_t *value, size_t stringlen)
{
oma_tlv_t tlv;
size_t size;
size = oma_tlv_read(&tlv, inbuf, len);
if(size > 0) {
if(stringlen <= tlv.length) {
/* The outbuffer can not contain the full string including ending zero */
return 0;
}
memcpy(value, tlv.value, tlv.length);
value[tlv.length] = '\0';
}
return size;
}
/*---------------------------------------------------------------------------*/
static size_t
read_float32fix(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int32_t *value, int bits)
{
oma_tlv_t tlv;
size_t size;
size = oma_tlv_read(&tlv, inbuf, len);
if(size > 0) {
oma_tlv_float32_to_fix(&tlv, value, bits);
}
return size;
}
/*---------------------------------------------------------------------------*/
static size_t
read_boolean(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int *value)
{
oma_tlv_t tlv;
size_t size;
size = oma_tlv_read(&tlv, inbuf, len);
if(size > 0) {
*value = oma_tlv_get_int32(&tlv) != 0;
}
return size;
}
/*---------------------------------------------------------------------------*/
const lwm2m_reader_t oma_tlv_reader = {
read_int,
read_string,
read_float32fix,
read_boolean
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \addtogroup oma-lwm2m
* @{ */
/**
* \file
* Header file for the Contiki OMA LWM2M TLV reader
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef OMA_TLV_READER_H_
#define OMA_TLV_READER_H_
#include "lwm2m-object.h"
extern const lwm2m_reader_t oma_tlv_reader;
#endif /* OMA_TLV_READER_H_ */
/** @} */

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M TLV writer
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "oma-tlv.h"
/*---------------------------------------------------------------------------*/
static size_t
write_boolean_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int value)
{
return oma_tlv_write_int32(ctx->resource_id, value != 0 ? 1 : 0,
outbuf, outlen);
}
/*---------------------------------------------------------------------------*/
static size_t
write_int_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int32_t value)
{
return oma_tlv_write_int32(ctx->resource_id, value, outbuf, outlen);
}
/*---------------------------------------------------------------------------*/
static size_t
write_float32fix_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf,
size_t outlen, int32_t value, int bits)
{
return oma_tlv_write_float32(ctx->resource_id, value, bits, outbuf, outlen);
}
/*---------------------------------------------------------------------------*/
static size_t
write_string_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
const char *value, size_t stringlen)
{
oma_tlv_t tlv;
tlv.type = OMA_TLV_TYPE_RESOURCE;
tlv.value = (uint8_t *) value;
tlv.length = (uint32_t) stringlen;
tlv.id = ctx->resource_id;
return oma_tlv_write(&tlv, outbuf, outlen);
}
/*---------------------------------------------------------------------------*/
const lwm2m_writer_t oma_tlv_writer = {
write_int_tlv,
write_string_tlv,
write_float32fix_tlv,
write_boolean_tlv
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \addtogroup oma-lwm2m
* @{ */
/**
* \file
* Header file for the Contiki OMA LWM2M TLV writer
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef OMA_TLV_WRITER_H_
#define OMA_TLV_WRITER_H_
#include "lwm2m-object.h"
extern const lwm2m_writer_t oma_tlv_writer;
#endif /* OMA_TLV_WRITER_H_ */
/** @} */

296
apps/oma-lwm2m/oma-tlv.c Normal file
View file

@ -0,0 +1,296 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M TLV
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <string.h>
#include <stdint.h>
#include "oma-tlv.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
static inline uint8_t
get_len_type(const oma_tlv_t *tlv)
{
if(tlv->length < 8) {
return 0;
} else if(tlv->length < 256) {
return 1;
} else if(tlv->length < 0x10000) {
return 2;
} else {
return 3;
}
}
/*---------------------------------------------------------------------------*/
size_t
oma_tlv_read(oma_tlv_t *tlv, const uint8_t *buffer, size_t len)
{
uint8_t len_type;
uint8_t len_pos = 1;
size_t tlv_len;
tlv->type = (buffer[0] >> 6) & 3;
len_type = (buffer[0] >> 3) & 3;
len_pos = 1 + (((buffer[0] & (1 << 5)) != 0) ? 2 : 1);
tlv->id = buffer[1];
/* if len_pos is larger than two it means that there is more ID to read */
if(len_pos > 2) {
tlv->id = (tlv->id << 8) + buffer[2];
}
if(len_type == 0) {
tlv_len = buffer[0] & 7;
} else {
/* read the length */
tlv_len = 0;
while(len_type > 0) {
tlv_len = tlv_len << 8 | buffer[len_pos++];
len_type--;
}
}
/* and read out the data??? */
tlv->length = tlv_len;
tlv->value = &buffer[len_pos];
return len_pos + tlv_len;
}
/*---------------------------------------------------------------------------*/
size_t
oma_tlv_get_size(const oma_tlv_t *tlv)
{
size_t size;
/* first hdr + len size */
size = 1 + get_len_type(tlv);
/* id size */
size += (tlv->id > 255) ? 2 : 1;
/* and the length */
size += tlv->length;
return size;
}
/*---------------------------------------------------------------------------*/
size_t
oma_tlv_write(const oma_tlv_t *tlv, uint8_t *buffer, size_t len)
{
int pos;
uint8_t len_type;
/* len type is the same as number of bytes required for length */
len_type = get_len_type(tlv);
pos = 1 + len_type;
/* ensure that we do not write too much */
if(len < tlv->length + pos) {
PRINTF("OMA-TLV: Could not write the TLV - buffer overflow.\n");
return 0;
}
/* first type byte in TLV header */
buffer[0] = (tlv->type << 6) |
(tlv->id > 255 ? (1 << 5) : 0) |
(len_type << 3) |
(len_type == 0 ? tlv->length : 0);
pos = 1;
/* The ID */
if(tlv->id > 255) {
buffer[pos++] = (tlv->id >> 8) & 0xff;
}
buffer[pos++] = tlv->id & 0xff;
/* Add length if needed - unrolled loop ? */
if(len_type > 2) {
buffer[pos++] = (tlv->length >> 16) & 0xff;
}
if(len_type > 1) {
buffer[pos++] = (tlv->length >> 8) & 0xff;
}
if(len_type > 0) {
buffer[pos++] = tlv->length & 0xff;
}
/* finally add the value */
memcpy(&buffer[pos], tlv->value, tlv->length);
if(DEBUG) {
int i;
PRINTF("TLV:");
for(i = 0; i < pos + tlv->length; i++) {
PRINTF("%02x", buffer[i]);
}
PRINTF("\n");
}
return pos + tlv->length;
}
/*---------------------------------------------------------------------------*/
int32_t
oma_tlv_get_int32(const oma_tlv_t *tlv)
{
int i;
int32_t value = 0;
/* will probably need to handle MSB as a sign bit? */
for(i = 0; i < tlv->length; i++) {
value = (value << 8) | tlv->value[i];
}
return value;
}
/*---------------------------------------------------------------------------*/
size_t
oma_tlv_write_int32(int16_t id, int32_t value, uint8_t *buffer, size_t len)
{
oma_tlv_t tlv;
size_t tlvlen = 0;
uint8_t buf[4];
int i;
PRINTF("Exporting int32 %d %ld ", id, (long)value);
buf[3] = value & 0xff;
value = value >> 8;
for(i = 1; value > 0 && i < 4; i++) {
buf[3 - i] = value & 0xff;
value = value >> 8;
}
tlvlen = i;
/* export INT as TLV */
PRINTF("len: %zu\n", tlvlen);
tlv.type = OMA_TLV_TYPE_RESOURCE;
tlv.length = tlvlen;
tlv.value = &buf[3 - (tlvlen - 1)];
tlv.id = id;
return oma_tlv_write(&tlv, buffer, len);
}
/*---------------------------------------------------------------------------*/
/* convert fixpoint 32-bit to a IEEE Float in the byte array*/
size_t
oma_tlv_write_float32(int16_t id, int32_t value, int bits,
uint8_t *buffer, size_t len)
{
int i;
int e = 0;
int32_t val = 0;
int32_t v;
uint8_t b[4];
oma_tlv_t tlv;
v = value;
if(v < 0) {
v = -v;
}
while(v > 1) {
val = (val >> 1);
if (v & 1) {
val = val | (1L << 22);
}
v = (v >> 1);
e++;
}
PRINTF("Sign: %d, Fraction: %06lx 0b", value < 0, (long)val);
for(i = 0; i < 23; i++) {
PRINTF("%d", (int)((val >> (22 - i)) & 1));
}
PRINTF("\nExp:%d\n", e);
/* convert to the thing we should have */
e = e - bits + 127;
/* is this the right byte order? */
b[0] = (value < 0 ? 0x80 : 0) | (e >> 1);
b[1] = ((e & 1) << 7) | ((val >> 16) & 0x7f);
b[2] = (val >> 8) & 0xff;
b[3] = val & 0xff;
/* construct the TLV */
tlv.type = OMA_TLV_TYPE_RESOURCE;
tlv.length = 4;
tlv.value = b;
tlv.id = id;
return oma_tlv_write(&tlv, buffer, len);
}
/*---------------------------------------------------------------------------*/
/* convert float to fixpoint */
size_t
oma_tlv_float32_to_fix(const oma_tlv_t *tlv, int32_t *value, int bits)
{
/* TLV needs to be 4 bytes */
int e, i;
int32_t val;
int sign = (tlv->value[0] & 0x80) != 0;
e = ((tlv->value[0] << 1) & 0xff) | (tlv->value[1] >> 7);
val = (((long)tlv->value[1] & 0x7f) << 16) | (tlv->value[2] << 8) | tlv->value[3];
PRINTF("Sign: %d, Fraction: %06lx 0b", val < 0, (long)val);
for(i = 0; i < 23; i++) {
PRINTF("%d", (int)((val >> (22 - i)) & 1));
}
PRINTF("\nExp:%d => %d\n", e, e - 127);
e = e - 127 + bits;
/* e corresponds to the number of times we need to roll the number */
PRINTF("Actual e=%d\n", e);
e = e - 23;
PRINTF("E after sub %d\n", e);
val = val | 1L << 23;
if(e > 0) {
val = val << e;
} else {
val = val >> -e;
}
*value = sign ? -val : val;
return 4;
}
/*---------------------------------------------------------------------------*/
/** @} */

89
apps/oma-lwm2m/oma-tlv.h Normal file
View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \addtogroup oma-lwm2m
* @{ */
/**
* \file
* Header file for the Contiki OMA LWM2M TLV
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef OAM_TLV_H_
#define OAM_TLV_H_
#include "contiki.h"
enum {
OMA_TLV_TYPE_OBJECT_INSTANCE = 0,
OMA_TLV_TYPE_RESOURCE_INSTANCE = 1,
OMA_TLV_TYPE_MULTI_RESOURCE = 2,
OMA_TLV_TYPE_RESOURCE = 3
};
typedef uint8_t oma_tlv_type_t;
typedef enum {
OMA_TLV_LEN_TYPE_NO_LEN = 0,
OMA_TLV_LEN_TYPE_8BIT_LEN = 1,
OMA_TLV_LEN_TYPE_16BIT_LEN = 2,
OMA_TLV_LEN_TYPE_24BIT_LEN = 3
} oma_tlv_len_type_t;
typedef struct {
oma_tlv_type_t type;
uint16_t id; /* can be 8-bit or 16-bit when serialized */
uint32_t length;
const uint8_t *value;
} oma_tlv_t;
size_t oma_tlv_get_size(const oma_tlv_t *tlv);
/* read a TLV from the buffer */
size_t oma_tlv_read(oma_tlv_t *tlv, const uint8_t *buffer, size_t len);
/* write a TLV to the buffer */
size_t oma_tlv_write(const oma_tlv_t *tlv, uint8_t *buffer, size_t len);
int32_t oma_tlv_get_int32(const oma_tlv_t *tlv);
/* write a int as a TLV to the buffer */
size_t oma_tlv_write_int32(int16_t id, int32_t value, uint8_t *buffer, size_t len);
/* write a float converted from fixpoint as a TLV to the buffer */
size_t oma_tlv_write_float32(int16_t id, int32_t value, int bits, uint8_t *buffer, size_t len);
/* convert TLV with float32 to fixpoint */
size_t oma_tlv_float32_to_fix(const oma_tlv_t *tlv, int32_t *value, int bits);
#endif /* OAM_TLV_H_ */
/** @} */

View file

@ -86,7 +86,7 @@ base64_decode_char(char c)
static int
base64_add_char(struct base64_decoder_state *s, char c)
{
if(isspace(c)) {
if(isspace((int)c)) {
return 0;
}

View file

@ -90,7 +90,7 @@ PROCESS_THREAD(shell_var_process, ev, data)
{
int i;
int j;
char numbuf[32];
char numbuf[40];
PROCESS_BEGIN();

View file

@ -532,7 +532,7 @@ shell_strtolong(const char *str, const char **retstr)
++strptr;
}
for(i = 0; i < 10 && isdigit(strptr[i]); ++i) {
for(i = 0; i < 10 && isdigit((int)strptr[i]); ++i) {
num = num * 10 + strptr[i] - '0';
}
if(retstr != NULL) {

View file

@ -89,7 +89,6 @@ output(void)
{
int len, ret;
printf("ip64-interface: output source ");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF(" destination ");
@ -117,6 +116,8 @@ output(void)
return IP64_ETH_DRIVER.output(ip64_packet_buffer, len);
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
const struct uip_fallback_interface ip64_eth_interface = {

View file

@ -897,11 +897,13 @@ interface_init(void)
IP64_UIP_FALLBACK_INTERFACE.init();
}
/*---------------------------------------------------------------------------*/
static void
static int
interface_output(void)
{
PRINTF("ip64: interface_output len %d\n", uip_len);
IP64_UIP_FALLBACK_INTERFACE.output();
return 0;
}
/*---------------------------------------------------------------------------*/
const struct uip_fallback_interface ip64_uip_fallback_interface = {

View file

@ -90,8 +90,8 @@
* settles down, the code compensates the offsets.
*
* We consider 125, 250ms etc because they are nice divisors of 1 sec
* (quotient is power of two). For some machines (e.g sky/msp430,
* sensinode/cc243x), this is also a nice number of clock ticks
* (quotient is power of two). For some machines (e.g sky/msp430),
* this is also a nice number of clock ticks
*
* After experimentation, the values of Imin leading to best performance are:
* ContikiMAC: Imin=64 (500ms)

File diff suppressed because it is too large Load diff

View file

@ -1428,7 +1428,7 @@ uip_process(uint8_t flag)
UIP_STAT(++uip_stat.icmp.drop);
UIP_STAT(++uip_stat.icmp.chkerr);
UIP_LOG("icmpv6: bad checksum.");
PRINTF("icmpv6: bad checksum.");
PRINTF("icmpv6: bad checksum.\n");
goto drop;
}
#endif /*UIP_CONF_IPV6_CHECKS*/

View file

@ -271,14 +271,24 @@ static const struct unicast_callbacks rrep_callbacks = {rrep_packet_received};
static const struct netflood_callbacks rreq_callbacks = {rreq_packet_received, NULL, NULL};
/*---------------------------------------------------------------------------*/
void
route_discovery_explicit_open(struct route_discovery_conn *c,
clock_time_t time,
uint16_t netflood_channel,
uint16_t unicast_channel,
const struct route_discovery_callbacks *callbacks)
{
netflood_open(&c->rreqconn, time, netflood_channel, &rreq_callbacks);
unicast_open(&c->rrepconn, unicast_channel, &rrep_callbacks);
c->cb = callbacks;
}
/*---------------------------------------------------------------------------*/
void
route_discovery_open(struct route_discovery_conn *c,
clock_time_t time,
uint16_t channels,
const struct route_discovery_callbacks *callbacks)
{
netflood_open(&c->rreqconn, time, channels + 0, &rreq_callbacks);
unicast_open(&c->rrepconn, channels + 1, &rrep_callbacks);
c->cb = callbacks;
route_discovery_explicit_open(c, time, channels + 0, channels + 1, callbacks);
}
/*---------------------------------------------------------------------------*/
void

View file

@ -83,6 +83,10 @@ struct route_discovery_conn {
void route_discovery_open(struct route_discovery_conn *c, clock_time_t time,
uint16_t channels,
const struct route_discovery_callbacks *callbacks);
void route_discovery_explicit_open(struct route_discovery_conn *c, clock_time_t time,
uint16_t netflood_channel,
uint16_t unicast_channel,
const struct route_discovery_callbacks *callbacks);
int route_discovery_discover(struct route_discovery_conn *c, const linkaddr_t *dest,
clock_time_t timeout);

View file

@ -1274,7 +1274,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(dag != NULL && instance != NULL) {
if(lollipop_greater_than(dio->version, dag->version)) {
if(dag->rank == ROOT_RANK(instance)) {
PRINTF("RPL: Root received inconsistent DIO version number\n");
PRINTF("RPL: Root received inconsistent DIO version number (current: %u, received: %u)\n", dag->version, dio->version);
dag->version = dio->version;
RPL_LOLLIPOP_INCREMENT(dag->version);
rpl_reset_dio_timer(instance);
@ -1302,7 +1302,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
}
if(instance == NULL) {
PRINTF("RPL: New instance detected: Joining...\n");
PRINTF("RPL: New instance detected (ID=%u): Joining...\n", dio->instance_id);
rpl_join_instance(from, dio);
return;
}

View file

@ -1,112 +0,0 @@
/*
* \file
* This file contains a set of configuration for using SDCC as a compiler.
* Modified from z80 port for cc2430 port.
*
* \author
* Takahide Matsutsuka <markn@markn.org> (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net>
* (recent updates for the sensinode/cc2430 port)
*/
#ifndef E051_DEF_H_
#define E051_DEF_H_
#include <stdint.h>
/* This port no longer implements the legacy clock_delay. Hack its usages
* outta the way till it gets phased out completely
* NB: This also overwrites the prototype so delay_usec() is declared twice */
#define clock_delay(t) clock_delay_usec(t)
/*
* lint - style defines to help syntax parsers with sdcc-specific 8051 code
* They don't interfere with actual compilation
*/
#if !defined(__SDCC_mcs51) && !defined(SDCC_mcs51)
#define __data
#define __xdata
#define __code
#define __bit bool
#define __sfr volatile unsigned char
#define __sbit volatile bool
#define __critical
#define __at(x)
#define __using(x)
#define __interrupt(x)
#define __naked
#endif
#define CC_CONF_FUNCTION_POINTER_ARGS 1
#define CC_CONF_VA_ARGS 1
#define CC_CONF_UNSIGNED_CHAR_BUGS 0
#define CC_CONF_REGISTER_ARGS 0
#define CC_CONF_FUNCTION_POINTER_KEYWORD __reentrant
#define CC_CONF_NON_BANKED_OPTIMIZATION 1
#if (defined(__SDCC_mcs51) || defined(SDCC_mcs51)) && CC_CONF_NON_BANKED_OPTIMIZATION
#define CC_NON_BANKED __nonbanked
#else
#define CC_NON_BANKED
#endif
/*
* Max Stack Depth manipulation. It is possible to get up to 247 bytes
* allocated for the stack if:
* - You set this to 1 and
* - You have a patched toolchain and
* - You don't use __bit variables
* - You do not link libraries using BIT registers (e.g. printf_large)
* Enabling this will mean ISRs will NOT push bits (#pragma exclude bits) so
* make sure you know what you're doing
*
* More information on the wiki
*/
#define CC_CONF_OPTIMIZE_STACK_SIZE 0
#if CC_CONF_OPTIMIZE_STACK_SIZE
#define CC_AT_DATA
#else
#define CC_AT_DATA __data
#endif
/* Generic types. */
typedef unsigned short uip_stats_t;
/* Time type. */
typedef unsigned short clock_time_t;
#define MAX_TICKS (~((clock_time_t)0) / 2)
/* Defines tick counts for a second. */
#define CLOCK_CONF_SECOND 128
/* Compiler configurations */
#define CCIF
#define CLIF
/* Single asm instruction without messing up syntax highlighting */
#if defined(__SDCC_mcs51) || defined(SDCC_mcs51)
#define ASM(x) __asm \
x \
__endasm
#else
#define ASM(x)
#endif
/* Critical section management */
#define DISABLE_INTERRUPTS() do {EA = 0;} while(0)
#define ENABLE_INTERRUPTS() do {EA = 1;} while(0)
/* Macro for a soft reset. */
#define SOFT_RESET() do {((void (__code *) (void)) 0x0000) ();} while(0)
/* We don't provide architecture-specific checksum calculations */
#define UIP_ARCH_ADD32 0
#define UIP_ARCH_CHKSUM 0
#define CC_CONF_ASSIGN_AGGREGATE(dest, src) \
memcpy(dest, src, sizeof(*dest))
#define uip_ipaddr_copy(dest, src) \
memcpy(dest, src, sizeof(*dest))
#endif /* E051_DEF_H_ */

View file

@ -1,116 +0,0 @@
### Compiler definitions
CC = sdcc
LD = sdcc
AS = sdcc
AR = sdar
OBJCOPY = objcopy
STRIP = strip
PACKIHX = packihx
BANK_ALLOC = $(CONTIKI)/cpu/cc2430/bank-alloc.py
SEGMENT_RULES = $(OBJECTDIR)/segment.rules
CFLAGS += --model-$(MEMORY_MODEL) --stack-auto -DSDCC_CC2430 --std-c99
CFLAGS += --fomit-frame-pointer
### Disable warning 110 (EVELYN the modified dog) and 126 (unreachable code)
CFLAGS += --disable-warning 110 --disable-warning 126
LDFLAGS += --model-$(MEMORY_MODEL) --stack-auto -DSDCC_CC2430 --out-fmt-ihx
LDFLAGS += --xram-loc 0xE000 --xram-size 0x1F00
LDFLAGS += --code-loc $(START_ADDR) --code-size $(CODE_SIZE)
ASFLAGS += -plosgff
AROPTS = -rc
### Our object files are .rel, so we can't use the default finalize dependency
### generation. Override here.
define FINALIZE_SDCC_DEPENDENCY
cp $(@:.rel=.d) $(@:.rel=.$$$$); \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:.rel=.$$$$) >> $(@:.rel=.d); \
rm -f $(@:.rel=.$$$$)
endef
### Banking Guesswork:
### Examples outside examples/sensinode do not specify banking.
### We automatically turn it on if its unspecified and if we are building with
### CONTIKI_WITH_IPV6
ifndef HAVE_BANKING
ifeq ($(CONTIKI_WITH_IPV6),1)
HAVE_BANKING=1
else
HAVE_BANKING=0
endif
endif
### Does the project want us to offset the firmware?
### define start address and max code size accordingly, turn Disco on
ifeq ($(OFFSET_FIRMWARE),1)
START_ADDR = 0x01000
HOME_START = 00001000
ifeq ($(HAVE_BANKING),1)
CODE_SIZE = 0x1F000
else
CODE_SIZE = 0x0F000
endif
else
START_ADDR = 0x00000
HOME_START = 00000000
ifeq ($(HAVE_BANKING),1)
CODE_SIZE = 0x20000
else
CODE_SIZE = 0x10000
endif
endif
### Are we building with BANKing supoprt?
ifeq ($(HAVE_BANKING),1)
## Yes
MEMORY_MODEL=huge
LDFLAGS += -Wl-bBANK1=0x018000
LD_POST_FLAGS += -Wl-bBANK2=0x028000
LD_POST_FLAGS += -Wl-bBANK3=0x038000
LDFLAGS += -Wl-r
CFLAGS += -DHAVE_SDCC_BANKING
#use this in $(call c_seg,$<) to get segment for a source file.
c_seg = --codeseg $(shell python $(BANK_ALLOC) $1 $(SEGMENT_RULES) $2)
else
## No banking
MEMORY_MODEL=large
c_seg =
endif
### CPU-dependent cleanup files
CLEAN += *.lnk *.lk *.sym *.lib *.ihx *.rel *.mem *.rst *.asm *.hex
CLEAN += *.omf *.cdb *.banks
CLEAN += symbols.c symbols.h
### CPU-dependent directories
CONTIKI_CPU_DIRS = . dev
### CPU-dependent source files
CONTIKI_SOURCEFILES += bus.c clock.c uart0.c uart1.c cc2430_rf.c dma.c
CONTIKI_SOURCEFILES += uart_intr.c cc2430_rf_intr.c dma_intr.c
CONTIKI_SOURCEFILES += watchdog-cc2430.c rtimer-arch.c stack.c
CONTIKI_ASMFILES +=
CONTIKI_ASMOBJECTFILES = $(addprefix $(OBJECTDIR)/,$(CONTIKI_ASMFILES:.S=.rel))
CONTIKI_CASMOBJECTFILES = $(addprefix $(OBJECTDIR)/, \
$(CONTIKI_CASMFILES:.cS=.rel))
CONTIKI_PLATFORM_DIRS = $(PLATFORM_APPDIRS) \
$(addprefix $(CONTIKI)/platform/$(TARGET)/, $(CONTIKI_TARGET_DIRS))
CONTIKI_CPU_DIRS_LIST = $(addprefix $(CONTIKI_CPU)/, \
$(CONTIKI_CPU_DIRS))
oname = $(patsubst %.c,%.rel,$(patsubst %.S,%.rel,$(1)))
CONTIKI_OBJECTFILES = $(addprefix $(OBJECTDIR)/, \
$(call oname, $(CONTIKI_SOURCEFILES)))
PROJECT_OBJECTFILES = $(addprefix $(OBJECTDIR)/, \
$(call oname, $(PROJECT_SOURCEFILES)))

View file

@ -1,63 +0,0 @@
### Compilation rules
SEGMENT_RULE_FILES = $(foreach dir, . $(CONTIKI_PLATFORM_DIRS) \
$(CONTIKI_CPU_DIRS_LIST), $(wildcard $(dir)/segment.rules) )
# NB: Assumes SEGMENT_RULES was not overridden and is in $(OBJECTDIR)
$(SEGMENT_RULES): $(SEGMENT_RULE_FILES) | $(OBJECTDIR)
cat $(SEGMENT_RULE_FILES) | \
sed -e 's/#.*$$//' -e 's/^\s*//' -e '/^$$/d' > $@
CUSTOM_RULE_LINK=1
CUSTOM_RULE_C_TO_OBJECTDIR_O=1
CUSTOM_RULE_ALLOBJS_TO_TARGETLIB=1
$(OBJECTDIR)/%.rel: %.c $(SEGMENT_RULES) | $(OBJECTDIR)
$(TRACE_CC)
$(Q)$(CC) $(call c_seg,$<,$@) $(CFLAGS) -c $< -o $@ -Wp,-MMD,$(@:.rel=.d),-MQ,$@
@$(FINALIZE_SDCC_DEPENDENCY)
contiki-$(TARGET).lib: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) \
$(CONTIKI_ASMOBJECTFILES) $(CONTIKI_CASMOBJECTFILES)
rm -f $@
for target in $^; do echo $$target >> $@; done
.PRECIOUS: %.$(TARGET) %.hex
# build app/example local object files. We need a separate rule so that we can
# pass -DAUTOSTART_ENABLE for those files only
$(OBJECTDIR)/%.app.rel: %.c $(SEGMENT_RULES) | $(OBJECTDIR)
$(TRACE_CC)
$(Q)$(CC) $(call c_seg,$<,$@) -DAUTOSTART_ENABLE $(CFLAGS) -c $< -o $@
# .ihx is the sdcc binary output file
%.ihx: $(OBJECTDIR)/%.app.rel $(CONTIKI_TARGET_MAIN) contiki-$(TARGET).lib
# Automatic bank relocation when building banked code
ifeq ($(HAVE_BANKING),1)
@echo "\nFirst Link"
@echo "==============="
$(TRACE_LD)
$(Q)$(LD) $(LDFLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib
@echo "\nBank Allocation"
@echo "==============="
python $(BANK_ALLOC) $(basename $(@F)) $(SEGMENT_RULES) $(OFFSET_FIRMWARE)
@echo "\nFinal Link"
@echo "==============="
endif
$(TRACE_LD)
$(Q)$(LD) $(LDFLAGS) $(LD_POST_FLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib
# Pack the hex file for programmers which dislike SDCC output hex format
%.hex: %.ihx
@echo "\nPack hex file"
@echo "==============="
ifeq ($(HAVE_BANKING),1)
srec_cat -disable_sequence_warnings $< -intel -crop 0x10000 0x1FFFF -offset -0x10000 -o bank1.hex -intel
srec_cat -disable_sequence_warnings $< -intel -crop 0x20000 0x2FFFF -offset -0x18000 -o bank2.hex -intel
srec_cat -disable_sequence_warnings $< -intel -crop 0x30000 0x3FFFF -offset -0x20000 -o bank3.hex -intel
srec_cat -disable_sequence_warnings $< -intel -crop 0x00000 0x0FFFF -o home.ihx -intel
srec_cat home.ihx -intel bank1.hex -intel bank2.hex -intel bank3.hex -intel -o $@ -intel
rm -f home.ihx bank1.hex bank2.hex bank3.hex
else
$(PACKIHX) $< > $@
endif

View file

@ -1,228 +0,0 @@
#!/usr/bin/env python
# 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
# Automatic allocation of modules to code segments for bankable builds
# with SDCC's huge memory model.
#
# \author
# George Oikonomou - <oikonomou@users.sourceforge.net>
import sys
import re
import operator
import fileinput
import os
# Open a module object file (.rel) and read it's code size
def retrieve_module_size(file_name):
size_pat = re.compile('^A\s+(?:HOME|BANK[0-9])\s+size\s+([1-9A-F][0-9A-F]*)')
for code_line in open(file_name):
matches = size_pat.search(code_line)
if matches is not None:
return int(matches.group(1), 16)
return 0
# Searches for a code segment rule for file_name in the segment_rules file
# If there is a rule, we respect it. Otherwise, we can move the file around
def get_source_seg(source_file, object_file, segment_rules):
for line in open(segment_rules):
tokens = line.split(None)
match = re.search(tokens[1], source_file)
if match is not None:
# Save it in basename.seg
base, ext = os.path.splitext(object_file)
of = open(base + '.seg', 'w')
of.write(tokens[0] + '\n')
of.close
return tokens[0]
return None
# If segment.rules specified a rule for a source file, the respective object
# file's banking requirement will be stored in object_file.seg
def get_object_seg(object_file):
base, ext = os.path.splitext(object_file)
seg = base + '.seg'
bank = None
if os.path.isfile(seg) is True:
of = open(base + '.seg', 'r')
bank = of.readline().strip()
of.close()
return bank
# Open project.mem and retreive the project's total code footprint
def get_total_size(project):
mem_file = project + '.mem'
pat = re.compile('FLASH\s+(0x[0-9a-f]+\s+){2}([0-9]+)')
for line in open(mem_file):
l = pat.search(line)
if l is not None:
return int(l.group(2))
# Open project.map and retrieve the list of modules linked in
# This will only consider contiki sources, not SDCC libraries
# NB: Sometimes object filenames get truncated:
# contiki-sensinode.lib [ obj_sensinode/watchdog-cc2430.re ]
# See how for this file the 'l' in 'rel' is missing. For that reason, we retrieve
# the filaname until the last '.' but without the extension and we append 'rel'
# As long as the filename doesn't get truncated, we're good
def populate(project, modules, segment_rules, bins):
bankable_total = 0
user_total = 0
map_file = project + '.map'
file_pat = re.compile('obj_sensinode[^ ]+\.')
for line in open(map_file):
file_name = file_pat.search(line)
if file_name is not None:
mod = file_name.group(0) + 'rel'
code_size = retrieve_module_size(mod)
seg = get_object_seg(mod)
if seg is not None:
# This module has been assigned to a bank by the user
#print 'In', seg, file_name.group(0), 'size', code_size
bins[seg][0] += code_size
user_total += code_size
else:
# We are free to allocate this module
modules.append([mod, code_size, "NONE"])
bankable_total += code_size
return bankable_total, user_total
# Allocate bankable modules to banks according to a simple
# 'first fit, decreasing' bin packing heuristic.
def bin_pack(modules, bins, offset, log):
if offset==1:
bins['HOME'][1] -= 4096
# Sort by size, descending, in=place
modules.sort(key=operator.itemgetter(1), reverse=True)
for module in modules:
# We want to iterate in a specific order and dict.keys() won't do that
for bin_id in ['BANK1', 'BANK2', 'BANK3', 'HOME']:
if bins[bin_id][0] + module[1] < bins[bin_id][1]:
bins[bin_id][0] += module[1]
module[2] = bin_id
log.writelines(' '.join([module[2].ljust(8), \
str(module[1]).rjust(5), module[0], '\n']))
break
else:
if bin_id == 'HOME':
print "Failed to allocate", module[0], "with size", module[1], \
"to a code bank. This is fatal"
return 1
return 0
# Hack the new bank directly in the .rel file
def relocate(module, bank):
code_pat = re.compile('(A\s+)(?:HOME|BANK[0-9])(\s+size\s+[1-9A-F][0-9A-F]*.+\n)')
for line in fileinput.input(module, inplace=1):
m = code_pat.search(line)
if m is not None:
line = m.group(1) + bank + m.group(2)
sys.stdout.write(line)
return
if len(sys.argv) < 3:
print 'Usage:'
print 'bank-alloc.py project path_to_segment_rules [offset]'
print 'bank-alloc.py source_file path_to_segment_rules object_file'
sys.exit(1)
modules = list()
file_name = sys.argv[1]
segment_rules = sys.argv[2]
# Magic: Guess whether we want to determine the code bank for a code file
# or whether we want to bin-pack
basename, ext = os.path.splitext(file_name)
if ext == '.c':
# Code Segment determination
if len(sys.argv) < 4:
print 'Usage:'
print 'bank-alloc.py project path_to_segment_rules [offset]'
print 'bank-alloc.py source_file path_to_segment_rules object_file'
sys.exit(1)
object_file = sys.argv[3]
seg = get_source_seg(file_name, object_file, segment_rules)
if seg is None:
print "BANK1"
else:
print seg
exit()
# Bin-Packing
offset = 0
if len(sys.argv) > 3 and sys.argv[3] is not None:
offset = int(sys.argv[3])
sizes = {'total': 0, 'bankable': 0, 'user': 0, 'libs': 0}
# Name : [Allocated, capacity]
bins = {
'HOME': [0, 32768],
'BANK1': [0, 32768],
'BANK2': [0, 32768],
'BANK3': [0, 30720]
}
sizes['total'] = get_total_size(basename)
sizes['bankable'], sizes['user'] = populate(basename, modules, segment_rules, bins)
sizes['libs'] = sizes['total'] - sizes['bankable'] - sizes['user']
print 'Total Size =', sizes['total'], 'bytes (' + \
str(sizes['bankable']), 'bankable,', \
str(sizes['user']), 'user-allocated,', \
str(sizes['libs']), 'const+libs)'
bins['HOME'][0] += sizes['libs']
print 'Preallocations: HOME=' + str(bins['HOME'][0]) + \
', BANK1=' + str(bins['BANK1'][0]) + ', BANK2=' + str(bins['BANK2'][0]) + \
', BANK3=' + str(bins['BANK3'][0])
# Open a log file
of = open(basename + '.banks', 'w')
pack = bin_pack(modules, bins, offset, of)
of.close()
print "Bin-Packing results (target allocation):"
print "Segment - max - alloc"
for bin_id in ['HOME', 'BANK1', 'BANK2', 'BANK3']:
print bin_id.rjust(7), str(bins[bin_id][1]).rjust(6), str(bins[bin_id][0]).rjust(6)
if pack > 0:
sys.exit(1)
# If we reach here we seem to have a sane allocation. Start changing .rel files
for module in modules:
relocate(module[0], module[2])

View file

@ -1,709 +0,0 @@
/**
*
* \file cc2430_sfr.h
* \brief CC2430 registers header file for CC2430.
*
* Definitions for CC2430 SFR registers.
*
*
*/
#ifndef REG_CC2430_H
#define REG_CC2430_H
#include "8051def.h"
/* BYTE Register */
__sfr __at (0x80) P0 ;
/* P0 */
__sbit __at (0x87) P0_7 ;
__sbit __at (0x86) P0_6 ;
__sbit __at (0x85) P0_5 ;
__sbit __at (0x84) P0_4 ;
__sbit __at (0x83) P0_3 ;
__sbit __at (0x82) P0_2 ;
__sbit __at (0x81) P0_1 ;
__sbit __at (0x80) P0_0 ;
__sfr __at (0x81) SP ;
__sfr __at (0x82) DPL0 ;
__sfr __at (0x83) DPH0 ;
/*DPL and DPH correspond DPL0 and DPH0 (82-83)*/
__sfr __at (0x84) DPL1;
__sfr __at (0x85) DPH1;
__sfr __at (0x86) U0CSR;
#define U_MODE 0x80
#define U_RE 0x40
#define U_SLAVE 0x20
#define U_FE 0x10
#define U_ERR 0x08
#define U_RXB 0x04
#define U_TXB 0x02
#define U_ACTIVE 0x01
__sfr __at (0x87) PCON ;
/* PCON (0x87) */
#define IDLE 0x01
__sfr __at (0x88) TCON ;
/* TCON (0x88) */
__sbit __at (0x8F) TCON_URX1IF;
/*__sbit __at (0x8E) RES;*/
__sbit __at (0x8D) TCON_ADCIF;
/*__sbit __at (0x8C) RES;*/
__sbit __at (0x8B) TCON_URX0IF;
__sbit __at (0x8A) TCON_IT1;
__sbit __at (0x89) TCON_RFERRIF;
__sbit __at (0x88) TCON_IT0;
__sfr __at (0x89) P0IFG;
__sfr __at (0x8A) P1IFG;
__sfr __at (0x8B) P2IFG;
__sfr __at (0x8C) PICTL;
/*PICTL bits*/
#define PADSC 0x40
#define P2IEN 0x20
#define P0IENH 0x10
#define P0IENL 0x08
#define P2ICON 0x04
#define P1ICON 0x02
#define P0ICON 0x01
__sfr __at (0x8D) P1IEN;
__sfr __at (0x8F) P0INP;
__sfr __at (0x90) P1 ;
/* P1 */
__sbit __at (0x90) P1_0 ;
__sbit __at (0x91) P1_1 ;
__sbit __at (0x92) P1_2 ;
__sbit __at (0x93) P1_3 ;
__sbit __at (0x94) P1_4 ;
__sbit __at (0x95) P1_5 ;
__sbit __at (0x96) P1_6 ;
__sbit __at (0x97) P1_7 ;
__sfr __at (0x91) RFIM;
__sfr __at (0x92) DPS;
__sfr __at (0x93) _XPAGE; /*MPAGE as paging register for sdcc*/
__sfr __at (0x94) T2CMP;
__sfr __at (0x95) ST0;
__sfr __at (0x96) ST1;
__sfr __at (0x97) ST2;
__sfr __at (0x98) S0CON ;
__sbit __at (0x99) S0CON_ENCIF_1;
__sbit __at (0x98) S0CON_ENCIF_0;
__sfr __at (0x99) HSRC;
__sfr __at (0x9A) IEN2;
/*IEN2 bits*/
#define WDTIE 0x20
#define P1IE 0x10
#define UTX1IE 0x08
#define UTX0IE 0x04
#define P2IE 0x02
#define RFIE 0x01
__sfr __at (0x9B) S1CON;
/*S1CON bits*/
#define RFIF_1 0x02
#define RFIF_0 0x01
__sfr __at (0x9C) T2PEROF0;
__sfr __at (0x9D) T2PEROF1;
__sfr __at (0x9E) T2PEROF2;
/*T2PEROF2 bits*/
#define CMPIM 0x80
#define PERIM 0x40
#define OFCMPIM 0x20
#define PEROF23 0x08
#define PEROF22 0x04
#define PEROF21 0x02
#define PEROF20 0x01
__sfr __at (0x9F) FMAP;
__sfr __at (0x9F) PSBANK;
__sfr __at (0xA0) P2 ;
/* P2 */
__sbit __at (0xA0) P2_0 ;
__sbit __at (0xA1) P2_1 ;
__sbit __at (0xA2) P2_2 ;
__sbit __at (0xA3) P2_3 ;
__sbit __at (0xA4) P2_4 ;
/*__sbit __at (0xA5) P2_5 ;
__sbit __at (0xA6) P2_6 ;
__sbit __at (0xA7) P2_7 ;*/
__sfr __at (0xA1) T2OF0;
__sfr __at (0xA2) T2OF1;
__sfr __at (0xA3) T2OF2;
__sfr __at (0xA4) T2CAPLPL;
__sfr __at (0xA5) T2CAPHPH;
__sfr __at (0xA6) T2TLD;
__sfr __at (0xA7) T2THD;
__sfr __at (0xA8) IE ;
__sfr __at (0xA8) IEN0;
/*IEN0 bits*/
#define IEN0_EA_MASK 0x80
#define STIE 0x20
#define ENCIE 0x10
#define URX1IE 0x08
#define URX0IE 0x04
#define ADCIE 0x02
#define RFERRIE 0x01
/* IEN0 (0xA8) */
__sbit __at (0xAF) EA;
__sbit __at (0xAF) IEN0_EA;
/*__sbit __at (0xAE) RES;*/
__sbit __at (0xAD) IEN0_STIE;
__sbit __at (0xAC) IEN0_ENCIE;
__sbit __at (0xAB) IEN0_URX1IE;
__sbit __at (0xAA) IEN0_URX0IE;
__sbit __at (0xA9) IEN0_ADCIE;
__sbit __at (0xA8) IEN0_RFERRIE;
__sfr __at (0xA9) IP0;
/*IP0 bits*/
#define IP0_5 0x20
#define IP0_4 0x10
#define IP0_3 0x08
#define IP0_2 0x04
#define IP0_1 0x02
#define IP0_0 0x01
__sfr __at (0xAB) FWT;
__sfr __at (0xAC) FADDRL;
__sfr __at (0xAD) FADDRH;
__sfr __at (0xAE) FCTL;
#define F_BUSY 0x80
#define F_SWBSY 0x40
#define F_CONTRD 0x10
#define F_WRITE 0x02
#define F_ERASE 0x01
__sfr __at (0xAF) FWDATA;
/*No port 3 (0xB0)*/
__sfr __at (0xB1) ENCDI;
__sfr __at (0xB2) ENCDO;
__sfr __at (0xB3) ENCCS;
#define CCS_MODE2 0x40
#define CCS_MODE1 0x20
#define CCS_MODE0 0x10
#define CCS_RDY 0x08
#define CCS_CMD1 0x04
#define CCS_CMD0 0x02
#define CCS_ST 0x01
__sfr __at (0xB4) ADCCON1;
/*ADCCON1 bits*/
#define ADEOC 0x80
#define ADST 0x40
#define ADSTS1 0x20
#define ADSTS0 0x10
#define ADRCTRL1 0x08
#define ADRCTRL0 0x04
__sfr __at (0xB5) ADCCON2;
/*ADCCON2 bits*/
#define ADSREF1 0x80
#define ADSREF0 0x40
#define ADSDIV1 0x20
#define ADSDIV0 0x10
#define ADSCH3 0x08
#define ADSCH2 0x04
#define ADSCH1 0x02
#define ADSCH0 0x01
__sfr __at (0xB6) ADCCON3;
/*ADCCON3 bits*/
#define ADEREF1 0x80
#define ADEREF0 0x40
#define ADEDIV1 0x20
#define ADEDIV0 0x10
#define ADECH3 0x08
#define ADECH2 0x04
#define ADECH1 0x02
#define ADECH0 0x01
__sfr __at (0xB7) RCCTL;
#undef IP /*this is 0xb8 in base core*/
__sfr __at (0xB8) IEN1;
/*IEN1 bits*/
#define P0IE 0x20
#define T4IE 0x10
#define T3IE 0x08
#define T2IE 0x04
#define T1IE 0x02
#define DMAIE 0x01
/* IEN1 (0xB8) */
/*__sbit __at (0xBF) IEN1_RES;*/
/*__sbit __at (0xBE) RES;*/
__sbit __at (0xBD) IEN1_P0IE;
__sbit __at (0xBC) IEN1_T4IE;
__sbit __at (0xBB) IEN1_T3IE;
__sbit __at (0xBA) IEN1_T2IE;
__sbit __at (0xB9) IEN1_T1IE;
__sbit __at (0xB8) IEN1_DMAIE;
__sfr __at (0xB9) IP1;
/*IP1 bits*/
#define IP1_5 0x20
#define IP1_4 0x10
#define IP1_3 0x08
#define IP1_2 0x04
#define IP1_1 0x02
#define IP1_0 0x01
__sfr __at (0xBA) ADCL;
__sfr __at (0xBB) ADCH;
__sfr __at (0xBC) RNDL;
__sfr __at (0xBD) RNDH;
__sfr __at (0xBE) SLEEP;
#define OSC32K_CALDIS 0x80
#define XOSC_STB 0x40
#define HFRC_STB 0x20
#define RST1 0x10
#define RST0 0x08
#define OSC_PD 0x04
#define SLEEP_MODE1 0x02
#define SLEEP_MODE0 0x01
__sfr __at (0xC0) IRCON;
/*IRCON bits*/
#define STIF 0x80
#define P0IF 0x20
#define T4IF 0x10
#define T3IF 0x08
#define T2IF 0x04
#define T1IF 0x02
#define DMAIF 0x01
/* IRCON */
__sbit __at (0xC7) IRCON_STIF ;
/*__sbit __at (0x86) IRCON_6 ;*/
__sbit __at (0xC5) IRCON_P0IF;
__sbit __at (0xC4) IRCON_T4IF;
__sbit __at (0xC3) IRCON_T3IF;
__sbit __at (0xC2) IRCON_T2IF;
__sbit __at (0xC1) IRCON_T1IF;
__sbit __at (0xC0) IRCON_DMAIF;
__sfr __at (0xC1) U0BUF;
__sfr __at (0xC2) U0BAUD;
__sfr __at (0xC3) T2CNF;
/*T2SEL bits*/
#define CMPIF 0x80
#define PERIF 0x40
#define OFCMPIF 0x20
#define CMSEL 0x08
#define SYNC 0x02
#define RUN 0x01
__sfr __at (0xC4) U0UCR;
#define U_FLUSH 0x80
#define U_FLOW 0x40
#define U_D9 0x20
#define U_BIT9 0x10
#define U_PARITY 0x08
#define U_SPB 0x04
#define U_STOP 0x02
#define U_START 0x01
__sfr __at (0xC5) U0GCR;
#define U_CPOL 0x80
#define U_CPHA 0x40
#define U_ORDER 0x20
#define U_BAUD_E4 0x10
#define U_BAUD_E3 0x08
#define U_BAUD_E2 0x04
#define U_BAUD_E1 0x02
#define U_BAUD_E0 0x01
__sfr __at (0xC6) CLKCON;
#define OSC32K 0x80
#define OSC 0x40
#define TICKSPD2 0x20
#define TICKSPD1 0x10
#define TICKSPD0 0x08
#define CLKSPD 0x01
__sfr __at (0xC7) MEMCTR;
#define MUNIF 0x40
__sfr __at (0xC8) T2CON;
__sfr __at (0xC9) WDCTL;
#define WDT_CLR3 0x80
#define WDT_CLR2 0x40
#define WDT_CLR1 0x20
#define WDT_CLR0 0x10
#define WDT_EN 0x08
#define WDT_MODE 0x04
#define WDT_INT1 0x02
#define WDT_INT0 0x01
__sfr __at (0xCA) T3CNT;
__sfr __at (0xCB) T3CTL;
/*T3CTL bits*/
#define T3DIV2 0x80
#define T3DIV1 0x40
#define T3DIV0 0x20
#define T3START 0x10
#define T3OVFIM 0x08
#define T3CLR 0x04
#define T3MODE1 0x02
#define T3MODE0 0x01
__sfr __at (0xCC) T3CCTL0;
/*T3CCTL0 bits*/
#define T3IM 0x40
#define T3CMP2 0x20
#define T3CMP1 0x10
#define T3CMP0 0x08
#define T3MODE 0x04
#define T3CAP1 0x02
#define T3CAP0 0x01
__sfr __at (0xCD) T3CC0;
__sfr __at (0xCE) T3CCTL1;
/*T3CCTL0 bits apply*/
__sfr __at (0xCF) T3CC1;
__sfr __at (0xD0) PSW ;
/* PSW */
__sbit __at (0xD0) P ;
__sbit __at (0xD1) F1 ;
__sbit __at (0xD2) OV ;
__sbit __at (0xD3) RS0 ;
__sbit __at (0xD4) RS1 ;
__sbit __at (0xD5) F0 ;
__sbit __at (0xD6) AC ;
__sbit __at (0xD7) CY ;
__sfr __at (0xD1) DMAIRQ;
/*DMAIRQ bits*/
#define DMAIF4 0x10
#define DMAIF3 0x08
#define DMAIF2 0x04
#define DMAIF1 0x02
#define DMAIF0 0x01
__sfr __at (0xD2) DMA1CFGL;
__sfr __at (0xD3) DMA1CFGH;
__sfr __at (0xD4) DMA0CFGL;
__sfr __at (0xD5) DMA0CFGH;
__sfr __at (0xD6) DMAARM;
/*DMAARM bits*/
#define ABORT 0x80
#define DMAARM4 0x10
#define DMAARM3 0x08
#define DMAARM2 0x04
#define DMAARM1 0x02
#define DMAARM0 0x01
__sfr __at (0xD7) DMAREQ;
/*DMAREQ bits*/
#define DMAREQ4 0x10
#define DMAREQ3 0x08
#define DMAREQ2 0x04
#define DMAREQ1 0x02
#define DMAREQ0 0x01
__sfr __at (0xD8) TIMIF;
/*TIMIF bits*/
#define OVFIM 0x40
#define T4CH1IF 0x20
#define T4CH0IF 0x10
#define T4OVFIF 0x08
#define T3CH1IF 0x04
#define T3CH0IF 0x02
#define T3OVFIF 0x01
__sfr __at (0xD9) RFD;
__sfr __at (0xDA) T1CC0L;
__sfr __at (0xDB) T1CC0H;
__sfr __at (0xDC) T1CC1L;
__sfr __at (0xDD) T1CC1H;
__sfr __at (0xDE) T1CC2L;
__sfr __at (0xDF) T1CC2H;
__sfr __at (0xE0) ACC;
__sfr __at (0xE1) RFST;
__sfr __at (0xE2) T1CNTL;
__sfr __at (0xE3) T1CNTH;
__sfr __at (0xE4) T1CTL;
/*T1CTL bits*/
#define CH2IF 0x80
#define CH1IF 0x40
#define CH0IF 0x20
#define OVFIF 0x10
#define T1DIV1 0x08
#define T1DIV0 0x04
#define T1MODE1 0x02
#define T1MODE0 0x01
__sfr __at (0xE5) T1CCTL0;
/*T1CCTL0 bits*/
#define T1CPSEL 0x80
#define T1IM 0x40
#define T1CMP2 0x20
#define T1CMP1 0x10
#define T1CMP0 0x08
#define T1MODE 0x04
#define T1CAP1 0x02
#define T1CAP0 0x01
__sfr __at (0xE6) T1CCTL1;
/*Bits defined in T1CCTL0 */
__sfr __at (0xE7) T1CCTL2;
/*Bits defined in T1CCTL0 */
__sfr __at (0xE8) IRCON2;
/*IRCON2 bits*/
#define WDTIF 0x10
#define P1IF 0x08
#define UTX1IF 0x04
#define UTX0IF 0x02
#define P2IF 0x01
/* IRCON 2 */
/*__sbit __at (0xEF) IRCON2_P1_7 ;
__sbit __at (0xEE) IRCON2_P1_6 ;
__sbit __at (0xED) IRCON2_P1_5 ;*/
__sbit __at (0xEC) IRCON2_WDTIF ;
__sbit __at (0xEB) IRCON2_P1IF ;
__sbit __at (0xEA) IRCON2_UTX1IF ;
__sbit __at (0xE9) IRCON2_UTX0IF ;
__sbit __at (0xE8) IRCON2_P2IF;
__sfr __at (0xE9) RFIF;
/*RFIF bits*/
#define IRQ_RREG_ON 0x80
#define IRQ_TXDONE 0x40
#define IRQ_FIFOP 0x20
#define IRQ_SFD 0x10
#define IRQ_CCA 0x08
#define IRQ_CSP_WT 0x04
#define IRQ_CSP_STOP 0x02
#define IRQ_CSP_INT 0x01
__sfr __at (0xEA) T4CNT;
__sfr __at (0xEB) T4CTL;
/*T4CTL bits*/
#define T4DIV2 0x80
#define T4DIV1 0x40
#define T4DIV0 0x20
#define T4START 0x10
#define T4OVFIM 0x08
#define T4CLR 0x04
#define T4MODE1 0x02
#define T4MODE0 0x01
__sfr __at (0xEC) T4CCTL0;
/*T4CCTL0 bits*/
#define T4IM 0x40
#define T4CMP2 0x20
#define T4CMP1 0x10
#define T4CMP0 0x08
#define T4MODE 0x04
#define T4CAP1 0x02
#define T4CAP0 0x01
__sfr __at (0xED) T4CC0;
__sfr __at (0xEE) T4CCTL1;
/*T4CCTL0 bits apply*/
__sfr __at (0xEF) T4CC1;
__sfr __at (0xF0) B ;
__sfr __at (0xF1) PERCFG;
/*PERCFG bits*/
#define T1CFG 0x40
#define T3CFG 0x20
#define T4CFG 0x10
#define U1CFG 0x02
#define U0CFG 0x01
__sfr __at (0xF2) ADCCFG;
/*ADCCFG bits*/
#define ADC7EN 0x80
#define ADC6EN 0x40
#define ADC5EN 0x20
#define ADC4EN 0x10
#define ADC3EN 0x08
#define ADC2EN 0x04
#define ADC1EN 0x02
#define ADC0EN 0x01
__sfr __at (0xF3) P0SEL;
__sfr __at (0xF4) P1SEL;
__sfr __at (0xF5) P2SEL;
/*P2SEL bits*/
#define PRI3P1 0x40
#define PRI2P1 0x20
#define PRI1P1 0x10
#define PRI0P1 0x08
#define SELP2_4 0x04
#define SELP2_3 0x02
#define SELP2_0 0x01
__sfr __at (0xF6) P1INP;
__sfr __at (0xF7) P2INP;
/*P2INP bits*/
#define PDUP2 0x80
#define PDUP1 0x40
#define PDUP0 0x20
#define MDP2_4 0x10
#define MDP2_3 0x08
#define MDP2_2 0x04
#define MDP2_1 0x02
#define MDP2_0 0x01
__sfr __at (0xF8) U1CSR;
__sfr __at (0xF9) U1BUF;
__sfr __at (0xFA) U1BAUD;
__sfr __at (0xFB) U1UCR;
__sfr __at (0xFC) U1GCR;
__sfr __at (0xFD) P0DIR;
__sfr __at (0xFE) P1DIR;
__sfr __at (0xFF) P2DIR;
/*P2DIR bits*/
#define PRI1P0 0x80
#define PRI0P0 0x40
#define DIRP2_4 0x10
#define DIRP2_3 0x08
#define DIRP2_2 0x04
#define DIRP2_1 0x02
#define DIRP2_0 0x01
/* IEN0 */
/*__sbit __at (0xA8) EA ;
__sbit __at (0x99) TI ;
__sbit __at (0x9A) RB8 ;
__sbit __at (0x9B) TB8 ;
__sbit __at (0x9C) REN ;
__sbit __at (0x9D) SM2 ;
__sbit __at (0x9E) SM1 ;
__sbit __at (0x9F) SM0 ;*/
/* Interrupt numbers: address = (number * 8) + 3 */
/*#undef IE0_VECTOR
#undef TF0_VECTOR
#undef IE1_VECTOR
#undef TF1_VECTOR
#undef SI0_VECTOR*/
/* CC2430 interrupt vectors */
#define RFERR_VECTOR 0
#define ADC_VECTOR 1
#define URX0_VECTOR 2
#define URX1_VECTOR 3
#define ENC_VECTOR 4
#define ST_VECTOR 5
#define P2INT_VECTOR 6
#define UTX0_VECTOR 7
#define DMA_VECTOR 8
#define T1_VECTOR 9
#define T2_VECTOR 10
#define T3_VECTOR 11
#define T4_VECTOR 12
#define P0INT_VECTOR 13
#define UTX1_VECTOR 14
#define P1INT_VECTOR 15
#define RF_VECTOR 16
#define WDT_VECTOR 17
/* RF control registers*/
__xdata __at (0xDF02) unsigned char MDMCTRL0H;
__xdata __at (0xDF03) unsigned char MDMCTRL0L;
__xdata __at (0xDF04) unsigned char MDMCTRL1H;
__xdata __at (0xDF05) unsigned char MDMCTRL1L;
__xdata __at (0xDF06) unsigned char RSSIH;
__xdata __at (0xDF07) unsigned char RSSIL;
__xdata __at (0xDF08) unsigned char SYNCWORDH;
__xdata __at (0xDF09) unsigned char SYNCWORDL;
__xdata __at (0xDF0A) unsigned char TXCTRLH;
__xdata __at (0xDF0B) unsigned char TXCTRLL;
__xdata __at (0xDF0C) unsigned char RXCTRL0H;
__xdata __at (0xDF0D) unsigned char RXCTRL0L;
__xdata __at (0xDF0E) unsigned char RXCTRL1H;
__xdata __at (0xDF0F) unsigned char RXCTRL1L;
__xdata __at (0xDF10) unsigned char FSCTRLH;
__xdata __at (0xDF11) unsigned char FSCTRLL;
__xdata __at (0xDF12) unsigned char CSPX;
__xdata __at (0xDF13) unsigned char CSPY;
__xdata __at (0xDF14) unsigned char CSPZ;
__xdata __at (0xDF15) unsigned char CSPCTRL;
__xdata __at (0xDF16) unsigned char CSPT;
__xdata __at (0xDF17) unsigned char RFPWR;
#define ADI_RADIO_PD 0x10
#define RREG_RADIO_PD 0x08
#define RREG_DELAY_MASK 0x07
__xdata __at (0xDF20) unsigned char FSMTCH;
__xdata __at (0xDF21) unsigned char FSMTCL;
__xdata __at (0xDF22) unsigned char MANANDH;
__xdata __at (0xDF23) unsigned char MANANDL;
__xdata __at (0xDF24) unsigned char MANORH;
__xdata __at (0xDF25) unsigned char MANORL;
__xdata __at (0xDF26) unsigned char AGCCTRLH;
__xdata __at (0xDF27) unsigned char AGCCTRLL;
__xdata __at (0xDF39) unsigned char FSMSTATE;
__xdata __at (0xDF3A) unsigned char ADCTSTH;
__xdata __at (0xDF3B) unsigned char ADCTSTL;
__xdata __at (0xDF3C) unsigned char DACTSTH;
__xdata __at (0xDF3D) unsigned char DACTSTL;
__xdata __at (0xDF43) unsigned char IEEE_ADDR0;
__xdata __at (0xDF44) unsigned char IEEE_ADDR1;
__xdata __at (0xDF45) unsigned char IEEE_ADDR2;
__xdata __at (0xDF46) unsigned char IEEE_ADDR3;
__xdata __at (0xDF47) unsigned char IEEE_ADDR4;
__xdata __at (0xDF48) unsigned char IEEE_ADDR5;
__xdata __at (0xDF49) unsigned char IEEE_ADDR6;
__xdata __at (0xDF4A) unsigned char IEEE_ADDR7;
__xdata __at (0xDF4B) unsigned char PANIDH;
__xdata __at (0xDF4C) unsigned char PANIDL;
__xdata __at (0xDF4D) unsigned char SHORTADDRH;
__xdata __at (0xDF4E) unsigned char SHORTADDRL;
__xdata __at (0xDF4F) unsigned char IOCFG0;
__xdata __at (0xDF50) unsigned char IOCFG1;
__xdata __at (0xDF51) unsigned char IOCFG2;
__xdata __at (0xDF52) unsigned char IOCFG3;
__xdata __at (0xDF53) unsigned char RXFIFOCNT;
__xdata __at (0xDF54) unsigned char FSMTC1;
#define ABORTRX_ON_SRXON 0x20
#define RX_INTERRUPTED 0x10
#define AUTO_TX2RX_OFF 0x08
#define RX2RX_TIME_OFF 0x04
#define PENDING_OR 0x02
#define ACCEPT_ACKPKT 0x01
__xdata __at (0xDF60) unsigned char CHVER;
__xdata __at (0xDF61) unsigned char CHIPID;
__xdata __at (0xDF62) unsigned char RFSTATUS;
#define TX_ACTIVE 0x10
#define FIFO 0x08
#define FIFOP 0x04
#define SFD 0x02
#define CCA 0x01
__xdata __at (0xDFC1) unsigned char U0BUF_SHADOW;
__xdata __at (0xDFD9) unsigned char RFD_SHADOW;
__xdata __at (0xDFF9) unsigned char U1BUF_SHADOW;
__xdata __at (0xDFBA) unsigned int ADC_SHADOW;
#endif /*REG_CC2430*/

View file

@ -1,58 +0,0 @@
/*
* Copyright (c) 2009, 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.
*
*/
/**
* \file
* Initialization functions for the 8051 bus
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "cc2430_sfr.h"
#include "dev/bus.h"
#include "sys/clock.h"
#include "contiki-conf.h"
/*---------------------------------------------------------------------------*/
void
bus_init(void)
{
CLKCON = (0x00 | OSC32K); /* 32k internal */
while(CLKCON != (0x00 | OSC32K));
P1DIR |= 0x0E;
IEN0_EA = 1;
/* Initialize the clock */
clock_init();
}
/*---------------------------------------------------------------------------*/

View file

@ -1,53 +0,0 @@
/*
* Copyright (c) 2009, 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.
*
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef BUS_H_
#define BUS_H_
#include "cc2430_sfr.h"
#include "8051def.h"
#include "contiki-conf.h"
#define inline
void bus_init(void);
void clock_ISR( void ) __interrupt (ST_VECTOR);
#endif /* BUS_H_ */

View file

@ -1,750 +0,0 @@
/**
* \file
* CC2430 RF driver
* \author
* Zach Shelby <zach@sensinode.com> (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net>
* (port to the netstack API, hexdump output, RX FIFO overflow fixes
* code cleanup, ...)
*
* bankable code for cc2430 rf driver. this code can be placed in any bank.
*
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/radio.h"
#include "dev/cc2430_rf.h"
#include "cc2430_sfr.h"
#include "sys/clock.h"
#include "sys/rtimer.h"
#include "net/packetbuf.h"
#include "net/rime/rimestats.h"
#include "net/netstack.h"
#define CC2430_RF_TX_POWER_RECOMMENDED 0x5F
#ifdef CC2430_RF_CONF_TX_POWER
#define CC2430_RF_TX_POWER CC2430_RF_CONF_TX_POWER
#else
#define CC2430_RF_TX_POWER CC2430_RF_TX_POWER_RECOMMENDED
#endif
#ifdef CC2430_RF_CONF_CHANNEL
#define CC2430_RF_CHANNEL CC2430_RF_CONF_CHANNEL
#else
#define CC2430_RF_CHANNEL 18
#endif /* CC2430_RF_CONF_CHANNEL */
#define CC2430_CHANNEL_MIN 11
#define CC2430_CHANNEL_MAX 26
#ifdef CC2430_RF_CONF_AUTOACK
#define CC2430_RF_AUTOACK CC2430_RF_CONF_AUTOACK
#else
#define CC2430_RF_AUTOACK 1
#endif
#ifndef CC2430_CONF_CHECKSUM
#define CC2430_CONF_CHECKSUM 0
#endif /* CC2420_CONF_CHECKSUM */
#if CC2430_CONF_CHECKSUM
#include "lib/crc16.h"
#define CHECKSUM_LEN 2
#else
#define CHECKSUM_LEN 2
#endif /* CC2430_CONF_CHECKSUM */
#if DEBUG_LEDS
/* moved leds code to BANK1 to make space for cc2430_rf_process in HOME */
/* can't call code in BANK1 from alternate banks unless it is marked with __banked */
#include "dev/leds.h"
#define RF_RX_LED_ON() leds_on(LEDS_RED);
#define RF_RX_LED_OFF() leds_off(LEDS_RED);
#define RF_TX_LED_ON() leds_on(LEDS_GREEN);
#define RF_TX_LED_OFF() leds_off(LEDS_GREEN);
#else
#define RF_RX_LED_ON()
#define RF_RX_LED_OFF()
#define RF_TX_LED_ON()
#define RF_TX_LED_OFF()
#endif
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) do {} while (0)
#endif
/* rf_flags bits */
#define RX_ACTIVE 0x80
#define TX_ACK 0x40
#define TX_ON_AIR 0x20
#define WAS_OFF 0x10
#define INITIALISED 0x01
#define RX_NO_DMA
/* Bits of the last byte in the RX FIFO */
#define CRC_BIT_MASK 0x80
#define LQI_BIT_MASK 0x7F
/* 192 ms, radio off -> on interval */
#define ONOFF_TIME ((RTIMER_ARCH_SECOND / 3125) + 4)
#if CC2430_RF_CONF_HEXDUMP
#include "uart1.h"
static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */
#endif
#ifdef HAVE_RF_ERROR
uint8_t rf_error = 0;
#endif
/*---------------------------------------------------------------------------*/
#if !NETSTACK_CONF_SHORTCUTS
PROCESS(cc2430_rf_process, "CC2430 RF driver");
#endif
/*---------------------------------------------------------------------------*/
static uint8_t CC_AT_DATA rf_flags;
static uint8_t rf_channel;
static int on(void); /* prepare() needs our prototype */
static int off(void); /* transmit() needs our prototype */
static int channel_clear(void); /* transmit() needs our prototype */
/*---------------------------------------------------------------------------*/
/**
* Execute a single CSP command.
*
* \param command command to execute
*
*/
void
cc2430_rf_command(uint8_t command)
{
if(command >= 0xE0) { /*immediate strobe*/
uint8_t fifo_count;
switch (command) { /*hardware bug workaround*/
case ISRFOFF:
case ISRXON:
case ISTXON:
fifo_count = RXFIFOCNT;
RFST = command;
clock_delay_usec(2);
if(fifo_count != RXFIFOCNT) {
RFST = ISFLUSHRX;
RFST = ISFLUSHRX;
}
break;
default:
RFST = command;
}
} else if(command == SSTART) {
RFIF &= ~IRQ_CSP_STOP; /*clear IRQ flag*/
RFST = SSTOP; /*make sure there is a stop in the end*/
RFST = ISSTART; /*start execution*/
while((RFIF & IRQ_CSP_STOP) == 0);
} else {
RFST = command; /*write command*/
}
}
/*---------------------------------------------------------------------------*/
static void
flush_rx()
{
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
#if !NETSTACK_CONF_SHORTCUTS
IEN2 |= RFIE;
#endif
#if CC2430_RFERR_INTERRUPT
IEN0 |= RFERRIE;
#endif
RFIF &= ~IRQ_FIFOP;
}
/*---------------------------------------------------------------------------*/
/**
* Select RF channel.
*
* \param channel channel number to select
*
* \return channel value or negative (invalid channel number)
*/
/* channel freqdiv = (2048 + FSCTRL(9:0)) / 4
freq = (2048 + FSCTRL(9:0)) MHz */
int8_t
cc2430_rf_channel_set(uint8_t channel)
{
uint16_t freq;
if((channel < 11) || (channel > 26)) {
return -1;
}
cc2430_rf_command(ISSTOP); /*make sure CSP is not running*/
cc2430_rf_command(ISRFOFF);
/* Channel values: 11-26 */
freq = (uint16_t) channel - 11;
freq *= 5; /*channel spacing*/
freq += 357; /*correct channel range*/
freq |= 0x4000; /*LOCK_THR = 1*/
FSCTRLH = (freq >> 8);
FSCTRLL = (uint8_t)freq;
cc2430_rf_command(ISRXON);
rf_channel = channel;
return (int8_t) channel;
}
/*---------------------------------------------------------------------------*/
uint8_t
cc2430_rf_channel_get()
{
return rf_channel;
}
/*---------------------------------------------------------------------------*/
/**
* Select RF transmit power.
*
* \param new_power new power level
*
* \return new level
*/
uint8_t
cc2430_rf_power_set(uint8_t new_power)
{
/* Set transmitter power */
TXCTRLL = new_power;
return TXCTRLL;
}
/*---------------------------------------------------------------------------*/
#if 0 /* unused */
/**
* Enable RF transmitter.
*
*
* \return pdTRUE
* \return pdFALSE bus not free
*/
int
cc2430_rf_tx_enable(void)
{
DMAARM = 0x80 + (1 << 0); /*ABORT + channel bit*/
return 1;
}
#endif
/*---------------------------------------------------------------------------*/
/**
* Set MAC addresses
*
* \param pan The PAN address to set
* \param addr The short address to set
* \param ieee_addr The 64-bit IEEE address to set
*/
void
cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr)
{
uint8_t f;
__xdata unsigned char *ptr;
PANIDH = pan >> 8;
PANIDL = pan & 0xff;
SHORTADDRH = addr >> 8;
SHORTADDRL = addr & 0xff;
if(ieee_addr != NULL) {
ptr = &IEEE_ADDR7;
/* LSB first, MSB last for 802.15.4 addresses in CC2420 */
for(f = 0; f < 8; f++) {
*ptr-- = ieee_addr[f];
}
}
}
#if 0 /* currently unused */
/*---------------------------------------------------------------------------*/
/**
* Channel energy detect.
*
* Coordinator use this function detect best channel for PAN-network.
* \return RSSI-energy level dBm.
* \return 0 operation failed.
*/
int8_t
cc2430_rf_analyze_rssi(void)
{
int8_t retval = -128;
/*pause_us(128);*/
retval = (int8_t)RSSIL;
retval -= 45;
return retval;
}
#endif /* currently unused */
/*---------------------------------------------------------------------------*/
/**
* Send ACK.
*
*\param pending set up pending flag if pending > 0.
*/
void
cc2430_rf_send_ack(uint8_t pending)
{
if(pending) {
cc2430_rf_command(ISACKPEND);
} else {
cc2430_rf_command(ISACK);
}
}
/*---------------------------------------------------------------------------*/
/* Netstack API radio driver functions */
/*---------------------------------------------------------------------------*/
static int
init(void)
{
if(rf_flags & INITIALISED) {
return 0;
}
PRINTF("cc2430_rf_init called\n");
RFPWR &= ~RREG_RADIO_PD; /*make sure it's powered*/
while((RFPWR & ADI_RADIO_PD) == 1);
while((RFIF & IRQ_RREG_ON) == 0); /*wait for power up*/
SLEEP &= ~OSC_PD; /*Osc on*/
while((SLEEP & XOSC_STB) == 0); /*wait for power up*/
rf_flags = 0;
FSMTC1 = 1; /*don't abort reception, if enable called, accept ack, auto rx after tx*/
MDMCTRL0H = 0x0A; /* Generic client, standard hysteresis, decoder on 0x0a */
MDMCTRL0L = 0xE2; /* automatic CRC, standard CCA and preamble 0xE2 */
#if CC2430_RF_AUTOACK
MDMCTRL0L |= 0x10;
#endif
MDMCTRL1H = 0x30; /* Defaults */
MDMCTRL1L = 0x0;
RXCTRL0H = 0x32; /* RX tuning optimized */
RXCTRL0L = 0xf5;
cc2430_rf_channel_set(CC2430_RF_CHANNEL);
cc2430_rf_command(ISFLUSHTX);
cc2430_rf_command(ISFLUSHRX);
/* Temporary values, main() will sort this out later on */
cc2430_rf_set_addr(0xffff, 0x0000, NULL);
RFIM = IRQ_FIFOP;
RFIF &= ~(IRQ_FIFOP);
S1CON &= ~(RFIF_0 | RFIF_1);
#if !NETSTACK_CONF_SHORTCUTS
IEN2 |= RFIE;
#endif
/* If contiki-conf.h turns on the RFERR interrupt, enable it here */
#if CC2430_RFERR_INTERRUPT
IEN0 |= RFERRIE;
#endif
RF_TX_LED_OFF();
RF_RX_LED_OFF();
rf_flags |= INITIALISED;
#if !NETSTACK_CONF_SHORTCUTS
process_start(&cc2430_rf_process, NULL);
#endif
cc2430_rf_power_set(CC2430_RF_TX_POWER);
return 1;
}
/*---------------------------------------------------------------------------*/
static int
prepare(const void *payload, unsigned short payload_len)
{
uint8_t i;
/*
* When we transmit in very quick bursts, make sure previous transmission
* is not still in progress before re-writing in the TX FIFO
*/
while(RFSTATUS & TX_ACTIVE);
if(rf_flags & TX_ACK) {
return -1;
}
if((rf_flags & RX_ACTIVE) == 0) {
on();
}
PRINTF("cc2430_rf: sending %u byte payload\n", payload_len);
cc2430_rf_command(ISFLUSHTX);
PRINTF("cc2430_rf: data = ");
/* Send the phy length byte first */
RFD = payload_len + CHECKSUM_LEN; /* Payload plus FCS */
PRINTF("(%d)", payload_len + CHECKSUM_LEN);
for(i = 0; i < payload_len; i++) {
RFD = ((unsigned char *)(payload))[i];
PRINTF("%02X", ((unsigned char *)(payload))[i]);
}
PRINTF("\n");
/* Leave space for the FCS */
RFD = 0;
RFD = 0;
return 0;
}
/*---------------------------------------------------------------------------*/
static int
transmit(unsigned short transmit_len)
{
uint8_t counter;
int ret = RADIO_TX_ERR;
if(!(rf_flags & RX_ACTIVE)) {
on();
rf_flags |= WAS_OFF;
}
if(channel_clear() == CC2430_CCA_BUSY) {
RIMESTATS_ADD(contentiondrop);
return RADIO_TX_COLLISION;
}
/*
* prepare() double checked that TX_ACTIVE is low. If SFD is high we are
* receiving. Abort transmission and bail out with RADIO_TX_COLLISION
*/
if(RFSTATUS & SFD) {
RIMESTATS_ADD(contentiondrop);
return RADIO_TX_COLLISION;
}
/* Start the transmission */
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
cc2430_rf_command(ISTXON);
counter = 0;
while(!(RFSTATUS & TX_ACTIVE) && (counter++ < 3)) {
clock_delay_usec(6);
}
if(!(RFSTATUS & TX_ACTIVE)) {
PRINTF("cc2430_rf: TX never active.\n");
cc2430_rf_command(ISFLUSHTX);
ret = RADIO_TX_ERR;
} else {
/* Wait for the transmission to finish */
while(RFSTATUS & TX_ACTIVE);
RF_RX_LED_OFF();
RF_TX_LED_ON();
ret = RADIO_TX_OK;
// rf_flags |= TX_ON_AIR;
}
ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
if(rf_flags & WAS_OFF) {
off();
}
RIMESTATS_ADD(lltx);
/* OK, sent. We are now ready to send more */
return ret;
}
/*---------------------------------------------------------------------------*/
static int
send(void *payload, unsigned short payload_len)
{
prepare(payload, payload_len);
return transmit(payload_len);
}
/*---------------------------------------------------------------------------*/
static int
read(void *buf, unsigned short bufsize)
{
uint8_t i;
uint8_t len;
uint8_t crc_corr;
int8_t rssi;
#if CC2420_CONF_CHECKSUM
uint16_t checksum;
#endif /* CC2420_CONF_CHECKSUM */
/* Don't interrupt us while emptying the FIFO */
#if !NETSTACK_CONF_SHORTCUTS
IEN2 &= ~RFIE;
#endif
#if CC2430_RFERR_INTERRUPT
IEN0 &= ~RFERRIE;
#endif
/* RX interrupt polled the cc2430_rf_process, now read the RX FIFO */
/* Check the length */
len = RFD;
/* Check for validity */
if(len > CC2430_MAX_PACKET_LEN) {
/* Oops, we must be out of sync. */
PRINTF("error: bad sync\n");
RIMESTATS_ADD(badsynch);
flush_rx();
return 0;
}
if(len <= CC2430_MIN_PACKET_LEN) {
PRINTF("error: too short\n");
RIMESTATS_ADD(tooshort);
flush_rx();
return 0;
}
if(len - CHECKSUM_LEN > bufsize) {
PRINTF("error: too long\n");
RIMESTATS_ADD(toolong);
flush_rx();
return 0;
}
#if CC2430_RF_CONF_HEXDUMP
/* If we reach here, chances are the FIFO is holding a valid frame */
uart1_writeb(magic[0]);
uart1_writeb(magic[1]);
uart1_writeb(magic[2]);
uart1_writeb(magic[3]);
uart1_writeb(len);
#endif
PRINTF("cc2430_rf: read = ");
PRINTF("(%d)", len);
len -= CHECKSUM_LEN;
for(i = 0; i < len; ++i) {
((unsigned char *)(buf))[i] = RFD;
#if CC2430_RF_CONF_HEXDUMP
uart1_writeb(((unsigned char *)(buf))[i]);
#endif
PRINTF("%02X", ((unsigned char *)(buf))[i]);
}
PRINTF("\n");
#if CC2430_CONF_CHECKSUM
/* Deal with the checksum */
checksum = RFD * 256;
checksum += RFD;
#endif /* CC2430_CONF_CHECKSUM */
/* Read the RSSI and CRC/Corr bytes */
rssi = ((int8_t) RFD) - 45;
crc_corr = RFD;
#if CC2430_RF_CONF_HEXDUMP
uart1_writeb(rssi);
uart1_writeb(crc_corr);
#endif
/* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */
if(crc_corr & CRC_BIT_MASK) {
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
RIMESTATS_ADD(llrx);
} else {
RIMESTATS_ADD(badcrc);
flush_rx();
return 0;
}
/* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */
if((RFSTATUS & (FIFO | FIFOP)) == FIFOP) {
/*
* If we reach here means that there might be more intact packets in the
* FIFO despite the overflow. This can happen with bursts of small packets.
*
* Only flush if the FIFO is actually empty. If not, then next pass we will
* pick up one more packet or flush due to an error.
*/
if(!RXFIFOCNT) {
flush_rx();
}
}
RF_RX_LED_OFF();
#if !NETSTACK_CONF_SHORTCUTS
IEN2 |= RFIE;
#endif
#if CC2430_RFERR_INTERRUPT
IEN0 |= RFERRIE;
#endif
RFIF &= ~IRQ_FIFOP;
return (len);
}
/*---------------------------------------------------------------------------*/
static int
channel_clear(void)
{
if(!(RFSTATUS & CCA)) {
return CC2430_CCA_BUSY;
}
return CC2430_CCA_CLEAR;
}
/*---------------------------------------------------------------------------*/
static int
receiving_packet(void)
{
/*
* SFD high while transmitting and receiving.
* TX_ACTIVE high only when transmitting
*
* RFSTATUS & (TX_ACTIVE | SFD) == SFD <=> receiving
*/
return (RFSTATUS & (TX_ACTIVE | SFD) == SFD);
}
/*---------------------------------------------------------------------------*/
static int
pending_packet(void)
{
return (RFSTATUS & FIFOP);
}
/*---------------------------------------------------------------------------*/
/**
* Enable RF receiver.
*
*
* \return pdTRUE
* \return pdFALSE bus not free
*/
static int
on(void)
{
rtimer_clock_t t0;
PRINTF("cc2430_rf_rx_enable called\n");
if(!(rf_flags & RX_ACTIVE)) {
t0 = RTIMER_NOW();
rf_flags |= RX_ACTIVE;
IOCFG0 = 0x7f; /* Set the FIFOP threshold 127 */
RSSIH = 0xd2; /* -84dbm = 0xd2 default, 0xe0 -70 dbm */
RFPWR &= ~RREG_RADIO_PD; /* make sure it's powered */
while((RFIF & IRQ_RREG_ON) == 0); /* wait for power up */
/* Make sure the RREG On Interrupt Flag is 0 next time we get called */
RFIF &= ~IRQ_RREG_ON;
cc2430_rf_command(ISRXON);
cc2430_rf_command(ISFLUSHRX);
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME));
}
PRINTF("cc2430_rf_rx_enable done\n");
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* Disable RF receiver.
*
*
* \return pdTRUE
* \return pdFALSE bus not free
*/
static int
off(void)
{
cc2430_rf_command(ISSTOP); /* make sure CSP is not running */
cc2430_rf_command(ISRFOFF);
RFPWR |= RREG_RADIO_PD; /* RF powerdown */
/* Clear the RREG On Interrupt Flag */
RFIF &= ~IRQ_RREG_ON;
rf_flags &= ~RX_ACTIVE;
rf_flags &= ~WAS_OFF;
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
return 1;
}
/*---------------------------------------------------------------------------*/
static radio_result_t
get_value(radio_param_t param, radio_value_t *value)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
/*---------------------------------------------------------------------------*/
static radio_result_t
set_value(radio_param_t param, radio_value_t value)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
/*---------------------------------------------------------------------------*/
static radio_result_t
get_object(radio_param_t param, void *dest, size_t size)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
/*---------------------------------------------------------------------------*/
static radio_result_t
set_object(radio_param_t param, const void *src, size_t size)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
/*---------------------------------------------------------------------------*/
const struct radio_driver cc2430_rf_driver = {
init,
prepare,
transmit,
send,
read,
channel_clear,
receiving_packet,
pending_packet,
on,
off,
get_value,
set_value,
get_object,
set_object
};
/*---------------------------------------------------------------------------*/
#if !NETSTACK_CONF_SHORTCUTS
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(cc2430_rf_process, ev, data)
{
int len;
PROCESS_BEGIN();
while(1) {
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
packetbuf_clear();
len = read(packetbuf_dataptr(), PACKETBUF_SIZE);
if(len > 0) {
packetbuf_set_datalen(len);
NETSTACK_RDC.input();
}
}
PROCESS_END();
}
#endif
/*---------------------------------------------------------------------------*/

View file

@ -1,91 +0,0 @@
/**
* \file
* CC2430 RF driver header file
* \author
* Zach Shelby <zach@sensinode.com>
*/
#ifndef CC2430_RF_H_
#define CC2430_RF_H_
#include "contiki.h"
#include "dev/radio.h"
#include "cc2430_sfr.h"
#if HAVE_RF_DMA
#include "dev/dma.h"
#endif
/* Constants */
typedef enum rf_address_mode_t {
RF_DECODER_NONE = 0,
RF_DECODER_COORDINATOR,
RF_SOFTACK_MONITOR,
RF_MONITOR,
RF_SOFTACK_CLIENT,
RF_DECODER_ON
} rf_address_mode_t;
/*CSP command set*/
#define SSTOP 0xDF
/*this is not a real command but a way of having rf_command
wait until the script is done*/
#define SSTART 0xDE
#define SNOP 0xC0
#define STXCALN 0xC1
#define SRXON 0xC2
#define STXON 0xC3
#define STXONCCA 0xC4
#define SRFOFF 0xC5
#define SFLUSHRX 0xC6
#define SFLUSHTX 0xC7
#define SACK 0xC8
#define SACKPEND 0xC9
#define ISTXCALN 0xE1
#define ISRXON 0xE2
#define ISTXON 0xE3
#define ISTXONCCA 0xE4
#define ISRFOFF 0xE5
#define ISFLUSHRX 0xE6
#define ISFLUSHTX 0xE7
#define ISACK 0xE8
#define ISACKPEND 0xE9
#define ISSTOP 0xFF
#define ISSTART 0xFE
#define MAC_IFS (1200/128)
#define CC2430_MAX_PACKET_LEN 127
#define CC2430_MIN_PACKET_LEN 4
#define CC2430_CCA_CLEAR 1
#define CC2430_CCA_BUSY 0
#ifdef CC2430_CONF_RFERR_INTERRUPT
#define CC2430_RFERR_INTERRUPT CC2430_CONF_RFERR_INTERRUPT
#else
#define CC2430_RFERR_INTERRUPT 0
#endif
extern const struct radio_driver cc2430_rf_driver;
void cc2430_rf_command(uint8_t command);
int8_t cc2430_rf_channel_set(uint8_t channel);
uint8_t cc2430_rf_channel_get();
uint8_t cc2430_rf_power_set(uint8_t new_power);
void cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr);
#if !NETSTACK_CONF_SHORTCUTS
extern void cc2430_rf_ISR(void) __interrupt(RF_VECTOR);
#endif
#if CC2430_RFERR_INTERRUPT
extern void cc2430_rf_error_ISR(void) __interrupt(RFERR_VECTOR);
#endif
#ifdef HAVE_RF_DMA
void rf_dma_callback_isr(void);
#endif
#endif /* CC2430_RF_H_ */

View file

@ -1,112 +0,0 @@
/**
* \file
* CC2430 RF driver
* \author
* Zach Shelby <zach@sensinode.com> (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net>
* (recent updates for the contiki cc2430 port)
*
* Non-bankable code for cc2430 rf driver.
* Interrupt routines must be placed into the HOME bank.
*
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/radio.h"
#include "dev/cc2430_rf.h"
#include "cc2430_sfr.h"
#ifdef RF_LED_ENABLE
#include "dev/leds.h"
#endif
#include "sys/clock.h"
#include "net/packetbuf.h"
#include "net/rime/rimestats.h"
#include "net/netstack.h"
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) do {} while (0)
#endif
#ifdef RF_LED_ENABLE
#define RF_RX_LED_ON() leds_on(LEDS_RED);
#define RF_RX_LED_OFF() leds_off(LEDS_RED);
#define RF_TX_LED_ON() leds_on(LEDS_GREEN);
#define RF_TX_LED_OFF() leds_off(LEDS_GREEN);
#else
#define RF_RX_LED_ON()
#define RF_RX_LED_OFF()
#define RF_TX_LED_ON()
#define RF_TX_LED_OFF()
#endif
#ifdef HAVE_RF_ERROR
uint8_t rf_error = 0;
#endif
PROCESS_NAME(cc2430_rf_process);
#if !NETSTACK_CONF_SHORTCUTS
/*---------------------------------------------------------------------------*/
/**
* RF interrupt service routine.
*
*/
#pragma save
#if CC_CONF_OPTIMIZE_STACK_SIZE
#pragma exclude bits
#endif
void
cc2430_rf_ISR(void) __interrupt(RF_VECTOR)
{
EA = 0;
ENERGEST_ON(ENERGEST_TYPE_IRQ);
/*
* We only vector here if RFSTATUS.FIFOP goes high.
* Just double check the flag.
*/
if(RFIF & IRQ_FIFOP) {
RF_RX_LED_ON();
/* Poll the RF process which calls cc2430_rf_read() */
process_poll(&cc2430_rf_process);
}
S1CON &= ~(RFIF_0 | RFIF_1);
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
EA = 1;
}
#pragma restore
#endif
/*---------------------------------------------------------------------------*/
#if CC2430_RFERR_INTERRUPT
/**
* RF error interrupt service routine.
* Turned off by default, can be turned on in contiki-conf.h
*/
#pragma save
#if CC_CONF_OPTIMIZE_STACK_SIZE
#pragma exclude bits
#endif
void
cc2430_rf_error_ISR(void) __interrupt(RFERR_VECTOR)
{
EA = 0;
TCON_RFERRIF = 0;
#ifdef HAVE_RF_ERROR
rf_error = 254;
#endif
cc2430_rf_command(ISRFOFF);
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISRXON);
RF_RX_LED_OFF();
RF_TX_LED_OFF();
EA = 1;
}
#pragma restore
#endif
/*---------------------------------------------------------------------------*/

View file

@ -1,169 +0,0 @@
/*
* Copyright (c) 2009, 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.
*/
/**
* \file
* Implementation of the clock functions for the cc243x
* \author
* Zach Shelby (zach@sensinode.com) - original
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "sys/clock.h"
#include "sys/etimer.h"
#include "cc2430_sfr.h"
#include "sys/energest.h"
/* Sleep timer runs on the 32k RC osc. */
/* One clock tick is 7.8 ms */
#define TICK_VAL (32768/128) /* 256 */
/*---------------------------------------------------------------------------*/
#if CLOCK_CONF_STACK_FRIENDLY
volatile uint8_t sleep_flag;
#endif
/*---------------------------------------------------------------------------*/
/* Used in sleep timer interrupt for calculating the next interrupt time */
static unsigned long timer_value;
static volatile CC_AT_DATA clock_time_t count = 0; /* Uptime in ticks */
static volatile CC_AT_DATA clock_time_t seconds = 0; /* Uptime in secs */
/*---------------------------------------------------------------------------*/
/*
* Each iteration is ~1.0xy usec, so this function delays for roughly len usec
*/
void
clock_delay_usec(uint16_t len)
{
DISABLE_INTERRUPTS();
while(len--) {
ASM(nop); ASM(nop);
ASM(nop); ASM(nop);
}
ENABLE_INTERRUPTS();
}
/*---------------------------------------------------------------------------*/
/*
* Wait for a multiple of ~8 ms (a tick)
*/
void
clock_wait(clock_time_t i)
{
clock_time_t start;
start = clock_time();
while(clock_time() - start < (clock_time_t)i);
}
/*---------------------------------------------------------------------------*/
CCIF clock_time_t
clock_time(void)
{
return count;
}
/*---------------------------------------------------------------------------*/
CCIF unsigned long
clock_seconds(void)
{
return seconds;
}
/*---------------------------------------------------------------------------*/
void
clock_init(void)
{
CLKCON = OSC32K | TICKSPD2 | TICKSPD1; /* tickspeed 500 kHz for timers[1-4] */
/* Initialize tick value */
timer_value = ST0; /* ST low bits [7:0] */
timer_value += ((unsigned long int)ST1) << 8; /* middle bits [15:8] */
timer_value += ((unsigned long int)ST2) << 16; /* high bits [23:16] */
timer_value += TICK_VAL; /* Init value 256 */
ST2 = (unsigned char)(timer_value >> 16);
ST1 = (unsigned char)(timer_value >> 8);
ST0 = (unsigned char)timer_value;
IEN0_STIE = 1; /* IEN0.STIE acknowledge Sleep Timer Interrupt */
}
/*---------------------------------------------------------------------------*/
#pragma save
#if CC_CONF_OPTIMIZE_STACK_SIZE
#pragma exclude bits
#endif
void
clock_ISR(void) __interrupt(ST_VECTOR)
{
DISABLE_INTERRUPTS();
ENERGEST_ON(ENERGEST_TYPE_IRQ);
/*
* If the Sleep timer throws an interrupt while we are powering down to
* PM1, we need to abort the power down. Clear SLEEP.MODE, this will signal
* main() to abort the PM1 transition
*/
SLEEP &= 0xFC;
/*
* Read value of the ST0:ST1:ST2, add TICK_VAL and write it back.
* Next interrupt occurs after the current time + TICK_VAL
*/
timer_value = ST0;
timer_value += ((unsigned long int)ST1) << 8;
timer_value += ((unsigned long int)ST2) << 16;
timer_value += TICK_VAL;
ST2 = (unsigned char)(timer_value >> 16);
ST1 = (unsigned char)(timer_value >> 8);
ST0 = (unsigned char)timer_value;
++count;
/* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure
that the modulo operation below becomes a logical and and not
an expensive divide. Algorithm from Wikipedia:
http://en.wikipedia.org/wiki/Power_of_two */
#if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0
#error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...).
#error Change CLOCK_CONF_SECOND in contiki-conf.h.
#endif
if(count % CLOCK_CONF_SECOND == 0) {
++seconds;
}
#if CLOCK_CONF_STACK_FRIENDLY
sleep_flag = 1;
#else
if(etimer_pending()
&& (etimer_next_expiration_time() - count - 1) > MAX_TICKS) {
etimer_request_poll();
}
#endif
IRCON_STIF = 0;
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
ENABLE_INTERRUPTS();
}
#pragma restore
/*---------------------------------------------------------------------------*/

View file

@ -1,69 +0,0 @@
/**
* \file
* Driver for the cc2430 DMA controller. Can be assigned to any bank
*
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
* Further Modifications:
* George Oikonomou <oikonomou@users.sourceforge.net>
*
*/
#include "contiki.h"
#include "dev/dma.h"
#include "cc2430_sfr.h"
#if DMA_ON
struct dma_config dma_conf[DMA_CHANNEL_COUNT]; /* DMA Descriptors */
struct process *dma_callback[DMA_CHANNEL_COUNT];
/*---------------------------------------------------------------------------*/
void
dma_init(void)
{
uint16_t tmp_ptr;
memset(dma_conf, 0, 4 * sizeof(dma_config_t));
for(tmp_ptr = 0; tmp_ptr < DMA_CHANNEL_COUNT; tmp_ptr++) {
dma_callback[tmp_ptr] = 0;
}
/* The address of the descriptor for Channel 0 is configured separately */
tmp_ptr = (uint16_t)&(dma_conf[0]);
DMA0CFGH = tmp_ptr >> 8;
DMA0CFGL = tmp_ptr;
/*
* Descriptors for Channels 1-4 must be consecutive in RAM.
* We write the address of the 1st one to the register and the rest are
* derived by the SoC
*/
#if (DMA_CHANNEL_COUNT > 1)
tmp_ptr = (uint16_t)&(dma_conf[1]);
DMA1CFGH = tmp_ptr >> 8;
DMA1CFGL = tmp_ptr;
#endif
IEN1_DMAIE = 1; /* Enable DMA interrupts */
}
/*---------------------------------------------------------------------------*/
/*
* Associate process p with DMA channel c. When a transfer on that channel
* completes, the ISR will poll this process.
*/
void
dma_associate_process(struct process *p, uint8_t c)
{
if((!c) || (c >= DMA_CHANNEL_COUNT)) {
return;
}
if(p) {
dma_conf[c].inc_prio |= 8; /* Enable interrupt generation */
IEN1_DMAIE = 1; /* Make sure DMA interrupts are acknowledged */
}
dma_callback[c] = p;
}
/*---------------------------------------------------------------------------*/
#endif

View file

@ -1,148 +0,0 @@
/**
* \file
* Header file for the cc2430 DMA controller
*
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
* Further Modifications:
* George Oikonomou <oikonomou@users.sourceforge.net>
*/
#ifndef __DMA_H
#define __DMA_H
#include "cc2430_sfr.h"
/* DMA triggers */
#define DMA_T_NONE 0 /* None, DMAREQ.DMAREQx bits start transfer */
#define DMA_T_PREV 1 /* completion of previous channel */
#define DMA_T_T1_CH0 2 /* Timer 1, compare, channel 0 */
#define DMA_T_T1_CH1 3 /* Timer 1, compare, channel 1 */
#define DMA_T_T1_CH2 4 /* Timer 1, compare, channel 2 */
#define DMA_T_T2_COMP 5 /* Timer 2, compare */
#define DMA_T_T2_OVFL 6 /* Timer 2, overflow */
#define DMA_T_T3_CH0 7 /* Timer 3, compare, channel 0 */
#define DMA_T_T3_CH1 8 /* Timer 3, compare, channel 1 */
#define DMA_T_T4_CH0 9 /* Timer 4, compare, channel 0 */
#define DMA_T_T4_CH1 10 /* Timer 4, compare, channel 1 */
#define DMA_T_ST 11 /* Sleep Timer compare */
#define DMA_T_IOC_0 12 /* Port 0 I/O pin input transition */
#define DMA_T_IOC_1 13 /* Port 1 I/O pin input transition */
#define DMA_T_URX0 14 /* USART0 RX complete */
#define DMA_T_UTX0 15 /* USART0 TX complete */
#define DMA_T_URX1 16 /* USART1 RX complete */
#define DMA_T_UTX1 17 /* USART1 TX complete */
#define DMA_T_FLASH 18 /* Flash data write complete */
#define DMA_T_RADIO 19 /* RF packet byte received/transmit */
#define DMA_T_ADC_CHALL 20 /* ADC end of a conversion in a sequence */
#define DMA_T_ADC_CH11 21 /* ADC end of conversion channel 0 in sequence */
#define DMA_T_ADC_CH21 22 /* ADC end of conversion channel 1 in sequence */
#define DMA_T_ADC_CH32 23 /* ADC end of conversion channel 2 in sequence */
#define DMA_T_ADC_CH42 24 /* ADC end of conversion channel 3 in sequence */
#define DMA_T_ADC_CH53 25 /* ADC end of conversion channel 4 in sequence */
#define DMA_T_ADC_CH63 26 /* ADC end of conversion channel 5 in sequence */
#define DMA_T_ADC_CH74 27 /* ADC end of conversion channel 6 in sequence */
#define DMA_T_ADC_CH84 28 /* ADC end of conversion channel 7 in sequence */
#define DMA_T_ENC_DW 29 /* AES processor requests download input data */
#define DMA_T_ENC_UP 30 /* AES processor requests upload output data */
/* variable DMA length modes (VLEN) */
#define DMA_VLEN_LEN (0 << 5) /* Use LEN for transfer count*/
/*
* Transfer the number of bytes/words specified by first byte/word + 1
* (up to a maximum specified by LEN).
* Thus transfer count excludes length byte/word.
*/
#define DMA_VLEN_N1 (1 << 5)
/*
* Transfer the number of bytes/words specified by first byte/word
* (up to a maximum specified by LEN).
* Thus transfer count includes length byte/word.
*/
#define DMA_VLEN_N (2 << 5)
/*
* Transfer the number of bytes/words specified by first byte/word + 2
* (up to a maximum specified by LEN).
*/
#define DMA_VLEN_N2 (3 << 5)
/*
* Transfer the number of bytes/words specified by first byte/word + 3
* (up to a maximum specified by LEN).
*/
#define DMA_VLEN_N3 (4 << 5)
#define DMA_VLEN_RES1 (5 << 5) /* reserved */
#define DMA_VLEN_RES2 (6 << 5) /* reserved */
#define DMA_VLEN_LEN2 (7 << 5) /* Use LEN for transfer count */
/* Transfer Types (Byte 6 [6:5]) */
#define DMA_SINGLE 0x00 /* Single */
#define DMA_BLOCK 0x20 /* Block */
#define DMA_RPT_SINGLE 0x40 /* Repeated single */
#define DMA_RPT_BLOCK 0x60 /* Repeated block */
/* Source Increment Modes (Byte 7 [7:6])*/
#define DMA_SRC_INC_NO 0x00 /* Source No increment */
#define DMA_SRC_INC_1 0x40 /* Source Increment 1 */
#define DMA_SRC_INC_2 0x80 /* Source Increment 2 */
#define DMA_SRC_DEC 0xC0 /* Source Decrement 1 */
/* Source Increment Modes (Byte 7 [5:4])*/
#define DMA_DST_INC_NO 0x00 /* DestinationNo increment */
#define DMA_DST_INC_1 0x10 /* Destination Increment 1 */
#define DMA_DST_INC_2 0x20 /* Destination Increment 2 */
#define DMA_DST_DEC 0x30 /* Destination Decrement 1 */
/* Descriptor Byte 7, Bits[3:0] */
#define DMA_IRQ_MASK_ENABLE 0x08
#define DMA_MODE_7_BIT 0x04
#define DMA_PRIO_HIGHEST 0x03
#define DMA_PRIO_HIGH 0x02
#define DMA_PRIO_GUARANTEED 0x01
#define DMA_PRIO_LOW 0x00
/** DMA configuration structure */
typedef struct dma_config {
uint8_t src_h; /* source address high byte*/
uint8_t src_l; /* source address low byte*/
uint8_t dst_h; /* dest. address high byte*/
uint8_t dst_l; /* dest. address low byte*/
uint8_t len_h; /* [7:5] VLEN, [4:0] length high byte, 5 lowest bits*/
uint8_t len_l; /* length low byte*/
uint8_t wtt; /* 7: wordsize, [6:5] transfer mode, [4:0] trigger */
/* [7:6] src inc, [5:4] dst_inc, 3: IRQ, 2: M8(vlen), [1-0] prio */
uint8_t inc_prio;
} dma_config_t;
#ifdef DMA_CONF_ON
#define DMA_ON DMA_CONF_ON
#else
#define DMA_ON 0
#endif
/* Number of DMA Channels and their Descriptors */
#if DMA_ON
#define DMA_CHANNEL_COUNT 2
extern dma_config_t dma_conf[DMA_CHANNEL_COUNT];
#endif
/* DMA-Related Macros */
#define DMA_ARM(c) (DMAARM |= (1 << c)) /* Arm DMA Channel C */
#define DMA_TRIGGER(c) (DMAREQ |= (1 << c)) /* Trigger DMA Channel C */
/*
* Check Channel C for Transfer Status
* 1: Complete, Pending Interrupt, 0: Incomplete
*/
#define DMA_STATUS(c) (DMAIRQ &(1 << c))
/* Abort Ongoing DMA Transfers on Channel C */
#define DMA_ABORT(c) (DMAARM = ABORT | (1 << c))
#define DMA_ABORT_ALL() (DMAARM = 0x9F) /* Abort ALL Ongoing DMA Transfers */
/* Functions Declarations */
void dma_init(void);
void dma_associate_process(struct process *p, uint8_t c);
/* Only link the ISR when DMA_ON is .... on */
#if DMA_ON
void dma_ISR(void) __interrupt(DMA_VECTOR);
#endif
#endif /*__DMA_H*/

View file

@ -1,73 +0,0 @@
/**
* \file
* DMA driver ISRs
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
*
* DMA interrupt routines, must be stored in HOME bank
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/dma.h"
#include "cc2430_sfr.h"
#if DMA_ON
extern struct process *dma_callback[DMA_CHANNEL_COUNT];
#endif
/*---------------------------------------------------------------------------*/
#ifdef HAVE_RF_DMA
extern void rf_dma_callback_isr(void);
#endif
#ifdef SPI_DMA_RX
extern void spi_rx_dma_callback(void);
#endif
/*---------------------------------------------------------------------------*/
/**
* DMA interrupt service routine.
*
* if callback defined a poll is made to that process
*/
#pragma save
#if CC_CONF_OPTIMIZE_STACK_SIZE
#pragma exclude bits
#endif
void
dma_ISR(void) __interrupt(DMA_VECTOR)
{
#if DMA_ON
uint8_t i;
#endif
EA = 0;
IRCON_DMAIF = 0;
#ifdef HAVE_RF_DMA
if((DMAIRQ & 1) != 0) {
DMAIRQ &= ~1;
DMAARM = 0x81;
rf_dma_callback_isr();
}
#endif
#ifdef SPI_DMA_RX
if((DMAIRQ & 0x08) != 0) {
DMAIRQ &= ~(1 << 3);
spi_rx_dma_callback();
}
#endif
#if DMA_ON
for(i = 0; i < DMA_CHANNEL_COUNT; i++) {
if((DMAIRQ & (1 << i)) != 0) {
DMAIRQ &= ~(1 << i);
if(dma_callback[i] != 0) {
process_poll(dma_callback[i]);
}
}
}
#endif
EA = 1;
}
#pragma restore
/*---------------------------------------------------------------------------*/

View file

@ -1,148 +0,0 @@
/*
* Copyright (c) 2005, 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.
*
*/
#ifndef HWCONF_H_
#define HWCONF_H_
#include "sys/cc.h"
#include <cc2430_sfr.h>
#define HWCONF_PIN(name, port, bit) \
static CC_INLINE void name##_SELECT() {P##port##SEL &= ~(1 << bit);} \
static CC_INLINE void name##_SELECT_IO() {P##port##SEL &= ~(1 << bit);} \
static CC_INLINE void name##_SELECT_PM() {P##port##SEL |= 1 << bit;} \
static CC_INLINE void name##_SET() {P##port##_##bit = 1; } \
static CC_INLINE void name##_CLEAR() {P##port##_##bit = 0; } \
static CC_INLINE unsigned char name##_READ() {return P##port##_##bit; } \
static CC_INLINE void name##_MAKE_OUTPUT() {P##port##DIR |= 1 << bit;} \
static CC_INLINE void name##_MAKE_INPUT() {P##port##DIR &= ~(1 << bit); }
#define HWCONF_IRQ_XXX(name, port, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \
if ( port == 2 ) { PICTL |= P2IEN; p2ien |= 1<<bit; IEN2 |= P2IE; } \
if (( port == 0) && ( bit <4)) { PICTL |= P0IENL; p0ien |= 1<<bit; IEN1 |= P0IE; } \
if ((port == 0) && ( bit >=4)) { PICTL |= P0IENH; p0ien |= 1<<bit; IEN1 |= P0IE; } \
if ( port == 1) { P##port##IEN |= 1 << bit; IEN2 |= P1IE; } \
} \
static CC_INLINE void name##_DISABLE_IRQ() { \
if ( port == 2 ) { \
p2ien &= ~(1<<bit); \
if (p2ien==0) PICTL &= ~P2IEN; \
} \
if (( port == 0) && ( bit <4)) { \
p0ien &= ~(1<<bit); \
if ((p0ien&0xf)==0) PICTL &= ~P0IENL; \
} \
if (( port == 0) && ( bit >=4)) { \
p0ien &= ~(1<<bit); \
if ((p0ien&0xf0)==0) PICTL &= ~P0IENH; \
} \
if ( port == 1) { P##port##IEN &= ~(1 << bit); } \
} \
static CC_INLINE int name##_IRQ_ENABLED() {return P##port##IEN & (1 << bit);} \
static CC_INLINE int name##_CHECK_IRQ() {return P##port##IFG & (1 << bit);} \
static CC_INLINE void name##_IRQ_FLAG_OFF() { \
P##port##IFG &= ~(1 << bit); \
if (port == 0) {IRCON &= ~P0IF;} \
else {IRCON2 &= ~P##port##IF;} \
}
#define HWCONF_IRQ(name, port, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \
if ( port == 1) { P##port##IEN |= 1 << bit; } \
} \
static CC_INLINE void name##_DISABLE_IRQ() { \
if ( port == 1) { P##port##IEN &= ~(1 << bit); } \
} \
static CC_INLINE int name##_IRQ_ENABLED() {return P##port##IEN & (1 << bit);} \
static CC_INLINE int name##_CHECK_IRQ() {return P##port##IFG & (1 << bit);} \
static CC_INLINE int name##_IRQ_PORT() {return IRQ_PORT##port;}
#define HWCONF_PORT_0_IRQ(name, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \
if ( bit <4 ) { PICTL |= P0IENL; p0ien |= 1<<bit; IEN1 |= P0IE; } \
if ( bit >=4 ) { PICTL |= P0IENH; p0ien |= 1<<bit; IEN1 |= P0IE; } \
} \
static CC_INLINE void name##_DISABLE_IRQ() { \
if ( bit <4) { \
p0ien &= ~(1<<bit); \
if ((p0ien&0xf)==0) PICTL &= ~P0IENL; \
} \
if ( bit >=4) { \
p0ien &= ~(1<<bit); \
if ((p0ien&0xf0)==0) PICTL &= ~P0IENH; \
} \
} \
static CC_INLINE int name##_IRQ_ENABLED() {return p0ien & (1 << bit);} \
static CC_INLINE void name##_IRQ_EDGE_SELECTD() {PICTL |= P0ICON;} \
static CC_INLINE void name##_IRQ_EDGE_SELECTU() {PICTL &= ~P0ICON;} \
static CC_INLINE int name##_CHECK_IRQ() {return P0IFG & (1 << bit);} \
static CC_INLINE void name##_IRQ_FLAG_OFF() { \
IRCON_P0IF = 0; \
P0IFG = 0; \
}
#define HWCONF_PORT_1_IRQ(name, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { P1IEN |= 1 << bit; IEN2 |= P1IE; } \
static CC_INLINE void name##_DISABLE_IRQ() { \
P1IEN &= ~(1 << bit); \
if (P1IEN == 0) { IEN2 &= ~P1IE; } \
} \
static CC_INLINE int name##_IRQ_ENABLED() { return P1IEN & (1 << bit); } \
static CC_INLINE void name##_IRQ_EDGE_SELECTD() {PICTL |= P1ICON;} \
static CC_INLINE void name##_IRQ_EDGE_SELECTU() {PICTL &= ~P1ICON;} \
static CC_INLINE int name##_CHECK_IRQ() { return P1IFG & (1 << bit); } \
static CC_INLINE void name##_IRQ_FLAG_OFF() { \
IRCON2_P1IF = 0; \
P1IFG = 0; \
}
#define HWCONF_PORT_2_IRQ(name, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \
PICTL |= P2IEN; \
p2ien |= 1<<bit; \
IEN2 |= P2IE; \
} \
static CC_INLINE void name##_DISABLE_IRQ() { \
p2ien &= ~(1<<bit); \
if (p2ien==0) { PICTL &= ~P2IEN; IEN2 &= ~P2IE; } \
} \
static CC_INLINE int name##_IRQ_ENABLED() {return p2ien & (1 << bit);} \
static CC_INLINE void name##_IRQ_EDGE_SELECTD() {PICTL |= P2ICON;} \
static CC_INLINE void name##_IRQ_EDGE_SELECTU() {PICTL &= ~P2ICON;} \
static CC_INLINE int name##_CHECK_IRQ() {return P2IFG & (1 << bit);} \
static CC_INLINE void name##_IRQ_FLAG_OFF() { \
IRCON2_P2IF = 0; \
P2IFG = 0; \
}
#endif /* HWCONF_H_ */

View file

@ -1,57 +0,0 @@
/*
* 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 cc2430 Low Power Modes (LPM)
* We currently support the following:
* - Set MCU IDLE while in PM0. This is working as intended
* - Drop to PM1. This results in incoming radio packet losses.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef LPM_H_
#define LPM_H_
#include "contiki-conf.h"
#define LPM_MODE_NONE 0 /* No LPM - Always on */
#define LPM_MODE_IDLE 1 /* Set MCU Idle as part of the main loop */
#define LPM_MODE_PM2 2 /* Drop to PM1 - causes radio packet losses for now */
#ifdef LPM_CONF_MODE
#define LPM_MODE LPM_CONF_MODE
#else
#define LPM_MODE LPM_MODE_IDLE
#endif /* LPM_CONF_MODE */
#endif /* LPM_H_ */

View file

@ -1,135 +0,0 @@
/*
* 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
* Random number generator routines exploiting the cc2430 hardware
* capabilities.
*
* This file overrides core/lib/random.c.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "cc2430_sfr.h"
#include "dev/cc2430_rf.h"
/*---------------------------------------------------------------------------*/
/**
* \brief Generates a new random number using the cc2430 RNG.
* \return The random number.
*/
unsigned short
random_rand(void)
{
/* Clock the RNG LSFR once */
ADCCON1 |= ADRCTRL0;
return (RNDL | (RNDH << 8));
}
/*---------------------------------------------------------------------------*/
/**
* \brief Seed the cc2430 random number generator.
* \param seed Seed value for the RNG.
*
* If the SEED argument is 0, seed the RNG with IF_ADC as
* discussed in the cc2430 datasheet (rev. 2.1), section 13.11.2.2,
* page 134. Seeding with this method should not be done during
* normal radio operation. Thus, use this function before
* initialising the network.
*
* If the SEED is provided, seed with this value instead. This will
* result in the same sequence of random numbers each time the node
* reboots. So, don't use it unless you have a reason (e.g. tests)
*/
void
random_init(unsigned short seed)
{
int i;
/* Comment out this if() block to save a nice 16 bytes of code size */
if(seed) {
/* If the caller provides a seed, write the high-byte first and then
* write the low byte */
RNDL = seed >> 8; /* High byte first */
RNDL = seed & 0xFF;
return;
}
/*
* cc2430 Datasheet:
* "When a true random value is required, the LFSR should be seeded by
* writing RNDL with random values from the IF_ADC in the RF receive path."
*
* "To use this seeding method, the radio must first be powered on by
* enabling the voltage regulator"
*/
RFPWR &= ~RREG_RADIO_PD; /* Turn on the voltage regulator */
while(!(RFIF & IRQ_RREG_ON)); /* Wait for power up*/
/* OK, it's powered. The respective interrupt flag has been set, clear it */
RFIF &= ~IRQ_RREG_ON;
/*
* "The radio should be placed in infinite TX state, to avoid possible sync
* detect in RX state."
*
* Judging by old chipcon cc2430 code examples as well as by the way cc2530
* works, this is very likely to be "RX state" (i.e. a typo in the datasheet)
*
* With infinite TX, ADCTSTx always read as 0 so we'll use infinite RX
*/
MDMCTRL1L = 0x02; /* RX mode 10 - RX_INFINITE state */
/* "Enter RX State - Immediate" command strobe */
cc2430_rf_command(ISRXON);
/* Make sure the RNG is on */
ADCCON1 &= ~(ADRCTRL1 | ADRCTRL0);
/* Wait for IF_ADC I-branch and Q-branch values */
while(!(ADCTSTH & ADCTSTL));
/* 32 times as per the chipcon example. This seems to increase randomness */
for(i = 0; i < 32; i++) {
/* Seed the RNG by writing into RNDL twice with values from ADCTSTx */
RNDL = ADCTSTH;
RNDL = ADCTSTL;
/* Clock the RNG LSFR once */
ADCCON1 |= ADRCTRL0;
}
/*
* Exit RX state. Just shut down, network initialisation will take care of
* properly starting the radio for us.
*/
RFPWR |= RREG_RADIO_PD;
}

View file

@ -1,43 +0,0 @@
#ifndef UART_H
#define UART_H
#include "contiki-conf.h"
#include "cc2430_sfr.h"
#include "8051def.h"
/*---------------------------------------------------------------------------*/
/* UART BAUD Rates */
/*
* Macro to set speed of UART N by setting the UnBAUD SFR to M and the
* UnGCR SRF to E. See the cc2430 datasheet for possible values of M and E
*/
#define UART_SET_SPEED(N, M, E) do{ U##N##BAUD = M; U##N##GCR = E; } while(0)
/*
* Sample Values for M and E in the macro above to achieve some common BAUD
* rates. For more values, see the cc2430 datasheet
*/
/* 2000000 - cc2430 theoretical MAX when using the 32MHz clock */
#define UART_2K_M 0
#define UART_2K_E 16
/* 1000000 - cc2430 theoretical MAX when using the 16MHz clock */
#define UART_1K_M 0
#define UART_1K_E 15
/* 921600 */
#define UART_921_M 216
#define UART_921_E 14
/* 460800 Higher values lead to problems when the node needs to RX */
#define UART_460_M 216
#define UART_460_E 13
/* 115200 */
#define UART_115_M 216
#define UART_115_E 11
/* 38400 */
#define UART_38_M 59
#define UART_38_E 10
/* 9600 */
#define UART_9_M 59
#define UART_9_E 8
#endif /* UART_H */

View file

@ -1,69 +0,0 @@
/**
* \file
*
* uart0 write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
*/
#include <stdlib.h>
#include <string.h>
#include "cc2430_sfr.h"
#include "dev/uart0.h"
#if UART_ZERO_ENABLE
/*---------------------------------------------------------------------------*/
void
uart0_init()
{
UART_SET_SPEED(0, UART_115_M, UART_115_E);
#ifdef UART0_ALTERNATIVE_2
PERCFG |= U0CFG; /*alternative port 2 = P1.5-2*/
#ifdef UART0_RTSCTS
P1SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P1SEL |= 0x30; /*peripheral select for TX and RX*/
P1 &= ~0x08; /*RTS down*/
#endif
P1DIR |= 0x28; /*RTS, TX out*/
P1DIR &= ~0x14; /*CTS & RX in*/
#else
PERCFG &= ~U0CFG; /*alternative port 1 = P0.5-2*/
#ifdef UART0_RTSCTS
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P0SEL |= 0x0C; /*peripheral select for TX and RX*/
P0 &= ~0x20; /*RTS down*/
#endif
P0DIR |= 0x28; /*RTS & TX out*/
P0DIR &= ~0x14; /*CTS & RX in*/
#endif
#ifdef UART0_RTSCTS
U0UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/
#else
U0UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/
#endif
U0CSR = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
}
/*---------------------------------------------------------------------------*/
/* Write one byte over the UART. */
void
uart0_writeb(uint8_t byte)
{
IRCON2_UTX0IF = 0;
U0BUF = byte;
while(!IRCON2_UTX0IF); /* Wait until byte has been transmitted. */
IRCON2_UTX0IF = 0;
}
#endif

View file

@ -1,31 +0,0 @@
#ifndef UART_0_H
#define UART_0_H
#include "contiki-conf.h"
#include "cc2430_sfr.h"
#include "8051def.h"
#include "uart.h"
/*---------------------------------------------------------------------------*/
/* UART0 Enable - Disable */
#ifdef UART_ZERO_CONF_ENABLE
#define UART_ZERO_ENABLE UART_ZERO_CONF_ENABLE
#else
#define UART_ZERO_ENABLE 0
#endif
/*---------------------------------------------------------------------------*/
/* UART0 Function Declarations */
#if UART_ZERO_ENABLE
void uart0_init();
void uart0_writeb(uint8_t byte);
void uart0_set_input(int (* input)(unsigned char c));
void uart0_rx_ISR(void) __interrupt(URX0_VECTOR);
void uart0_tx_ISR(void) __interrupt(UTX0_VECTOR);
/* Macro to turn on / off UART RX Interrupt */
#define UART0_RX_INT(v) do { IEN0_URX0IE = v; } while(0)
#endif
#endif /* UART_0_H */

View file

@ -1,74 +0,0 @@
/**
* \file
*
* uart1 write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
*/
#include <stdlib.h>
#include <string.h>
#include "cc2430_sfr.h"
#include "dev/uart1.h"
#if UART_ONE_ENABLE
/*---------------------------------------------------------------------------*/
/* UART1 initialization */
void
uart1_init()
{
#ifdef UART1_ALTERNATIVE_1
PERCFG &= ~U1CFG; /*alternative port 1 = P0.5-2*/
#ifdef UART1_RTSCTS
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#else
P0SEL |= 0x30; /*peripheral select for TX and RX*/
P0 &= ~0x08; /*RTS down*/
#endif
P0DIR |= 0x18; /*RTS, TX out*/
P0DIR &= ~0x24; /*CTS, RX in*/
#else
PERCFG |= U1CFG; /*alternative port 2 = P1.7-4*/
#ifdef UART1_RTSCTS
P1SEL |= 0xF0; /*peripheral select for TX and RX*/
#else
P1SEL |= 0xC0; /*peripheral select for TX and RX*/
P1 &= ~0x20; /*RTS down*/
#endif
P1DIR |= 0x60; /*RTS, TX out*/
P1DIR &= ~0x90; /*CTS, RX in*/
#endif
#if UART_ONE_CONF_HIGH_SPEED
UART_SET_SPEED(1, UART_460_M, UART_460_E);
#else
UART_SET_SPEED(1, UART_115_M, UART_115_E);
#endif
#ifdef UART1_RTSCTS
U1UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/
#else
U1UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/
#endif
U1CSR = U_MODE | U_RE; /* UART mode, receiver enable */
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
}
/*---------------------------------------------------------------------------*/
/* Write one byte over the UART. */
void
uart1_writeb(uint8_t byte)
{
IRCON2_UTX1IF = 0;
U1BUF = byte;
while(!IRCON2_UTX1IF); /* Wait until byte has been transmitted. */
IRCON2_UTX1IF = 0;
}
/*---------------------------------------------------------------------------*/
#endif

View file

@ -1,39 +0,0 @@
#ifndef UART_1_H
#define UART_1_H
#include "contiki-conf.h"
#include "cc2430_sfr.h"
#include "8051def.h"
#include "uart.h"
/*---------------------------------------------------------------------------*/
/* UART1 Enable - Disable */
#ifdef UART_ONE_CONF_ENABLE
#define UART_ONE_ENABLE UART_ONE_CONF_ENABLE
#else
#define UART_ONE_ENABLE 0
#endif
/*---------------------------------------------------------------------------*/
/* UART1 Function Declarations */
#if UART_ONE_ENABLE
void uart1_init();
void uart1_writeb(uint8_t byte);
void uart1_set_input(int (*input)(unsigned char c));
#if UART_ONE_CONF_WITH_INPUT
void uart1_rx_ISR(void) __interrupt(URX1_VECTOR);
void uart1_tx_ISR(void) __interrupt(UTX1_VECTOR);
/* Macro to turn on / off UART RX Interrupt */
#define UART1_RX_INT(v) do { IEN0_URX1IE = v; } while(0)
#else
#define UART1_RX_INT(v)
#endif /* UART_ONE_CONF_WITH_INPUT */
#else
#define uart1_init(...)
#define uart1_writeb(...)
#define uart1_set_input(...)
#define UART1_RX_INT(v)
#endif /* UART_ONE_ENABLE */
#endif /* UART_1_H */

View file

@ -1,91 +0,0 @@
/**
* \file
*
* uart write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
* interrupt routines which must be in HOME bank. handles received data from UART.
*
*/
#include <stdlib.h>
#include <string.h>
#include "cc2430_sfr.h"
#include "dev/leds.h"
#include "dev/uart0.h"
#include "dev/uart1.h"
#include "sys/energest.h"
#if UART_ZERO_ENABLE
static int (* uart0_input_handler)(unsigned char c);
#endif
#if UART_ONE_ENABLE
static int (* uart1_input_handler)(unsigned char c);
#endif
#if UART_ZERO_ENABLE
/*---------------------------------------------------------------------------*/
void
uart0_set_input(int (* input)(unsigned char c))
{
uart0_input_handler = input;
}
/*---------------------------------------------------------------------------*/
#pragma save
#if CC_CONF_OPTIMIZE_STACK_SIZE
#pragma exclude bits
#endif
void
uart0_rx_ISR(void) __interrupt(URX0_VECTOR)
{
ENERGEST_ON(ENERGEST_TYPE_IRQ);
TCON_URX0IF = 0;
if(uart0_input_handler != NULL) {
uart0_input_handler(U0BUF);
}
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}
/*---------------------------------------------------------------------------*/
void
uart0_tx_ISR(void) __interrupt(UTX0_VECTOR)
{
}
#pragma restore
#endif /* UART_ZERO_ENABLE */
#if UART_ONE_ENABLE
/*---------------------------------------------------------------------------*/
void
uart1_set_input(int (* input)(unsigned char c))
{
uart1_input_handler = input;
}
/*---------------------------------------------------------------------------*/
#if UART_ONE_CONF_WITH_INPUT
#pragma save
#if CC_CONF_OPTIMIZE_STACK_SIZE
#pragma exclude bits
#endif
void
uart1_rx_ISR(void) __interrupt(URX1_VECTOR)
{
ENERGEST_ON(ENERGEST_TYPE_IRQ);
TCON_URX1IF = 0;
if(uart1_input_handler != NULL) {
uart1_input_handler(U1BUF);
}
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}
/*---------------------------------------------------------------------------*/
void
uart1_tx_ISR(void) __interrupt(UTX1_VECTOR)
{
}
#pragma restore
/*---------------------------------------------------------------------------*/
#endif /* UART_ONE_CONF_WITH_INPUT */
#endif /* UART_ONE_ENABLE */

View file

@ -1,72 +0,0 @@
/*
* 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
* Hardware-dependent header file for the cc2430 watchdog timer.
*
* The interrupt service routine's prototype must be included by the
* file containing main().
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef WATCHDOG_CC2430_H_
#define WATCHDOG_CC2430_H_
#include "dev/watchdog.h"
#include "cc2430_sfr.h"
#include "contiki-conf.h"
#define WDT_TIMEOUT_1_SEC 0x00
#define WDT_TIMEOUT_250_MSEC WDT_INT0
#define WDT_TIMEOUT_15_MSEC WDT_INT1
#define WDT_TIMEOUT_2_MSEC WDT_INT1 | WDT_INT0
#if WDT_CONF_TIMER_MODE
#define WDT_TIMER_MODE WDT_MODE /* Timer */
#else
#define WDT_TIMER_MODE 0x00 /* Watchdog */
#endif
#ifdef WDT_CONF_INTERVAL
#define WDT_INTERVAL WDT_CONF_INTERVAL
#else
#define WDT_INTERVAL WDT_TIMEOUT_1_SEC /* 2 secs */
#endif
/* The watchdog only throws interrupts in timer mode */
#if WDT_TIMER_MODE
void cc4230_watchdog_ISR(void) __interrupt (WDT_VECTOR);
#endif
#endif /* WATCHDOG_CC2430_H_ */

View file

@ -1,49 +0,0 @@
/*
* 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. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* \file
* Stub header file for cc2430 multi-threading. It doesn't do anything, it
* just exists so that mt.c can compile cleanly.
*
* This is based on the original mtarch.h for z80 by Takahide Matsutsuka
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef MTARCH_H_
#define MTARCH_H_
struct mtarch_thread {
unsigned char *sp;
};
#endif /* MTARCH_H_ */

View file

@ -1,127 +0,0 @@
/*
* 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
* Hardware-dependent functions used to support the
* contiki rtimer module.
*
* clock and etimer are using the sleep timer on the cc2430
*
* clock_init() has set our tick speed prescaler already, so we
* are ticking with 500 kHz freq.
*
* rtimer_clock_t is unsigned short (16bit on the cc2430)
* It thus makes sense to use the 16bit clock (Timer 1)
*
* This file contains an ISR and must reside in the HOME bank
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "sys/rtimer.h" /* Includes rtimer-arch.h for us */
#include "cc2430_sfr.h"
#include "sys/energest.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
void
rtimer_arch_init(void)
{
PRINTF("rtimer_arch_init() ");
/*
* - Free running mode
* - Prescale by 32:
* Tick Speed has been prescaled to 500 kHz already in clock_init()
* We further prescale by 32 resulting in 15625 Hz for this timer.
*/
T1CTL = (T1DIV1 | T1MODE0); /* 00001001 */
PRINTF("T1CTL=0x%02x\n", T1CTL);
/* Acknowledge Timer 1 Interrupts */
IEN1_T1IE = 1;
PRINTF("IEN1_T1IE=0x%02x\n", IEN1_T1IE);
/* Timer 1, Channel 1. Compare Mode (0x04), Interrupt mask on (0x40) */
T1CCTL1 = T1MODE + T1IM;
PRINTF("T1CCTL1=0x%02x\n", T1CCTL1);
/* Interrupt Mask Flags: No interrupt on overflow */
TIMIF &= ~OVFIM;
PRINTF("TIMIF=0x%02x\n", TIMIF);
PRINTF("done\n");
}
/*---------------------------------------------------------------------------*/
void
rtimer_arch_schedule(rtimer_clock_t t)
{
PRINTF("rtimer_arch_schedule(%u)\n", t);
/* set the compare mode values so we can get an interrupt after t */
T1CC1L = (unsigned char)t;
T1CC1H = (unsigned char)(t >> 8);
PRINTF("T1CC1=%u, t=%u\n", (T1CC1L + (T1CC1H << 8)), t);
/* Turn on compare mode interrupt */
PRINTF("T1CTL=0x%02x\n", T1CTL);
T1CCTL1 |= T1IM;
}
/*---------------------------------------------------------------------------*/
#pragma save
#if CC_CONF_OPTIMIZE_STACK_SIZE
#pragma exclude bits
#endif
void
cc2430_timer_1_ISR(void) __interrupt(T1_VECTOR)
{
IEN1_T1IE = 0; /* Ignore Timer 1 Interrupts */
ENERGEST_ON(ENERGEST_TYPE_IRQ);
/* No more interrupts from Channel 1 till next rtimer_arch_schedule() call.
* Setting the mask will instantly generate an interrupt so we clear the
* flag first. */
T1CTL &= ~(CH1IF);
T1CCTL1 &= ~T1IM;
rtimer_run_next();
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
IEN1_T1IE = 1; /* Acknowledge Timer 1 Interrupts */
}
#pragma restore

View file

@ -1,62 +0,0 @@
/*
* 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.
*
*/
/**
* \file
* Hardware-dependent function declarations used to
* support the contiki rtimer module.
*
* We use Timer 1 on the cc2431.
*
* \author
* Zach Shelby (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net>
* (rtimer-arch implementation for cc2430)
*/
#ifndef RTIMER_ARCH_H_
#define RTIMER_ARCH_H_
#include "contiki-conf.h"
#include "cc2430_sfr.h"
/*
* 32 MHz clock, prescaled down to 500 kHz for all 4 timers in clock_init().
* Further prescaled factor 32 for T1, thus T1 is 15625 Hz
*/
#define RTIMER_ARCH_SECOND (15625U)
#define rtimer_arch_now() ((rtimer_clock_t)(T1CNTL + (T1CNTH << 8)))
void cc2430_timer_1_ISR(void) __interrupt(T1_VECTOR);
#endif /* RTIMER_ARCH_H_ */

View file

@ -1,26 +0,0 @@
# segment.rules files assign source code modules to specific banks
# These files are only used when we build code with banking (HAVE_BANKING=1)
# The final segment.rules file is constructed from any segment.rules found in
# the search path, defined in Makefile.cc2430
# When building bankable code, the bank-alloc.py script automatically allocates
# modules to banks. segment.rules files provide hints, instructing the script
# as to which files are safe to move around and which files to leave alone
# In other words, only specify a rule for a file if you need to
# comments starting with "#" are supported
# The file spec in rules is actually interpreted as a python regex so you can
# write a rule that will match multiple files
#
# general rules --
# This file is only used when the Makefile defines HAVE_BANKING=1
# SDCC's standard libraries will always go in CSEG - We don't touch them
# Interrupt code must be in HOME. Specify all files with an ISR here
# All files without an associated rule get allocated to a bank automatically
# Files with ISRs must be in HOME
HOME intr.c # Match all files ending in intr.c (e.g. uart_intr.c)
HOME rtimer-arch.c
HOME watchdog-cc2430.c
HOME clock.c
# Some cc2430 files which need special treatment
HOME bus.c # bus.c::flash_read() must be run from HOME (if compiled in)

View file

@ -1,71 +0,0 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 AUTHOR 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
* 8051 stack debugging facilities
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
* Philippe Retornaz (EPFL)
*/
#include "contiki.h"
#ifndef STACK_POISON
#define STACK_POISON 0xAA
#endif
CC_AT_DATA uint8_t sp;
void
stack_poison(void)
{
__asm
mov r1, _SP
poison_loop:
inc r1
mov @r1, #STACK_POISON
cjne r1, #0xFF, poison_loop
__endasm;
}
uint8_t
stack_get_max(void)
{
__data uint8_t *sp = (__data uint8_t *)0xff;
uint8_t free = 0;
while(*sp-- == STACK_POISON) {
free++;
}
return 0xff - free;
}

View file

@ -1,68 +0,0 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 AUTHOR 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 8051 stack debugging facilities
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
* Philippe Retornaz (EPFL)
*/
#ifndef STACK_H_
#define STACK_H_
#if STACK_CONF_DEBUGGING
extern CC_AT_DATA uint8_t sp;
#define stack_dump(f) do { \
putstring(f); \
sp = SP; \
puthex(sp); \
putchar('\n'); \
} while(0)
#define stack_max_sp_print(f) do { \
putstring(f); \
puthex(stack_get_max()); \
putchar('\n'); \
} while(0)
void stack_poison(void);
uint8_t stack_get_max(void);
#else
#define stack_dump(...)
#define stack_max_sp_print(...)
#define stack_poison()
#define stack_get_max()
#endif
#endif /* STACK_H_ */

View file

@ -53,7 +53,8 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm
### CPU-dependent source files
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c
CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c ccm.c sha256.c
CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c cbc-mac.c gcm.c
CONTIKI_CPU_SOURCEFILES += ccm.c sha256.c
CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c

View file

@ -50,12 +50,12 @@
* bignum_divide_start bignum_divide_get_result (division)
* bignum_cmp_start bignum_cmp_get_result (comparison)
*/
#include "bignum-driver.h"
#include "dev/bignum-driver.h"
#include "stdio.h"
#include <stdio.h>
#include "reg.h"
#include "nvic.h"
#include "dev/nvic.h"
#define ASSERT(IF) if(!(IF)) { return PKA_STATUS_INVALID_PARAM; }

View file

@ -59,7 +59,7 @@
#define BIGNUM_DRIVER_H_
#include "contiki.h"
#include "pka.h"
#include "dev/pka.h"
#include <stdint.h>

91
cpu/cc2538/dev/cbc-mac.c Normal file
View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2016, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-cbc-mac
* @{
*
* \file
* Implementation of the cc2538 AES-CBC-MAC driver
*/
#include "contiki.h"
#include "dev/rom-util.h"
#include "dev/cbc-mac.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
uint8_t
cbc_mac_auth_start(uint8_t key_area, const void *mdata, uint16_t mdata_len,
struct process *process)
{
uint32_t ctrl;
uint32_t iv[AES_IV_LEN / sizeof(uint32_t)];
/* Program AES-CBC-MAC authentication operation */
ctrl = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */
AES_AES_CTRL_CBC_MAC | /* CBC-MAC */
AES_AES_CTRL_DIRECTION_ENCRYPT; /* Encryption */
/* Prepare the crypto initialization vector
* Set initialization vector to 0 */
rom_util_memset(iv, 0, AES_IV_LEN);
return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0,
mdata, NULL, mdata_len, process);
}
/*---------------------------------------------------------------------------*/
uint8_t
cbc_mac_auth_get_result(const void *mac_in, void *mac_out)
{
uint32_t tag[AES_TAG_LEN / sizeof(uint32_t)];
uint8_t ret;
ret = aes_auth_crypt_get_result(NULL, tag);
if(ret != CRYPTO_SUCCESS) {
return ret;
}
if(mac_in != NULL) {
/* Check MAC */
if(rom_util_memcmp(tag, mac_in, CBC_MAC_MAC_LEN)) {
ret = AES_AUTHENTICATION_FAILED;
}
}
if(mac_out != NULL) {
/* Copy tag to MAC */
rom_util_memcpy(mac_out, tag, CBC_MAC_MAC_LEN);
}
return ret;
}
/** @} */

98
cpu/cc2538/dev/cbc-mac.h Normal file
View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2016, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-aes
* @{
*
* \defgroup cc2538-cbc-mac cc2538 AES-CBC-MAC
*
* Driver for the cc2538 AES-CBC-MAC mode of the security core
* @{
*
* \file
* Header file for the cc2538 AES-CBC-MAC driver
*/
#ifndef CBC_MAC_H_
#define CBC_MAC_H_
#include "contiki.h"
#include "dev/aes.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \name AES-CBC-MAC constants
* @{
*/
#define CBC_MAC_MAC_LEN AES_TAG_LEN
/** @} */
/*---------------------------------------------------------------------------*/
/** \name AES-CBC-MAC functions
* @{
*/
/** \brief Starts a CBC-MAC authentication operation
* \param key_area Area in Key RAM where the key is stored (0 to
* \c AES_KEY_AREAS - 1)
* \param mdata Pointer to message to authenticate in SRAM
* \param mdata_len Length of message to authenticate in octets
* \param process Process to be polled upon completion of the operation, or
* \c NULL
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC-MAC error code
* \warning CBC-MAC is not secure for variable-length messages. There are a few
* workarounds that can be implemented by the caller, like prepending the
* message length to the first block of the message before passing it.
*/
uint8_t cbc_mac_auth_start(uint8_t key_area, const void *mdata,
uint16_t mdata_len, struct process *process);
/** \brief Checks the status of the CBC-MAC authentication operation
* \retval false Result not yet available, and no error occurred
* \retval true Result available, or error occurred
*/
#define cbc_mac_auth_check_status aes_auth_crypt_check_status
/** \brief Gets the result of the CBC-MAC authentication operation
* \param mac_in Pointer to 128-bit input MAC, or \c NULL
* \param mac_out Pointer to 128-bit output MAC, or \c NULL
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC-MAC error code
* \note This function must be called only after \c cbc_mac_auth_start().
*/
uint8_t cbc_mac_auth_get_result(const void *mac_in, void *mac_out);
/** @} */
#endif /* CBC_MAC_H_ */
/**
* @}
* @}
*/

66
cpu/cc2538/dev/cbc.c Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-cbc
* @{
*
* \file
* Implementation of the cc2538 AES-CBC driver
*/
#include "contiki.h"
#include "dev/cbc.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
uint8_t
cbc_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv,
const void *mdata_in, void *mdata_out, uint16_t mdata_len,
struct process *process)
{
uint32_t ctrl;
/* Program AES-CBC crypto operation */
ctrl = AES_AES_CTRL_CBC | /* CBC */
(encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */
return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0,
mdata_in, mdata_out, mdata_len, process);
}
/*---------------------------------------------------------------------------*/
int8_t
cbc_crypt_check_status(void)
{
return aes_auth_crypt_check_status() ? aes_auth_crypt_get_result(NULL, NULL) :
CRYPTO_PENDING;
}
/** @} */

92
cpu/cc2538/dev/cbc.h Normal file
View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2015, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-aes
* @{
*
* \defgroup cc2538-cbc cc2538 AES-CBC
*
* Driver for the cc2538 AES-CBC mode of the security core
* @{
*
* \file
* Header file for the cc2538 AES-CBC driver
*/
#ifndef CBC_H_
#define CBC_H_
#include "contiki.h"
#include "dev/aes.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \name AES-CBC constants
* @{
*/
#define CBC_IV_LEN AES_IV_LEN
/** @} */
/*---------------------------------------------------------------------------*/
/** \name AES-CBC functions
* @{
*/
/** \brief Starts a CBC crypto operation
* \param encrypt \c true to encrypt, or \c false to decrypt
* \param key_area Area in Key RAM where the key is stored (0 to
* \c AES_KEY_AREAS - 1)
* \param iv Pointer to 128-bit initialization vector
* \param mdata_in Pointer to input message in SRAM
* \param mdata_out Pointer to output message in SRAM (may be \p mdata_in)
* \param mdata_len Length of message in octets
* \param process Process to be polled upon completion of the operation, or
* \c NULL
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC error code
*/
uint8_t cbc_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv,
const void *mdata_in, void *mdata_out,
uint16_t mdata_len, struct process *process);
/** \brief Checks the status of the CBC crypto operation
* \return \c CRYPTO_PENDING if operation still pending, \c CRYPTO_SUCCESS if
* successful, or CRYPTO/AES/CBC error code
* \note This function must be called only after \c cbc_crypt_start().
*/
int8_t cbc_crypt_check_status(void);
/** @} */
#endif /* CBC_H_ */
/**
* @}
* @}
*/

View file

@ -54,7 +54,7 @@
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \name CCM constants
/** \name AES-CCM constants
* @{
*/
#define CCM_FLAGS_LEN 1

77
cpu/cc2538/dev/ctr.c Normal file
View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2015, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-ctr
* @{
*
* \file
* Implementation of the cc2538 AES-CTR driver
*/
#include "contiki.h"
#include "dev/rom-util.h"
#include "dev/ctr.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
uint8_t
ctr_crypt_start(uint8_t encrypt, uint8_t key_area, const void *nonce,
const void *ictr, uint8_t ctr_len, const void *mdata_in,
void *mdata_out, uint16_t mdata_len, struct process *process)
{
uint32_t ctrl;
uint32_t iv[AES_IV_LEN / sizeof(uint32_t)];
uint8_t nonce_len;
/* Program AES-CTR crypto operation */
ctrl = (((ctr_len >> 2) - 1) << AES_AES_CTRL_CTR_WIDTH_S) | /* CTR width */
AES_AES_CTRL_CTR | /* CTR */
(encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */
/* Prepare the crypto initialization vector */
nonce_len = AES_IV_LEN - ctr_len;
/* Nonce */
rom_util_memcpy(&((uint8_t *)iv)[0], nonce, nonce_len);
/* Initial counter */
rom_util_memcpy(&((uint8_t *)iv)[nonce_len], ictr, ctr_len);
return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0,
mdata_in, mdata_out, mdata_len, process);
}
/*---------------------------------------------------------------------------*/
int8_t
ctr_crypt_check_status(void)
{
return aes_auth_crypt_check_status() ? aes_auth_crypt_get_result(NULL, NULL) :
CRYPTO_PENDING;
}
/** @} */

89
cpu/cc2538/dev/ctr.h Normal file
View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-aes
* @{
*
* \defgroup cc2538-ctr cc2538 AES-CTR
*
* Driver for the cc2538 AES-CTR mode of the security core
* @{
*
* \file
* Header file for the cc2538 AES-CTR driver
*/
#ifndef CTR_H_
#define CTR_H_
#include "contiki.h"
#include "dev/aes.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \name AES-CTR functions
* @{
*/
/** \brief Starts a CTR crypto operation
* \param encrypt \c true to encrypt, or \c false to decrypt
* \param key_area Area in Key RAM where the key is stored (0 to
* \c AES_KEY_AREAS - 1)
* \param nonce Pointer to nonce (\c AES_IV_LEN - \p ctr_len octets), or \c NULL
* \param ictr Pointer to initial counter
* \param ctr_len Length of counter in octets (4, 8, 12, or 16)
* \param mdata_in Pointer to input message in SRAM
* \param mdata_out Pointer to output message in SRAM (may be \p mdata_in)
* \param mdata_len Length of message in octets
* \param process Process to be polled upon completion of the operation, or
* \c NULL
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CTR error code
*/
uint8_t ctr_crypt_start(uint8_t encrypt, uint8_t key_area, const void *nonce,
const void *ictr, uint8_t ctr_len, const void *mdata_in,
void *mdata_out, uint16_t mdata_len,
struct process *process);
/** \brief Checks the status of the CTR crypto operation
* \return \c CRYPTO_PENDING if operation still pending, \c CRYPTO_SUCCESS if
* successful, or CRYPTO/AES/CTR error code
* \note This function must be called only after \c ctr_crypt_start().
*/
int8_t ctr_crypt_check_status(void);
/** @} */
#endif /* CTR_H_ */
/**
* @}
* @}
*/

View file

@ -35,15 +35,15 @@
* \file
* Implementation of the cc2538 ECC Algorithms
*/
#include <contiki.h>
#include <process.h>
#include "contiki.h"
#include "sys/process.h"
#include <limits.h>
#include <stdio.h>
#include "ecc-algorithm.h"
#include "ecc-driver.h"
#include "pka.h"
#include "dev/ecc-algorithm.h"
#include "dev/ecc-driver.h"
#include "dev/pka.h"
#define CHECK_RESULT(...) \
state->result = __VA_ARGS__; \

View file

@ -49,8 +49,8 @@
#ifndef ECC_ALGORITHM_H_
#define ECC_ALGORITHM_H_
#include "bignum-driver.h"
#include "ecc-driver.h"
#include "dev/bignum-driver.h"
#include "dev/ecc-driver.h"
typedef struct {
/* Containers for the State */

View file

@ -32,8 +32,8 @@
* \addtogroup c2538-ecc-curves
* @{
*/
#include <contiki.h>
#include <ecc-driver.h>
#include "contiki.h"
#include "dev/ecc-driver.h"
/* [NIST P-256, X9.62 prime256v1] */
static const uint32_t nist_p_256_p[8] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,

View file

@ -39,7 +39,7 @@
* \file
* Implementation of the cc2538 ECC driver
*/
#include "ecc-driver.h"
#include "dev/ecc-driver.h"
#include "reg.h"
#include "dev/nvic.h"

View file

@ -48,7 +48,7 @@
#define ECC_DRIVER_H_
#include "contiki.h"
#include "pka.h"
#include "dev/pka.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/

125
cpu/cc2538/dev/gcm.c Normal file
View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2015, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-gcm
* @{
*
* \file
* Implementation of the cc2538 AES-GCM driver
*/
#include "contiki.h"
#include "dev/rom-util.h"
#include "dev/gcm.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
static uint8_t
gcm_auth_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv,
const void *adata, uint16_t adata_len,
const void *data_in, void *data_out, uint16_t data_len,
struct process *process)
{
uint32_t ctrl;
uint32_t aes_iv[AES_IV_LEN / sizeof(uint32_t)];
/* Program AES-GCM authentication/crypto operation */
ctrl = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */
AES_AES_CTRL_GCM | /* GCM */
AES_AES_CTRL_CTR_WIDTH_32 | /* CTR width 32 */
AES_AES_CTRL_CTR | /* CTR */
(encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */
/* Prepare the crypto initialization vector
* Initialization vector */
rom_util_memcpy(aes_iv, iv, GCM_IV_LEN);
/* Initialize counter to 1 */
aes_iv[GCM_IV_LEN / sizeof(aes_iv[0])] = 0x01000000;
return aes_auth_crypt_start(ctrl, key_area, aes_iv, adata, adata_len,
data_in, data_out, data_len, process);
}
/*---------------------------------------------------------------------------*/
static uint8_t
gcm_auth_crypt_get_result(const void *tag_in, void *tag_out)
{
uint32_t tag[AES_TAG_LEN / sizeof(uint32_t)];
uint8_t ret;
ret = aes_auth_crypt_get_result(NULL, tag);
if(ret != CRYPTO_SUCCESS) {
return ret;
}
if(tag_in != NULL) {
/* Check tag */
if(rom_util_memcmp(tag, tag_in, GCM_TAG_LEN)) {
ret = AES_AUTHENTICATION_FAILED;
}
}
if(tag_out != NULL) {
/* Copy tag */
rom_util_memcpy(tag_out, tag, GCM_TAG_LEN);
}
return ret;
}
/*---------------------------------------------------------------------------*/
uint8_t
gcm_auth_encrypt_start(uint8_t key_area, const void *iv, const void *adata,
uint16_t adata_len, const void *pdata,
uint16_t pdata_len, void *cdata, struct process *process)
{
return gcm_auth_crypt_start(true, key_area, iv, adata, adata_len,
pdata, cdata, pdata_len, process);
}
/*---------------------------------------------------------------------------*/
uint8_t
gcm_auth_encrypt_get_result(void *tag)
{
return gcm_auth_crypt_get_result(NULL, tag);
}
/*---------------------------------------------------------------------------*/
uint8_t
gcm_auth_decrypt_start(uint8_t key_area, const void *iv, const void *adata,
uint16_t adata_len, const void *cdata,
uint16_t cdata_len, void *pdata, struct process *process)
{
return gcm_auth_crypt_start(false, key_area, iv, adata, adata_len,
cdata, pdata, cdata_len, process);
}
/*---------------------------------------------------------------------------*/
uint8_t
gcm_auth_decrypt_get_result(const void *tag_in, void *tag_out)
__attribute__ ((alias("gcm_auth_crypt_get_result")));
/** @} */

139
cpu/cc2538/dev/gcm.h Normal file
View file

@ -0,0 +1,139 @@
/*
* Copyright (c) 2015, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-aes
* @{
*
* \defgroup cc2538-gcm cc2538 AES-GCM
*
* Driver for the cc2538 AES-GCM mode of the security core
* @{
*
* \file
* Header file for the cc2538 AES-GCM driver
*/
#ifndef GCM_H_
#define GCM_H_
#include "contiki.h"
#include "dev/aes.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \name AES-GCM constants
* @{
*/
#define GCM_IV_LEN (96 / 8)
#define GCM_TAG_LEN AES_TAG_LEN
/** @} */
/*---------------------------------------------------------------------------*/
/** \name AES-GCM functions
* @{
*/
/** \brief Starts a GCM authentication and encryption operation
* \param key_area Area in Key RAM where the key is stored (0 to
* \c AES_KEY_AREAS - 1)
* \param iv Pointer to 96-bit initialization vector
* \param adata Pointer to additional authenticated data in SRAM, or \c NULL
* \param adata_len Length of additional authenticated data in octets, or \c 0
* \param pdata Pointer to message to authenticate and encrypt in SRAM, or
* \c NULL
* \param pdata_len Length of message to authenticate and encrypt in octets, or
* \c 0
* \param cdata Pointer to encrypted message in SRAM (may be \p pdata), or
* \c NULL
* \param process Process to be polled upon completion of the operation, or
* \c NULL
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code
*/
uint8_t gcm_auth_encrypt_start(uint8_t key_area, const void *iv,
const void *adata, uint16_t adata_len,
const void *pdata, uint16_t pdata_len,
void *cdata, struct process *process);
/** \brief Checks the status of the GCM authentication and encryption operation
* \retval false Result not yet available, and no error occurred
* \retval true Result available, or error occurred
*/
#define gcm_auth_encrypt_check_status aes_auth_crypt_check_status
/** \brief Gets the result of the GCM authentication and encryption operation
* \param tag Pointer to 128-bit authentication tag, or \c NULL
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code
* \note This function must be called only after \c gcm_auth_encrypt_start().
*/
uint8_t gcm_auth_encrypt_get_result(void *tag);
/** \brief Starts a GCM authentication checking and decryption operation
* \param key_area Area in Key RAM where the key is stored (0 to
* \c AES_KEY_AREAS - 1)
* \param iv Pointer to 96-bit initialization vector
* \param adata Pointer to additional authenticated data in SRAM, or \c NULL
* \param adata_len Length of additional authenticated data in octets, or \c 0
* \param cdata Pointer to encrypted message in SRAM, or \c NULL
* \param cdata_len Length of encrypted message in octets, or \c 0
* \param pdata Pointer to decrypted message in SRAM (may be \p cdata), or
* \c NULL
* \param process Process to be polled upon completion of the operation, or
* \c NULL
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code
*/
uint8_t gcm_auth_decrypt_start(uint8_t key_area, const void *iv,
const void *adata, uint16_t adata_len,
const void *cdata, uint16_t cdata_len,
void *pdata, struct process *process);
/** \brief Checks the status of the GCM authentication checking and decryption
* operation
* \retval false Result not yet available, and no error occurred
* \retval true Result available, or error occurred
*/
#define gcm_auth_decrypt_check_status aes_auth_crypt_check_status
/** \brief Gets the result of the GCM authentication checking and decryption
* operation
* \param tag_in Pointer to 128-bit input authentication tag, or \c NULL
* \param tag_out Pointer to 128-bit output authentication tag, or \c NULL
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code
* \note This function must be called only after \c gcm_auth_decrypt_start().
*/
uint8_t gcm_auth_decrypt_get_result(const void *tag_in, void *tag_out);
/** @} */
#endif /* GCM_H_ */
/**
* @}
* @}
*/

View file

@ -56,7 +56,7 @@ static volatile struct channel_ctrl channel_config[UDMA_CONF_MAX_CHANNEL + 1]
void
udma_init()
{
memset(&channel_config, 0, sizeof(channel_config));
memset((void *)&channel_config, 0, sizeof(channel_config));
REG(UDMA_CFG) = UDMA_CFG_MASTEN;

View file

@ -142,14 +142,12 @@ soc_rtc_last_isr_time(void)
void
soc_rtc_isr(void)
{
uint32_t now, next;
uint32_t next;
ENERGEST_ON(ENERGEST_TYPE_IRQ);
last_isr_time = RTIMER_NOW();
now = ti_lib_aon_rtc_current_compare_value_get();
/* Adjust the s/w tick counter irrespective of which event trigger this */
clock_update();
@ -161,7 +159,8 @@ soc_rtc_isr(void)
* event on the next 512 tick boundary. If we drop to deep sleep before it
* happens, lpm_drop() will reschedule us in the 'distant' future
*/
next = (now + COMPARE_INCREMENT) & MULTIPLE_512_MASK;
next = ((ti_lib_aon_rtc_current_compare_value_get() + 5) +
COMPARE_INCREMENT) & MULTIPLE_512_MASK;
ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next);
}

View file

@ -244,8 +244,18 @@ lpm_drop()
uint32_t domains = LOCKABLE_DOMAINS;
/* Critical. Don't get interrupted! */
ti_lib_int_master_disable();
/* Check if any events fired before we turned interrupts off. If so, abort */
if(process_nevents()) {
ti_lib_int_master_enable();
return;
}
if(RTIMER_CLOCK_LT(soc_rtc_get_next_trigger(),
RTIMER_NOW() + STANDBY_MIN_DURATION)) {
ti_lib_int_master_enable();
lpm_sleep();
return;
}
@ -261,30 +271,20 @@ lpm_drop()
}
}
/* Check if any events fired during this process. Last chance to abort */
if(process_nevents()) {
return;
}
/* Drop */
if(max_pm == LPM_MODE_SLEEP) {
lpm_sleep();
} else {
/* Critical. Don't get interrupted! */
ti_lib_int_master_disable();
/*
* Reschedule AON RTC CH1 to fire an event N ticks before the next etimer
* event
*/
/* Reschedule AON RTC CH1 to fire just in time for the next etimer event */
next_event = etimer_next_expiration_time();
if(next_event) {
if(etimer_pending()) {
next_event = next_event - clock_time();
soc_rtc_schedule_one_shot(AON_RTC_CH1, soc_rtc_last_isr_time() +
(next_event * (RTIMER_SECOND / CLOCK_SECOND)));
}
/* Drop */
if(max_pm == LPM_MODE_SLEEP) {
ti_lib_int_master_enable();
lpm_sleep();
} else {
/*
* Notify all registered modules that we are dropping to mode X. We do not
* need to do this for simple sleep.

View file

@ -395,26 +395,33 @@ set_tx_power(radio_value_t power)
int i;
rfc_CMD_SET_TX_POWER_t cmd;
/* Send a CMD_SET_TX_POWER command to the RF */
memset(&cmd, 0x00, sizeof(cmd));
cmd.commandNo = CMD_SET_TX_POWER;
/* First, find the correct setting and save it */
for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
if(power <= output_power[i].dbm) {
tx_power_current = &output_power[i];
break;
}
}
/*
* If the core is not accessible, the new setting will be applied next
* time we send CMD_RADIO_SETUP, so we don't need to do anything further.
* If the core is accessible, we can apply the new setting immediately with
* CMD_SET_TX_POWER
*/
if(rf_core_is_accessible() == RF_CORE_NOT_ACCESSIBLE) {
return;
}
memset(&cmd, 0x00, sizeof(cmd));
cmd.commandNo = CMD_SET_TX_POWER;
cmd.txPower.IB = output_power[i].register_ib;
cmd.txPower.GC = output_power[i].register_gc;
cmd.txPower.tempCoeff = output_power[i].temp_coeff;
if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_OK) {
/* Success: Remember the new setting */
tx_power_current = &output_power[i];
} else {
if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
PRINTF("set_tx_power: CMDSTA=0x%08lx\n", cmd_status);
}
return;
}
}
}
/*---------------------------------------------------------------------------*/
static uint8_t
@ -760,7 +767,7 @@ transmit(unsigned short transmit_len)
uint16_t stat;
uint8_t tx_active = 0;
rtimer_clock_t t0;
rfc_CMD_IEEE_TX_t cmd;
volatile rfc_CMD_IEEE_TX_t cmd;
if(!rf_is_on()) {
was_off = 1;

View file

@ -109,9 +109,7 @@ PROCESS(rf_core_process, "CC13xx / CC26xx RF driver");
uint8_t
rf_core_is_accessible()
{
if(ti_lib_prcm_rf_ready() &&
ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) ==
PRCM_DOMAIN_POWER_ON) {
if(ti_lib_prcm_rf_ready()) {
return RF_CORE_ACCESSIBLE;
}
return RF_CORE_NOT_ACCESSIBLE;
@ -124,11 +122,19 @@ rf_core_send_cmd(uint32_t cmd, uint32_t *status)
bool interrupts_disabled;
bool is_radio_op = false;
/* If cmd is 4-byte aligned, then it's a radio OP. Clear the status field */
/*
* If cmd is 4-byte aligned, then it's either a radio OP or an immediate
* command. Clear the status field if it's a radio OP
*/
if((cmd & 0x03) == 0) {
uint32_t cmd_type;
cmd_type = ((rfc_command_t *)cmd)->commandNo & RF_CORE_COMMAND_TYPE_MASK;
if(cmd_type == RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP ||
cmd_type == RF_CORE_COMMAND_TYPE_RADIO_OP) {
is_radio_op = true;
((rfc_radioOp_t *)cmd)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
}
}
/*
* Make sure ContikiMAC doesn't turn us off from within an interrupt while
@ -162,7 +168,7 @@ rf_core_send_cmd(uint32_t cmd, uint32_t *status)
}
return RF_CORE_CMD_ERROR;
}
} while(*status == RF_CORE_CMDSTA_PENDING);
} while((*status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_PENDING);
if(!interrupts_disabled) {
ti_lib_int_master_enable();
@ -238,10 +244,6 @@ rf_core_power_up()
ti_lib_prcm_load_set();
while(!ti_lib_prcm_load_get());
while(!rf_core_is_accessible()) {
PRINTF("rf_core_power_up: Not ready\n");
}
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0;
ti_lib_int_enable(INT_RF_CPE0);
@ -498,8 +500,8 @@ cc26xx_rf_cpe1_isr(void)
}
}
/* Clear interrupt flags */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
/* Clear INTERNAL_ERROR interrupt flag */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x7FFFFFFF;
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}
@ -520,17 +522,25 @@ cc26xx_rf_cpe0_isr(void)
ti_lib_int_master_disable();
if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_FRAME_IRQ) {
/* Clear the RX_ENTRY_DONE interrupt flag */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFF7FFFFF;
process_poll(&rf_core_process);
}
if(RF_CORE_DEBUG_CRC) {
if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_NOK_IRQ) {
/* Clear the RX_NOK interrupt flag */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFDFFFF;
rx_nok_isr();
}
}
/* Clear interrupt flags */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) &
(IRQ_LAST_FG_COMMAND_DONE | IRQ_LAST_COMMAND_DONE)) {
/* Clear the two TX-related interrupt flags */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFFFFF5;
}
ti_lib_int_master_enable();
ENERGEST_OFF(ENERGEST_TYPE_IRQ);

View file

@ -218,7 +218,6 @@ typedef struct rf_core_primary_mode_s {
/*---------------------------------------------------------------------------*/
/* Command Types */
#define RF_CORE_COMMAND_TYPE_MASK 0x0C00
#define RF_CORE_COMMAND_TYPE_IMMEDIATE 0x0000
#define RF_CORE_COMMAND_TYPE_RADIO_OP 0x0800
#define RF_CORE_COMMAND_TYPE_IEEE_BG_RADIO_OP 0x0800
#define RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP 0x0C00

View file

@ -35,6 +35,7 @@
#include "ip64.h"
#include "ip64-eth.h"
#include "rime.h"
#include <string.h>
#include <stdio.h>

View file

@ -107,11 +107,6 @@
* \ingroup platform
*/
/**
* \addtogroup sensinode Sensinode
* \ingroup platform
*/
/**
* \addtogroup sky The Tmote Sky Board
* \ingroup platform

View file

@ -38,10 +38,10 @@ ArchRock and Sensinode implementations.
We do not implement mesh under related features, as we target route over
techniques.
\subsection hc01 draft-hui-6lowpan-hc-01
\subsection RFC 6282
draft-hui-6lowpan-hc-01 defines a stateful header compression mechanism
which should soon deprecate the stateless header compression mechanism
RFC6282 defines a stateful header compression mechanism
which deprecate the stateless header compression mechanism
defined in RFC4944. It is much more powerfull and flexible, in
particular it allows compression of some multicast addresses and of all
global unicast addresses.
@ -110,8 +110,8 @@ the link-layer address. The dependency is reflected in the
\subsection io Packet Input/Output
At initialization, the #input function in sicslowpan.c is set as the
function to be called by the MAC upon packet reception. The #output
At initialization, the input function in sicslowpan.c is set as the
function to be called by the MAC upon packet reception. The output
function is set as the tcpip_output function.<br>
At packet reception, the link-layer copies the 802.15.4 payload in the
rime buffer, and sets its length. It also stores the source and
@ -122,19 +122,19 @@ packetbuf_set_datalen(rx_frame.payload_length);
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)&rx_frame.dest_addr);
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)&rx_frame.src_addr);
\endcode
It then calls the sicslowpan #input function. Similarly, when the IPv6 layer
It then calls the sicslowpan input function. Similarly, when the IPv6 layer
has a packet to send over the radio, it puts the packet in uip_buf,
sets uip_len and calls the sicslowpan #output function.
sets uip_len and calls the sicslowpan output function.
\subsection frag Fragmentation
\li #output function: When an IP packet, after header compression, is
\li output function: When an IP packet, after header compression, is
too big to fit in a 802.15.4 frame, it is fragmented in several packets
which are sent successively over the radio. The packets are formatted
as defined in RFC 4944. Only the first fragment contains the IP/UDP
compressed or uncompressed header fields.
\li #input function: This function takes care of fragment
\li input function: This function takes care of fragment
reassembly. We do not assume that the fragments are received in order.
When reassembly of a packet is ongoing, we discard any non fragmented
packet or fragment from another packet. Reassembly times out after
@ -143,8 +143,9 @@ packet or fragment from another packet. Reassembly times out after
\note Fragmentation support is enabled by setting the #SICSLOWPAN_CONF_FRAG
compilation option.
\note As we do not support complex buffer allocation mechanism, for now
we define a new 1280 bytes buffer (#sicslowpan_buf) to reassemble packets.
\note In order to make it possible to reassemble multiple packets at
the same time we have a mechanism for storing each fragment per sender
and tag until it is fully reassembled or the reassemly times out.
At reception, once all the fragments are received, we copy the packet
to #uip_buf, set #uip_len, and call #tcpip_input.
@ -157,49 +158,35 @@ the header 25 bytes long).
<b>Compression schemes</b><br>
The #SICSLOWPAN_CONF_COMPRESSION compilation option defines the
compression scheme supported. We support HC1, HC06, and IPv6 compression.
HC1 and IPv6 compression are defined in RFC4944, HC06 in
draft-hui-6lowpan-hc-06. What we call IPv6 compression means sending packets
compression scheme supported. We support IPHC, and IPv6 compression.
IPv6 compression are defined in RFC4944, IPHC in RFC6282.
What we call IPv6 compression means sending packets
with no compression, and adding the IPv6 dispatch before the IPv6 header.<br>
If at compile time IPv6 "compression" is chosen, packets sent will never
be compressed, and compressed packets will not be processed at reception.<br>
If at compile time either HC1 or HC06 are chosen, we will try to compress
If at compile time IPHC is chosen, we will try to compress
all fields at sending, and will accept packets compressed with the
chosen scheme, as well as uncompressed packets.<br>
Note that HC1 and HC06 supports are mutually exclusive. HC06 should soon
deprecate HC1.
chosen scheme, as well as uncompressed packets.<br>.
<b>Compression related functions</b><br>
When a packet is received, the #input function is called. Fragmentation
When a packet is received, the input function is called. Fragmentation
issues are handled, then we check the dispatch byte: if it is IPv6, we
treat the packet inline. If it is HC1 or HC06, the corresponding
decompression function (#uncompress_hdr_hc1 or #uncompress_hdr_hc06)
is called.<br>
treat the packet inline. If it is IPHC, the decompression function
(uncompress_hdr_iphc) is called.<br>
When a packet needs to be sent, we try to compress it. If only the IPv6
compression support is enabled, we just add the IPv6 dispatch before the
802.15.4 payload. If HC1 or HC06 support is enabled, we call the
corresponding compression function (#compress_hdr_hc1 or #compress_hdr_hc06)
802.15.4 payload. If IPHC support is enabled, we call the
corresponding compression function (compress_hdr_iphc)
to compress the packet as much as possible.
<b>HC1 comments</b><br>
In HC1, if the IPv6 flow label is not compressed, we would need to copy
the fields after the flow label starting in the middle of a byte (the
flow label is 20 bits long). To avoid this, we compress the packets only
if all fields can be compressed. If we cannot, we use the IPv6 dispatch
and send all headers fields inline. This behavior is the one defined in
draft-hui-6lowpan-interop-00.<br>
In the same way, if the packet is an UDP packet, we compress the UDP
header only if all fields can be compressed.<br>
Note that HC1 can only compress unicast link local addresses. For this
reason, we recommend using HC01.
<b>HC01 comments</b><br>
HC01 uses address contexts to enable compression of global unicast
<b>IPHC comments</b><br>
IPHC uses address contexts to enable compression of global unicast
addresses. All nodes must share context (namely the global prefixes in
use) to compress and uncompress such addresses successfully. The context
number is defined by 2 bits. Context 00 is reserved for the link local
number is defined by 4 bits. Context 00 is reserved for the link local
context. Other contexts have to be distributed within the LoWPAN
dynamically, by means of ND extensions yet to be defined.<br>
dynamically, by means of ND extensions yet to be implemented.<br>
Until then, if you want to test global address compression, you need
to configure the global contexts manually.

View file

@ -2,7 +2,7 @@
* 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
* It is largely based on hello_world of the original sensinode port
*
* Author: George Oikonomou - <oikonomou@users.sourceforge.net>
*/

View file

@ -0,0 +1,8 @@
DEFINES+=PROJECT_CONF_H=\"project-conf.h\"
CONTIKI_PROJECT = test-pwm timer-test
all: $(CONTIKI_PROJECT)
CONTIKI = ../..
CONTIKI_WITH_RIME = 1
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,18 @@
README file for CC2538 common examples
=========
The `cc2538-commmon` groups examples common to all cc2538-based platforms.
The examples in this folder are known to work on:
* cc2538dk (default)
* zoul
To change the default target at compilation time you can add the following:
make TARGET=zoul
Or to define the default platform permanently:
make TARGET=zoul savetarget
This will create a `Makefile.target` file with the TARGET predefined.

Some files were not shown because too many files have changed in this diff Show more