Merge branch 'master' of ssh://contiki.git.sourceforge.net/gitroot/contiki/contiki

This commit is contained in:
Joakim Eriksson 2011-03-15 14:15:55 +01:00
commit 6554e87c00
41 changed files with 2148 additions and 211 deletions

13
.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
*.a
*.bin
*.map
*.png
*.log
*.elf
*.ihex
obj_*
symbols.*
Makefile.target
doc/html
patches-*
tools/tunslip6

View file

@ -250,9 +250,10 @@ dio_input(void)
dio.mc.aggr = buffer[i + 4] >> 4;
dio.mc.prec = buffer[i + 4] & 0xf;
dio.mc.length = buffer[i + 5];
if(dio.mc.type == RPL_DAG_MC_ETX) {
dio.mc.etx.etx = buffer[i + 6] << 8;
dio.mc.etx.etx |= buffer[i + 7];
dio.mc.obj.etx = buffer[i + 6] << 8;
dio.mc.obj.etx |= buffer[i + 7];
PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n",
(unsigned)dio.mc.type,
@ -260,7 +261,10 @@ dio_input(void)
(unsigned)dio.mc.aggr,
(unsigned)dio.mc.prec,
(unsigned)dio.mc.length,
(unsigned)dio.mc.etx.etx);
(unsigned)dio.mc.obj.etx);
} else if(dio.mc.type == RPL_DAG_MC_ENERGY) {
dio.mc.obj.energy.flags = buffer[i + 6];
dio.mc.obj.energy.energy_est = buffer[i + 7];
} else {
PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type);
return;
@ -380,8 +384,12 @@ dio_output(rpl_dag_t *dag, uip_ipaddr_t *uc_addr)
buffer[pos++] |= dag->mc.prec;
if(dag->mc.type == RPL_DAG_MC_ETX) {
buffer[pos++] = 2;
buffer[pos++] = dag->mc.etx.etx >> 8;
buffer[pos++] = dag->mc.etx.etx & 0xff;
buffer[pos++] = dag->mc.obj.etx >> 8;
buffer[pos++] = dag->mc.obj.etx & 0xff;
} else if(dag->mc.type == RPL_DAG_MC_ENERGY) {
buffer[pos++] = 2;
buffer[pos++] = dag->mc.obj.energy.flags;
buffer[pos++] = dag->mc.obj.energy.energy_est;
} else {
PRINTF("RPL: Unable to send DIO because of unhandled DAG MC type %u\n",
(unsigned)dag->mc.type);

View file

@ -66,7 +66,7 @@ rpl_of_t rpl_of_etx = {
#define NI_ETX_TO_RPL_ETX(etx) \
((etx) * (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR))
#define RPL_ETX_TO_NI_ETX(etx) \
#define rpl_path_metric_tO_NI_ETX(etx) \
((etx) / (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR))
/* Reject parents that have a higher link metric than the following. */
@ -84,13 +84,12 @@ rpl_of_t rpl_of_etx = {
*/
#define PARENT_SWITCH_THRESHOLD_DIV 2
typedef uint16_t rpl_etx_t;
#define MAX_ETX 65535
typedef uint16_t rpl_path_metric_t;
static uint16_t
calculate_etx(rpl_parent_t *p)
calculate_path_metric(rpl_parent_t *p)
{
return p->mc.etx.etx + NI_ETX_TO_RPL_ETX(p->etx);
return p->mc.obj.etx + NI_ETX_TO_RPL_ETX(p->etx);
}
static void
@ -140,48 +139,64 @@ static rpl_parent_t *
best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
{
rpl_dag_t *dag;
rpl_etx_t min_diff;
rpl_etx_t p1_etx;
rpl_etx_t p2_etx;
rpl_path_metric_t min_diff;
rpl_path_metric_t p1_metric;
rpl_path_metric_t p2_metric;
dag = p1->dag; /* Both parents must be in the same DAG. */
min_diff = RPL_DAG_MC_ETX_DIVISOR /
PARENT_SWITCH_THRESHOLD_DIV;
p1_etx = calculate_etx(p1);
p2_etx = calculate_etx(p2);
p1_metric = calculate_path_metric(p1);
p2_metric = calculate_path_metric(p2);
/* Maintain stability of the preferred parent in case of similar ranks. */
if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
if(p1_etx < p2_etx + min_diff &&
p1_etx > p2_etx - min_diff) {
if(p1_metric < p2_metric + min_diff &&
p1_metric > p2_metric - min_diff) {
PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
p2_etx - min_diff,
p1_etx,
p2_etx + min_diff);
p2_metric - min_diff,
p1_metric,
p2_metric + min_diff);
return dag->preferred_parent;
}
}
return p1_etx < p2_etx ? p1 : p2;
return p1_metric < p2_metric ? p1 : p2;
}
static void
update_metric_container(rpl_dag_t *dag)
{
#if RPL_DAG_MC == RPL_DAG_MC_ETX
dag->mc.type = RPL_DAG_MC_ETX;
dag->mc.flags = RPL_DAG_MC_FLAG_P;
dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
dag->mc.prec = 0;
dag->mc.length = sizeof(dag->mc.etx.etx);
dag->mc.length = sizeof(dag->mc.obj.etx);
if(dag->rank == ROOT_RANK(dag)) {
dag->mc.etx.etx = 0;
dag->mc.obj.etx = 0;
} else {
dag->mc.etx.etx = calculate_etx(dag->preferred_parent);
dag->mc.obj.etx = calculate_path_metric(dag->preferred_parent);
}
#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
dag->mc.type = RPL_DAG_MC_ENERGY;
dag->mc.flags = RPL_DAG_MC_FLAG_P;
dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
dag->mc.prec = 0;
dag->mc.length = sizeof(dag->mc.obj.energy);
if(dag->rank == ROOT_RANK(dag)) {
dag->mc.obj.energy.flags = RPL_DAG_MC_ENERGY_TYPE_MAINS << RPL_DAG_MC_ENERGY_TYPE;
} else {
dag->mc.obj.energy.flags = RPL_DAG_MC_ENERGY_TYPE_BATTERY << RPL_DAG_MC_ENERGY_TYPE;
}
dag->mc.obj.energy.energy_est = calculate_path_metric(dag->preferred_parent);
#else
#error "Unsupported RPL_DAG_MC configured. See rpl.h."
#endif /* RPL_DAG_MC */
PRINTF("RPL: My path ETX to the root is %u.%u\n",
dag->mc.etx.etx / RPL_DAG_MC_ETX_DIVISOR,
(dag->mc.etx.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR);
dag->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR,
(dag->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR);
}

View file

@ -49,6 +49,17 @@
#define RPL_CONF_STATS 0
#endif /* RPL_CONF_STATS */
/*
* Select routing metric supported at runtime. This must be a valid
* DAG Metric Container Object Type (see below). Currently, we only
* support RPL_DAG_MC_ETX and RPL_DAG_MC_ENERGY.
*/
#ifdef RPL_CONF_DAG_MC
#define RPL_DAG_MC RPL_CONF_DAG_MC
#else
#define RPL_DAG_MC RPL_DAG_MC_ETX
#endif /* RPL_CONF_DAG_MC */
/*
* The objective function used by RPL is configurable through the
* RPL_CONF_OF parameter. This should be defined to be the name of an
@ -78,8 +89,8 @@ typedef uint16_t rpl_ocp_t;
/* DAG Metric Container Object Types, to be confirmed by IANA. */
#define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */
#define RPL_DAG_MC_NSA 1 /* Node State and Attributes */
#define RPL_DAG_MC_NE 2 /* Node Energy */
#define RPL_DAG_MC_HC 3 /* Hop Count */
#define RPL_DAG_MC_ENERGY 2 /* Node Energy */
#define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */
#define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */
#define RPL_DAG_MC_LATENCY 5 /* Latency */
#define RPL_DAG_MC_LQL 6 /* Link Quality Level */
@ -99,9 +110,19 @@ typedef uint16_t rpl_ocp_t;
#define RPL_DAG_MC_AGGR_MINIMUM 2
#define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
/* Logical representation of an ETX object in a DAG Metric Container. */
struct rpl_metric_object_etx {
uint16_t etx;
/* The bit index within the flags field of
the rpl_metric_object_energy structure. */
#define RPL_DAG_MC_ENERGY_INCLUDED 3
#define RPL_DAG_MC_ENERGY_TYPE 1
#define RPL_DAG_MC_ENERGY_ESTIMATION 0
#define RPL_DAG_MC_ENERGY_TYPE_MAINS 0
#define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1
#define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2
struct rpl_metric_object_energy {
uint8_t flags;
uint8_t energy_est;
};
/* Logical representation of a DAG Metric Container. */
@ -111,9 +132,10 @@ struct rpl_metric_container {
uint8_t aggr;
uint8_t prec;
uint8_t length;
/* Once we support more objects, the etx field will be replaced by a
union of those. */
struct rpl_metric_object_etx etx;
union metric_object {
struct rpl_metric_object_energy energy;
uint16_t etx;
} obj;
};
typedef struct rpl_metric_container rpl_metric_container_t;
/*---------------------------------------------------------------------------*/

View file

@ -26,7 +26,6 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: uip-debug.c,v 1.1 2010/04/30 13:20:57 joxe Exp $
*/
/**
@ -39,7 +38,7 @@
*/
#include "net/uip-debug.h"
#include <stdio.h>
/*---------------------------------------------------------------------------*/
void
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
@ -52,19 +51,19 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) {
printf("::");
PRINTA("::");
}
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
printf(":");
PRINTA(":");
}
printf("%x", a);
PRINTA("%x", a);
}
}
#else /* UIP_CONF_IPV6 */
printf("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);
PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);
#endif /* UIP_CONF_IPV6 */
}
/*---------------------------------------------------------------------------*/
@ -74,9 +73,9 @@ uip_debug_lladdr_print(const uip_lladdr_t *addr)
unsigned int i;
for(i = 0; i < sizeof(uip_lladdr_t); i++) {
if(i > 0) {
printf(":");
PRINTA(":");
}
printf("%02x", addr->addr[i]);
PRINTA("%02x", addr->addr[i]);
}
}
/*---------------------------------------------------------------------------*/

View file

@ -43,6 +43,7 @@
#define UIP_DEBUG_H
#include "net/uip.h"
#include <stdio.h>
void uip_debug_ipaddr_print(const uip_ipaddr_t *addr);
void uip_debug_lladdr_print(const uip_lladdr_t *addr);
@ -52,10 +53,16 @@ void uip_debug_lladdr_print(const uip_lladdr_t *addr);
#define DEBUG_ANNOTATE 2
#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT
#if (DEBUG) & DEBUG_ANNOTATE
#include <stdio.h>
/* PRINTA will always print if the debug routines are called directly */
#ifdef __AVR__
#include <avr/pgmspace.h>
#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTA(...) printf(__VA_ARGS__)
#endif
#if (DEBUG) & DEBUG_ANNOTATE
#ifdef __AVR__
#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define ANNOTATE(...) printf(__VA_ARGS__)
@ -65,9 +72,7 @@ void uip_debug_lladdr_print(const uip_lladdr_t *addr);
#endif /* (DEBUG) & DEBUG_ANNOTATE */
#if (DEBUG) & DEBUG_PRINT
#include <stdio.h>
#ifdef __AVR__
#include <avr/pgmspace.h>
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTF(...) printf(__VA_ARGS__)

View file

@ -15,12 +15,23 @@ long sleepseconds;
#if RF230BB && WEBSERVER
#define RADIOSTATS 1
#endif
#if RADIOSTATS
static volatile uint8_t rcount;
volatile unsigned long radioontime;
extern uint8_t RF230_receive_on;
#endif
/* Set RADIOCALIBRATE for periodic calibration of the PLL during extended radio on time.
* The data sheet suggests every 5 minutes if the temperature is fluctuating.
* Using an eight bit counter gives 256 second calibrations.
* Actual calibration is done by the driver on the next transmit request.
*/
#if RADIOCALIBRATE
extern volatile uint8_t rf230_calibrate;
static uint8_t calibrate_interval;
#endif
/*
CLOCK_SECOND is the number of ticks per second.
It is defined through CONF_CLOCK_SECOND in the contiki-conf.h for each platform.
@ -46,48 +57,50 @@ void clock_adjust_seconds(uint8_t howmany) {
#endif
}
/*---------------------------------------------------------------------------*/
/* These routines increment the second counters.
* Calling these avoids the interrupt overhead of pushing many registers on the stack.
*/
static void increment_seconds(void) __attribute__ ((noinline));
static void increment_seconds(void)
{
seconds++;
}
#if RADIOSTATS
extern volatile uint8_t rf230_calibrate;
static void increment_radioontime(void) __attribute__ ((noinline));
static void increment_radioontime(void)
{
static uint8_t calibrate_interval;
radioontime++;
if (++calibrate_interval==0) {
rf230_calibrate=1;
}
}
#endif
/*---------------------------------------------------------------------------*/
//SIGNAL(SIG_OUTPUT_COMPARE0)
ISR(AVR_OUTPUT_COMPARE_INT)
{
count++;
if(++scount == CLOCK_SECOND) {
scount = 0;
increment_seconds();
// seconds++;
seconds++;
}
#if RADIOCALIBRATE
if (++calibrate_interval==0) {
rf230_calibrate=1;
}
#endif
#if RADIOSTATS
if (RF230_receive_on) {
if (++rcount == CLOCK_SECOND) {
rcount=0;
increment_radioontime();
// radioontime++;
radioontime++;
}
}
#endif
#if 1
/* gcc will save all registers on the stack if an external routine is called */
if(etimer_pending()) {
etimer_request_poll();
}
#else
/* doing this locally saves 9 pushes and 9 pops, but these etimer.c and process.c variables have to lose the static qualifier */
extern struct etimer *timerlist;
extern volatile unsigned char poll_requested;
#define PROCESS_STATE_NONE 0
#define PROCESS_STATE_RUNNING 1
#define PROCESS_STATE_CALLED 2
if (timerlist) {
if(etimer_process.state == PROCESS_STATE_RUNNING ||
etimer_process.state == PROCESS_STATE_CALLED) {
etimer_process.needspoll = 1;
poll_requested = 1;
}
}
#endif
}
/*---------------------------------------------------------------------------*/
@ -153,3 +166,91 @@ clock_seconds(void)
} while(tmp != seconds);
return tmp;
}
#ifdef HANG_ON_UNKNOWN_INTERRUPT
/* Useful for diagnosing unknown interrupts that reset the mcu.
* Currently set up for 12mega128rfa1.
* For other mcus, enable all and then disable the conflicts.
*/
static volatile uint8_t x;
ISR( _VECTOR(0)) {while (1) x++;}
ISR( _VECTOR(1)) {while (1) x++;}
ISR( _VECTOR(2)) {while (1) x++;}
ISR( _VECTOR(3)) {while (1) x++;}
ISR( _VECTOR(4)) {while (1) x++;}
ISR( _VECTOR(5)) {while (1) x++;}
ISR( _VECTOR(6)) {while (1) x++;}
ISR( _VECTOR(7)) {while (1) x++;}
ISR( _VECTOR(8)) {while (1) x++;}
ISR( _VECTOR(9)) {while (1) x++;}
ISR( _VECTOR(10)) {while (1) x++;}
ISR( _VECTOR(11)) {while (1) x++;}
ISR( _VECTOR(12)) {while (1) x++;}
ISR( _VECTOR(13)) {while (1) x++;}
ISR( _VECTOR(14)) {while (1) x++;}
ISR( _VECTOR(15)) {while (1) x++;}
ISR( _VECTOR(16)) {while (1) x++;}
ISR( _VECTOR(17)) {while (1) x++;}
ISR( _VECTOR(18)) {while (1) x++;}
ISR( _VECTOR(19)) {while (1) x++;}
//ISR( _VECTOR(20)) {while (1) x++;}
//ISR( _VECTOR(21)) {while (1) x++;}
ISR( _VECTOR(22)) {while (1) x++;}
ISR( _VECTOR(23)) {while (1) x++;}
ISR( _VECTOR(24)) {while (1) x++;}
//ISR( _VECTOR(25)) {while (1) x++;}
ISR( _VECTOR(26)) {while (1) x++;}
//ISR( _VECTOR(27)) {while (1) x++;}
ISR( _VECTOR(28)) {while (1) x++;}
ISR( _VECTOR(29)) {while (1) x++;}
ISR( _VECTOR(30)) {while (1) x++;}
ISR( _VECTOR(31)) {while (1) x++;}
//ISR( _VECTOR(32)) {while (1) x++;}
ISR( _VECTOR(33)) {while (1) x++;}
ISR( _VECTOR(34)) {while (1) x++;}
ISR( _VECTOR(35)) {while (1) x++;}
//ISR( _VECTOR(36)) {while (1) x++;}
ISR( _VECTOR(37)) {while (1) x++;}
//ISR( _VECTOR(38)) {while (1) x++;}
ISR( _VECTOR(39)) {while (1) x++;}
ISR( _VECTOR(40)) {while (1) x++;}
ISR( _VECTOR(41)) {while (1) x++;}
ISR( _VECTOR(42)) {while (1) x++;}
ISR( _VECTOR(43)) {while (1) x++;}
ISR( _VECTOR(44)) {while (1) x++;}
ISR( _VECTOR(45)) {while (1) x++;}
ISR( _VECTOR(46)) {while (1) x++;}
ISR( _VECTOR(47)) {while (1) x++;}
ISR( _VECTOR(48)) {while (1) x++;}
ISR( _VECTOR(49)) {while (1) x++;}
ISR( _VECTOR(50)) {while (1) x++;}
ISR( _VECTOR(51)) {while (1) x++;}
ISR( _VECTOR(52)) {while (1) x++;}
ISR( _VECTOR(53)) {while (1) x++;}
ISR( _VECTOR(54)) {while (1) x++;}
ISR( _VECTOR(55)) {while (1) x++;}
ISR( _VECTOR(56)) {while (1) x++;}
//ISR( _VECTOR(57)) {while (1) x++;}
//ISR( _VECTOR(58)) {while (1) x++;}
//ISR( _VECTOR(59)) {while (1) x++;}
//ISR( _VECTOR(60)) {while (1) x++;}
ISR( _VECTOR(61)) {while (1) x++;}
ISR( _VECTOR(62)) {while (1) x++;}
ISR( _VECTOR(63)) {while (1) x++;}
ISR( _VECTOR(64)) {while (1) x++;}
ISR( _VECTOR(65)) {while (1) x++;}
ISR( _VECTOR(66)) {while (1) x++;}
ISR( _VECTOR(67)) {while (1) x++;}
ISR( _VECTOR(68)) {while (1) x++;}
ISR( _VECTOR(69)) {while (1) x++;}
ISR( _VECTOR(70)) {while (1) x++;}
ISR( _VECTOR(71)) {while (1) x++;}
ISR( _VECTOR(72)) {while (1) x++;}
ISR( _VECTOR(73)) {while (1) x++;}
ISR( _VECTOR(74)) {while (1) x++;}
ISR( _VECTOR(75)) {while (1) x++;}
ISR( _VECTOR(76)) {while (1) x++;}
ISR( _VECTOR(77)) {while (1) x++;}
ISR( _VECTOR(78)) {while (1) x++;}
ISR( _VECTOR(79)) {while (1) x++;}
#endif

31
cpu/avr/dev/uart1.h Normal file
View file

@ -0,0 +1,31 @@
/*
Copied from mc1322x/dev/cpu.
This file exists as a work-around for the hardware dependant calls
to slip_arch_init.
Current the prototype for slip_arch_init is slip_arch_init(urb)
and a typical call is something like
slip_arch_init(BAUD2URB(115200))
BAUD2UBR is hardware specific, however. Furthermore, for the sky
platform it's typically defined with #include "dev/uart1.h" (see
rpl-boarder-router/slip-bridge.c), a sky specific file. dev/uart1.h
includes msp430.h which includes the sky contiki-conf.h which
defines BAUD2UBR.
To me, the correct think to pass is simply the baudrate and have the
hardware specific conversion happen inside slip_arch_init.
Notably, most implementations just ignore the passed parameter
anyway. (except AVR)
*/
#ifndef DEV_UART1_H
#define DEV_UART1_H
#define BAUD2UBR(x) x
#endif

View file

@ -148,9 +148,12 @@ struct timestamp {
#if RADIOSTATS
uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
#endif
#if RADIOCALIBRATE
/* Set in clock.c every 256 seconds */
uint8_t rf230_calibrate;
uint8_t rf230_calibrated; //debugging
uint8_t rf230_calibrated; //for debugging, prints from main loop when calibration occurs
#endif
/* Track flow through driver, see contiki-raven-main.c for example of use */
//#define DEBUGFLOWSIZE 64
@ -758,6 +761,7 @@ rf230_transmit(unsigned short payload_len)
// delay_us(TIME_SLEEP_TO_TRX_OFF);
RF230_sleeping=0;
} else {
#if RADIOCALIBRATE
/* If on, do periodic calibration. See clock.c */
if (rf230_calibrate) {
hal_subregister_write(SR_PLL_CF_START,1); //takes 80us max
@ -766,6 +770,7 @@ rf230_transmit(unsigned short payload_len)
rf230_calibrated=1;
delay_us(80); //?
}
#endif
}
/* Wait for any previous operation or state transition to finish */

View file

@ -28,45 +28,92 @@
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: watchdog.c,v 1.3 2010/12/18 20:51:11 dak664 Exp $
*/
/* Dummy watchdog routines for the Raven 1284p */
/* Watchdog routines for the AVR */
/* The default timeout of 2 seconds works on most MCUs.
* It should be disabled during sleep (unless used for wakeup) since
* it draws significant current (~5 uamp on 1284p, 20x the MCU consumption).
*
* Note the wdt is not properly simulated in AVR Studio 4 Simulator 1:
* On many devices calls to wdt_reset will have no effect, and a wdt reboot will occur.
* The MCUSR will not show the cause of a wdt reboot.
* A 1MHz clock is assumed; at 8MHz timeout occurs 8x faster than it should.
* Simulator 2 is supposed to work on supported devices (not atmega128rfa1),
* but neither it nor Studio 5 beta do any resets on the 1284p.
*
* Setting WATCHDOG_CONF_TIMEOUT -1 will disable the WDT.
*/
//#define WATCHDOG_CONF_TIMEOUT -1
#ifndef WATCHDOG_CONF_TIMEOUT
#define WATCHDOG_CONF_TIMEOUT WDTO_2S
#endif
/* While balancing start and stop calls is a good idea, an imbalance will cause
* resets that can take a lot of time to track down.
* Some low power protocols may cause this.
* The default is no balance; define WATCHDOG_CONF_BALANCE 1 to override.
*/
#ifndef WATCHDOG_CONF_BALANCE
#define WATCHDOG_CONF_BALANCE 0
#endif
#include "dev/watchdog.h"
#include <avr/wdt.h>
#include <avr/interrupt.h>
#if WATCHDOG_CONF_BALANCE && WATCHDOG_CONF_TIMEOUT >= 0
static int stopped = 0;
#endif
/*---------------------------------------------------------------------------*/
void
watchdog_init(void)
{
/* Clear startup bit and disable the wdt, whether or not it will be used.
Random code may have caused the last reset.
*/
MCUSR&=~(1<<WDRF);
stopped = 0;
watchdog_stop();
wdt_disable();
#if WATCHDOG_CONF_BALANCE && WATCHDOG_CONF_TIMEOUT >= 0
stopped = 1;
#endif
}
/*---------------------------------------------------------------------------*/
void
watchdog_start(void)
{
#if WATCHDOG_CONF_TIMEOUT >= 0
#if WATCHDOG_CONF_BALANCE
stopped--;
// if(!stopped)
wdt_enable(WDTO_2S);
if(!stopped)
#endif
wdt_enable(WATCHDOG_CONF_TIMEOUT);
#endif
}
/*---------------------------------------------------------------------------*/
void
watchdog_periodic(void)
{
// if(!stopped)
#if WATCHDOG_CONF_TIMEOUT >= 0
#if WATCHDOG_CONF_BALANCE
if(!stopped)
#endif
wdt_reset();
#endif
}
/*---------------------------------------------------------------------------*/
void
watchdog_stop(void)
{
// stopped++;
#if WATCHDOG_CONF_TIMEOUT >= 0
#if WATCHDOG_CONF_BALANCE
stopped++;
#endif
wdt_disable();
#endif
}
/*---------------------------------------------------------------------------*/
void
@ -77,3 +124,9 @@ watchdog_reboot(void)
while(1); //loop
}
/*---------------------------------------------------------------------------*/
#if 0
/* Not all AVRs implement the wdt interrupt */
ISR(WDT_vect)
{
}
#endif

View file

@ -72,8 +72,8 @@ CUSTOM_RULE_C_TO_O=yes
CFLAGS += -I$(OBJECTDIR) -I$(CONTIKI_CPU)/board -DBOARD=$(TARGET)
$(OBJECTDIR)/board.h: $(OBJECTDIR)
ifneq (,$(findstring cygdrive,$(shell pwd)))
${info Cygwin detected.}
ifneq (,$(findstring Windows,$(OS)))
${info Cygwin detected.}
ln -f $(CONTIKI_CPU)/board/$(TARGET).h $(OBJECTDIR)/board.h
else
ln -sf ../$(CONTIKI_CPU)/board/$(TARGET).h $(OBJECTDIR)/board.h
@ -90,8 +90,6 @@ $(OBJECTDIR)/%.o: %.c
$(CC) $(CFLAGS) $(THUMB_FLAGS) -c $< -o $@
CUSTOM_RULE_S_TO_OBJECTDIR_O = yes
%.o: %.S
$(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c
$(OBJECTDIR)/%.o: %.S
$(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c -o $@

138
cpu/mc1322x/lib/adc.c Normal file
View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* 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 libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
#include <stdint.h>
#include "crm.h"
#include "adc.h"
#include "gpio-util.h"
//#define ADC_CHANS_ENABLED 0x3F // channels 0-5 enabled
//#define ADC_CHANS_ENABLED 0x7E // channels 1-6 enabled
//#define ADC_CHANS_ENABLED (1 << 6) // only channel 6 enabled
#define ADC_CHANS_ENABLED 0x1FF // all channels, including battery reference voltage
//#define ADC_PRESCALE_VALUE 24 // divide by 24 for 1MHz.
#define ADC_SAMPLE_FREQ 400 // Hz (minimum of ~366.21 Hz)
#define ADC_PRESCALE_VALUE (REF_OSC / ADC_SAMPLE_FREQ)
#define ADC_USE_TIMER 0
#define ADC_USE_INTERRUPTS 0 // incomplete support
uint16_t adc_reading[NUM_ADC_CHAN];
void ADC_flush(void) {
while(ADC->FIFO_STATUSbits.EMPTY == 0) ADC->FIFO_READ;
}
uint16_t ADC_READ(void) {
while(ADC->FIFO_STATUSbits.EMPTY); // loop while empty
return ADC->FIFO_READ; // upper 4 bits are channel number
}
void adc_service(void) {
uint16_t value;
uint8_t channel;
while (ADC->FIFO_STATUSbits.EMPTY == 0) {
value = ADC->FIFO_READ;
channel = value >> 12;
if (channel < NUM_ADC_CHAN) adc_reading[channel] = value & 0xFFF;
}
}
void adc_init(void) {
uint8_t n;
ADC->CLOCK_DIVIDER = 80; // 300 KHz
ADC->PRESCALE = ADC_PRESCALE_VALUE - 1; // divide by 24 for 1MHz.
ADC->CONTROL = 1;
// The ON-TIME must always be 10µs or greater - typical On-Time value = 0x000A (10dec)
ADC->ON_TIME = 10;
/*
NOTE
The ADC analog block requires 6 ADC_Clocks per conversion, and the
ADC_Clock must 300kHz or less. With 6 clocks/conversion and a 33.33µs
clock period:
* The ADC convert time must always be 20µs or greater
* If the ADC_Clock is a frequency lower than 300kHz, the convert time
must always be 6 ADC_Clock periods or greater
* For override mode, extend convert time to 40µs minimum or greater
For the convert time:
* This delay is a function of the Prescale Clock (typically 1 MHz)
* The register must be initialized for proper operation
* For a 20µs convert time with 1MHz, value = 0x0014 (20dec)
* If convert time is insufficient, inaccurate sample data will result
*/
ADC->CONVERT_TIME = 1000000 / (115200 / 8) - 1;
ADC->MODE = 0; // Automatic
#if ADC_USE_INTERRUPTS
ADC->FIFO_CONTROL = 7;
#else
ADC->FIFO_CONTROL = 0;
#endif
#if ADC_USE_TIMER
ADC->SR_1_HIGH = 0x0000;
ADC->SR_1_LOW = (REF_OSC / ADC_PRESCALE_VALUE) / (115200 / 8) + 1;
#endif
ADC->SEQ_1 = 0
#if ADC_USE_TIMER
| (1 << 15) // sequence based on Timer 1.
#else
| (0 << 15) // sequence based on convert time.
#endif
| ADC_CHANS_ENABLED;
ADC->CONTROL = 0xF001
//#if ADC_USE_TIMER
| (1 << 1) // Timer 1 enable
//#endif
;
ADC->OVERRIDE = (1 << 8);
for (n=0; n<=8; n++) {
if ((ADC_CHANS_ENABLED >> n) & 1) {
gpio_select_function(30 + n, 1); // Function 1 = ADC
gpio_set_pad_dir(30 + n, PAD_DIR_INPUT);
}
}
}

View file

@ -0,0 +1,63 @@
#include <mc1322x.h>
#include <board.h>
#include "gpio-util.h"
void gpio_select_function(uint8_t gpio, uint8_t func) {
uint32_t mask = 3;
uint8_t major, minor, shift;
volatile uint32_t *base = GPIO_FUNC_SEL0;
uint32_t value;
major = gpio >> 4;
minor = gpio & 0xF;
shift = 2 * minor;
value = base[major];
value &= ~(mask << shift);
value |= (func << shift);
base[major] = value;
}
void gpio_reg_set(volatile uint32_t* reg, uint8_t bit) {
uint8_t major, minor;
major = bit / 32;
minor = bit % 32;
*(reg + major) |= (1UL << minor);
}
void gpio_reg_clear(volatile uint32_t* reg, uint8_t bit) {
uint8_t major, minor;
major = bit / 32;
minor = bit % 32;
*(reg + major) &= ~(1UL << minor);
}
void gpio_set_pad_dir(uint8_t gpio, uint8_t dir) {
uint8_t major, minor;
major = gpio / 32;
minor = gpio % 32;
if (dir) gpio_reg_set(GPIO_PAD_DIR0 + major, minor);
else gpio_reg_clear(GPIO_PAD_DIR0 + major, minor);
}
void gpio_set(uint8_t gpio) {
uint8_t major, minor;
major = gpio / 32;
minor = gpio % 32;
*(GPIO_DATA_SET0 + major) = (1UL << minor);
}
void gpio_reset(uint8_t gpio) {
uint8_t major, minor;
major = gpio / 32;
minor = gpio % 32;
*(GPIO_DATA_RESET0 + major) = (1UL << minor);
}
bool gpio_read(uint8_t gpio) {
uint8_t major, minor;
major = gpio / 32;
minor = gpio % 32;
return (*(GPIO_DATA0 + major) >> minor) & 1;
}

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* 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 libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
#ifndef ADC_H
#define ADC_H
#include <stdint.h>
#include "utils.h"
/* ADC registers are all 16-bit wide with 16-bit access only */
#define ADC_BASE (0x8000D000)
/* Structure-based register definitions */
struct ADC_struct {
union {
uint16_t COMP[8];
struct {
uint16_t COMP_0;
uint16_t COMP_1;
uint16_t COMP_2;
uint16_t COMP_3;
uint16_t COMP_4;
uint16_t COMP_5;
uint16_t COMP_6;
uint16_t COMP_7;
};
};
uint16_t BAT_COMP_OVER;
uint16_t BAT_COMP_UNDER;
union {
uint16_t SEQ_1;
struct ADC_SEQ_1 {
uint16_t CH0:1;
uint16_t CH1:1;
uint16_t CH2:1;
uint16_t CH3:1;
uint16_t CH4:1;
uint16_t CH5:1;
uint16_t CH6:1;
uint16_t CH7:1;
uint16_t BATT:1;
uint16_t :6;
uint16_t SEQ_MODE:1;
} SEQ_1bits;
};
union {
uint16_t SEQ_2;
struct ADC_SEQ_2 {
uint16_t CH0:1;
uint16_t CH1:1;
uint16_t CH2:1;
uint16_t CH3:1;
uint16_t CH4:1;
uint16_t CH5:1;
uint16_t CH6:1;
uint16_t CH7:1;
uint16_t :7;
uint16_t SEQ_MODE:1;
} SEQ_2bits;
};
union {
uint16_t CONTROL;
struct ADC_CONTROL {
uint16_t ON:1;
uint16_t TIMER1_ON:1;
uint16_t TIMER2_ON:1;
uint16_t SOFT_RESET:1;
uint16_t AD1_FREFHL_EN:1;
uint16_t AD2_VREFHL_EN:1;
uint16_t :6;
uint16_t COMPARE_IRQ_MASK:1;
uint16_t SEQ1_IRQ_MASK:1;
uint16_t SEQ2_IRQ_MASK:1;
uint16_t FIFO_IRQ_MASK:1;
} CONTROLbits;
};
uint16_t TRIGGERS;
uint16_t PRESCALE;
uint16_t reserved1;
uint16_t FIFO_READ;
uint16_t FIFO_CONTROL;
union {
uint16_t FIFO_STATUS;
struct ADC_FIFO_STATUS {
uint16_t LEVEL:4;
uint16_t FULL:1;
uint16_t EMPTY:1;
uint16_t :10;
} FIFO_STATUSbits;
};
uint16_t reserved2[5];
uint16_t SR_1_HIGH;
uint16_t SR_1_LOW;
uint16_t SR_2_HIGH;
uint16_t SR_2_LOW;
uint16_t ON_TIME;
uint16_t CONVERT_TIME;
uint16_t CLOCK_DIVIDER;
uint16_t reserved3;
union {
uint16_t OVERRIDE;
struct ADC_OVERRIDE {
uint16_t MUX1:4;
uint16_t MUX2:4;
uint16_t AD1_ON:1;
uint16_t AD2_ON:1;
uint16_t :6;
} OVERRIDEbits;
};
uint16_t IRQ;
uint16_t MODE;
uint16_t RESULT_1;
uint16_t RESULT_2;
};
static volatile struct ADC_struct * const ADC = (void *) (ADC_BASE);
#define NUM_ADC_CHAN 9
#define adc_enable() (ADC->CONTROLbits.ON = 1)
#define adc_disable() (ADC->CONTROLbits.ON = 0)
#define adc_select_channels(chans) (ADC->SEQ_1 = (ADC->SEQ_1 & 0xFE00) | chans)
extern uint16_t adc_reading[NUM_ADC_CHAN];
void ADC_flush(void);
uint16_t ADC_READ(void);
void read_scanners(void);
void adc_init(void);
void adc_service(void);
#endif

View file

@ -0,0 +1,28 @@
#ifndef GPIO_UTIL_H
#define GPIO_UTIL_H
#include <stdbool.h>
#include <stdint.h>
void gpio_select_function(uint8_t gpio, uint8_t func);
void gpio_reg_set(volatile uint32_t* reg, uint8_t bit);
void gpio_reg_clear(volatile uint32_t* reg, uint8_t bit);
#define PAD_DIR_INPUT 0
#define PAD_DIR_OUTPUT 1
void gpio_set_pad_dir(uint8_t gpio, uint8_t dir);
#undef gpio_set
#undef gpio_reset
#undef gpio_read
//#define gpio_set gpio_set_ian
//#define gpio_reset gpio_reset_ian
//#define gpio_read gpio_read_ian
void gpio_set(uint8_t gpio);
void gpio_reset(uint8_t gpio);
bool gpio_read(uint8_t gpio);
#endif

View file

@ -121,8 +121,8 @@ enum {
#define LFSR 6 /* 1 use polynomial for Turbolink */
#define TM 5
#define MODE 3
#define MODE_MASK bit_mask(2,MODE)
#define MACA_MODE 3
#define MODE_MASK bit_mask(2,MACA_MODE)
#define NO_CCA 0
#define NO_SLOT_CCA 1
#define SLOT_CCA 2

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* 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 libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
#ifndef PWM_H
#define PWM_H
/* Initialize PWM output.
timer_num = 0, 1, 2, 3
rate = desired rate in Hz,
duty = desired duty cycle. 0=always off, 65536=always on.
enable_timer = whether to actually run the timer, versus just configuring it
Returns actual PWM rate. */
uint32_t pwm_init_ex(int timer_num, uint32_t rate, uint32_t duty, int enable_timer);
/* Initialize PWM output, helper macros
timer = TMR0, TMR1, TMR2, TMR2
rate = desired rate in Hz,
duty = desired duty cycle. 0=always off, 65536=always on.
Returns actual PWM rate. */
#define pwm_init(timer,rate,duty) pwm_init_ex(TMR_NUM(timer), rate, duty, 1)
#define pwm_init_stopped(timer,rate,duty) pwm_init_ex(TMR_NUM(timer), rate, duty, 0)
/* Change duty cycle. Safe to call at any time.
timer_num = 0, 1, 2, 3
duty = desired duty cycle. 0=always off, 65536=always on.
*/
void pwm_duty_ex(int timer_num, uint32_t duty);
/* Change duty cycle. Safe to call at any time.
timer = TMR0, TMR1, TMR2, TMR2
duty = desired duty cycle. 0=always off, 65536=always on.
*/
#define pwm_duty(timer,duty) pwm_duty_ex(TMR_NUM(timer), duty)
#endif

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* 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 libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
#ifndef RTC_H
#define RTC_H
/* Init RTC (and calibrate, if using ring oscillator) */
void rtc_init_osc(int use_32khz);
#ifdef USE_32KHZ
#define rtc_init() rtc_init_osc(USE_32KHZ)
#else
#define rtc_init() rtc_init_osc(0)
#endif
/* Calibrate the ring oscillator */
void rtc_calibrate(void);
/* Delay for the specified number of milliseconds by polling RTC */
void rtc_delay_ms(uint32_t msec);
/* Calibrated frequency of the RTC, in Hz */
extern int rtc_freq;
#endif

View file

@ -184,7 +184,7 @@ void maca_init(void) {
/* nop, promiscuous, no cca */
*MACA_CONTROL =
(prm_mode << PRM) |
(NO_CCA << MODE);
(NO_CCA << MACA_MODE);
enable_irq(MACA);
*INTFRC = (1 << INT_NUM_MACA);

254
cpu/mc1322x/lib/pwm.c Normal file
View file

@ -0,0 +1,254 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* 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 libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
#include <mc1322x.h>
#include <stdlib.h>
#include "pwm.h"
static struct {
uint32_t period;
uint32_t guard;
uint32_t pad_forced;
} pwm_info[4];
static inline void pad_set_output(int timer_num) { // set to output (when in GPIO mode)
switch (timer_num) {
case 0: GPIO->DATA_SEL.TMR0_PIN = 1; GPIO->PAD_DIR.TMR0_PIN = 1; break;
case 1: GPIO->DATA_SEL.TMR1_PIN = 1; GPIO->PAD_DIR.TMR1_PIN = 1; break;
case 2: GPIO->DATA_SEL.TMR2_PIN = 1; GPIO->PAD_DIR.TMR2_PIN = 1; break;
case 3: GPIO->DATA_SEL.TMR3_PIN = 1; GPIO->PAD_DIR.TMR3_PIN = 1; break;
default: break;
}
}
static inline void pad_set_zero(int timer_num) { // set to zero in GPIO mode
switch (timer_num) {
case 0: GPIO->DATA_RESET.TMR0_PIN = 1; GPIO->FUNC_SEL.TMR0_PIN = 0; break;
case 1: GPIO->DATA_RESET.TMR1_PIN = 1; GPIO->FUNC_SEL.TMR1_PIN = 0; break;
case 2: GPIO->DATA_RESET.TMR2_PIN = 1; GPIO->FUNC_SEL.TMR2_PIN = 0; break;
case 3: GPIO->DATA_RESET.TMR3_PIN = 1; GPIO->FUNC_SEL.TMR3_PIN = 0; break;
default: break;
}
}
static inline void pad_set_one(int timer_num) { // set to one in GPIO mode
switch (timer_num) {
case 0: GPIO->DATA_SET.TMR0_PIN = 1; GPIO->FUNC_SEL.TMR0_PIN = 0; break;
case 1: GPIO->DATA_SET.TMR1_PIN = 1; GPIO->FUNC_SEL.TMR1_PIN = 0; break;
case 2: GPIO->DATA_SET.TMR2_PIN = 1; GPIO->FUNC_SEL.TMR2_PIN = 0; break;
case 3: GPIO->DATA_SET.TMR3_PIN = 1; GPIO->FUNC_SEL.TMR3_PIN = 0; break;
default: break;
}
}
static inline void pad_set_normal(int timer_num) { // set to TMR OFLAG output
switch (timer_num) {
case 0: GPIO->FUNC_SEL.TMR0_PIN = 1; break;
case 1: GPIO->FUNC_SEL.TMR1_PIN = 1; break;
case 2: GPIO->FUNC_SEL.TMR2_PIN = 1; break;
case 3: GPIO->FUNC_SEL.TMR3_PIN = 1; break;
default: break;
}
}
/* Initialize PWM output.
timer_num = 0, 1, 2, 3
rate = desired rate in Hz,
duty = desired duty cycle. 0=always off, 65536=always on.
enable_timer = whether to actually run the timer, versus just configuring it
Returns actual PWM rate. */
uint32_t pwm_init_ex(int timer_num, uint32_t rate, uint32_t duty, int enable_timer)
{
uint32_t actual_rate;
volatile struct TMR_struct *timer = TMR_ADDR(timer_num);
int log_divisor = 0;
uint32_t period, guard;
/* Turn timer off */
TMR0->ENBL &= ~(1 << timer_num);
/* Calculate optimal rate */
for (log_divisor = 0; log_divisor < 8; log_divisor++)
{
int denom = (rate * (1 << log_divisor));
period = (REF_OSC + denom/2) / denom;
if (period <= 65535)
break;
}
if (log_divisor >= 8)
{
period = 65535;
log_divisor = 7;
}
/* Guard value (for safely changing duty cycle) should be
about 32 CPU clocks. Calculate how many timer counts that
is, based on prescaler */
guard = 32 >> log_divisor;
if (guard < 2) guard = 2;
/* Period should be about 50% longer than guard */
if (period < ((guard * 3) / 2))
period = guard + 4;
/* Store period, guard, actual rate */
pwm_info[timer_num].period = period;
pwm_info[timer_num].guard = guard;
actual_rate = REF_OSC / (period * (1 << log_divisor));
/* Set up timer */
pwm_duty_ex(timer_num, duty); // sets CMPLD1, LOAD
timer->SCTRLbits = (struct TMR_SCTRL) {
.OEN = 1, // drive OFLAG
};
timer->CSCTRLbits = (struct TMR_CSCTRL) {
.CL1 = 0x01, // Reload COMP1 when COMP1 matches
};
timer->COMP1 = timer->CMPLD1;
timer->CNTR = timer->LOAD;
timer->CTRLbits = (struct TMR_CTRL) {
.COUNT_MODE = 1, // Count rising edge of primary source
.PRIMARY_CNT_SOURCE = 8 + log_divisor, // Peripheral clock divided by (divisor)
.LENGTH = 1, // At compare, reset to LOAD
.OUTPUT_MODE = 6, // Set on COMP1, clear on rollover
};
pad_set_output(timer_num);
pad_set_normal(timer_num);
if (enable_timer) {
TMR0->ENBL |= (1 << timer_num);
}
// printf("pwm timer %d, addr %p, requested rate %d, actual rate: %d, period %d, guard %d, divisor %d\r\n",
// timer_num, timer, rate, actual_rate, period, guard, 1 << log_divisor);
return actual_rate;
}
/* Change duty cycle. Safe to call at any time.
timer_num = 0, 1, 2, 3
duty = desired duty cycle. 0=always off, 65536=always on.
*/
void pwm_duty_ex(int timer_num, uint32_t duty)
{
uint16_t comp1, load;
volatile struct TMR_struct *timer = TMR_ADDR(timer_num);
uint32_t period = pwm_info[timer_num].period;
duty = (duty * period + 32767) / 65536;
/* We don't use the "variable PWM" mode described in the datasheet because
there's no way to reliably change the duty cycle without potentially
changing the period for one cycle, which will cause phase drifts.
Instead, we use the "Set on compare, clear on rollover" output mode:
waveform: |_________| |----------|
counter: 0 COMP1 LOAD 65535
The low portion of the wave is COMP1 cycles long. The
compare changes the counter to LOAD, and so the high
portion is (65536 - LOAD) cycles long.
Now, we just have to make sure we're not about to hit COMP1
before we change LOAD and COMPLD1. If (COMP1 - CNTR) is less
than GUARD cycles, we wait for it to reload before changing.
*/
if (duty == 0) {
pad_set_zero(timer_num);
pwm_info[timer_num].pad_forced = 1;
return;
}
if (duty >= period) {
pad_set_one(timer_num);
pwm_info[timer_num].pad_forced = 1;
return;
}
if (pwm_info[timer_num].pad_forced) {
pad_set_normal(timer_num);
pwm_info[timer_num].pad_forced = 0;
}
comp1 = (period - duty) - 1;
load = (65536 - duty);
/* Disable interrupts */
uint32_t old_INTCNTL = ITC->INTCNTL;
ITC->INTCNTL = 0;
if (TMR0->ENBL & (1 << timer_num))
{
/* Timer is enabled, so use the careful approach.
Implemented in ASM so we can be sure of the cycle
count */
uint32_t tmp1, tmp2;
asm volatile (//".arm \n\t"
"1: \n\t"
"ldrh %[tmp1], %[comp] \n\t" // load COMP1
"ldrh %[tmp2], %[count] \n\t" // load CNTR
"sub %[tmp1], %[tmp1], %[tmp2] \n\t" // subtract
"lsl %[tmp1], %[tmp1], #16 \n\t" // clear high bits
"lsr %[tmp1], %[tmp1], #16 \n\t"
"cmp %[tmp1], %[guard] \n\t" // compare to GUARD
"bls 1b \n\t" // if less, goto 1
"strh %[ld1], %[cmpld] \n\t" // store CMPLD1
"strh %[ld2], %[load] \n\t" // store LOAD
: /* out */
[tmp1] "=&l" (tmp1),
[tmp2] "=&l" (tmp2),
[cmpld] "=m" (timer->CMPLD1),
[load] "=m" (timer->LOAD)
: /* in */
[comp] "m" (timer->COMP1),
[count] "m" (timer->CNTR),
[ld1] "l" (comp1),
[ld2] "l" (load),
[guard] "l" (pwm_info[timer_num].guard)
: "memory"
);
} else {
/* Just set it directly, timer isn't running */
timer->CMPLD1 = comp1;
timer->LOAD = load;
}
/* Re-enable interrupts */
ITC->INTCNTL = old_INTCNTL;
}

202
cpu/mc1322x/lib/rtc.c Normal file
View file

@ -0,0 +1,202 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* 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 libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
#include <mc1322x.h>
#include <stdlib.h>
#include "rtc.h"
/* Define USE_32KHZ in board.h to start and use the 32 KHz
oscillator, otherwise the 2 KHz ring oscillator is used. */
int rtc_freq = 0;
static int __use_32khz = 0;
/* Init RTC */
void rtc_init_osc(int use_32khz)
{
__use_32khz = use_32khz;
if (use_32khz)
{
uint32_t old;
/* You have to hold its hand with this one */
/* once you start the 32KHz crystal it can only be
* stopped with a reset (hard or soft). */
/* first, disable the ring osc */
CRM->RINGOSC_CNTLbits.ROSC_EN = 0;
/* enable the 32kHZ crystal */
CRM->XTAL32_CNTLbits.XTAL32_EN = 1;
/* set the XTAL32_EXISTS bit */
/* the datasheet says to do this after you check that RTC_COUNT
is changing, but it is not correct; it needs to be set first */
CRM->SYS_CNTLbits.XTAL32_EXISTS = 1;
old = CRM->RTC_COUNT;
while (CRM->RTC_COUNT == old)
continue;
/* RTC has started up */
rtc_freq = 32000;
}
else
{
/* Enable ring osc */
CRM->RINGOSC_CNTLbits.ROSC_EN = 1;
CRM->XTAL32_CNTLbits.XTAL32_EN = 0;
/* Set default tune values from datasheet */
CRM->RINGOSC_CNTLbits.ROSC_CTUNE = 0x6;
CRM->RINGOSC_CNTLbits.ROSC_FTUNE = 0x17;
/* Trigger calibration */
rtc_calibrate();
}
}
uint32_t __rtc_try(int loading, int timeout)
{
/* Total loading is
ctune * 1000 fF + ftune * 160 fF
ctune = 0-15
ftune = 0-31
max = 19960 fF
*/
#define RTC_LOADING_MIN 0
#define RTC_LOADING_MAX 19960
/* The fine tune covers a range larger than a single coarse
step. Check all coarse steps within the fine tune range to
find the optimal CTUNE, FTUNE pairs. */
#define CTUNE_MAX 15
#define FTUNE_MAX 31
#define CSTEP 1000
#define FSTEP 160
#define MAX_F (FSTEP*FTUNE_MAX) /* actually lcm(CSTEP,FSTEP) would be better,
but in this case it's basically the same */
int ctune;
int ftune;
int ctune_start = (loading - MAX_F) / CSTEP;
int ctune_end = loading / CSTEP;
int best_err = loading, best_ctune = 0, best_ftune = 0;
uint32_t count;
if (ctune_start < 0) ctune_start = 0;
if (ctune_end > CTUNE_MAX) ctune_end = CTUNE_MAX;
for (ctune = ctune_start; ctune <= ctune_end; ctune++)
{
int this_loading, this_err;
ftune = ((loading - (ctune * CSTEP)) + (FSTEP / 2)) / FSTEP;
if (ftune < 0) ftune = 0;
if (ftune > FTUNE_MAX) ftune = FTUNE_MAX;
this_loading = ctune * CSTEP + ftune * FSTEP;
this_err = abs(this_loading - loading);
if (this_err < best_err) {
best_err = this_err;
best_ctune = ctune;
best_ftune = ftune;
}
}
// printf("requested loading %d, actual loading %d\r\n", loading,
// best_ctune * CSTEP + best_ftune * FSTEP);
/* Run the calibration */
CRM->RINGOSC_CNTLbits.ROSC_CTUNE = best_ctune;
CRM->RINGOSC_CNTLbits.ROSC_FTUNE = best_ftune;
CRM->CAL_CNTLbits.CAL_TIMEOUT = timeout;
CRM->STATUSbits.CAL_DONE = 1;
CRM->CAL_CNTLbits.CAL_EN = 1;
while (CRM->STATUSbits.CAL_DONE == 0)
continue;
/* Result should ideally be close to (REF_OSC * (timeout / 2000)) */
count = CRM->CAL_COUNT;
if (count == 0) count = 1; /* avoid divide by zero problems */
return count;
}
/* Calibrate the ring oscillator */
void rtc_calibrate(void)
{
/* Just bisect a few times. Our best tuning accuracy is about
1/500 of the full scale, so doing this 8-9 times is about
as accurate as we can get */
int i;
int low = RTC_LOADING_MIN, high = RTC_LOADING_MAX;
int mid;
uint32_t count;
if (__use_32khz) {
rtc_freq = 32000;
return;
}
#define TIMEOUT 100 /* 50 msec per attempt */
for (i = 0; i < 9; i++)
{
mid = (low + high) / 2;
count = __rtc_try(mid, TIMEOUT);
// careful about overflow
rtc_freq = REF_OSC / ((count + TIMEOUT/2) / TIMEOUT);
if (rtc_freq > 2000)
low = mid; // increase loading
else
high = mid; // decrease loading
}
// printf("RTC calibrated to %d Hz\r\n", rtc_freq);
}
/* Delay for the specified number of milliseconds by polling RTC */
void rtc_delay_ms(uint32_t msec)
{
uint32_t start;
start = CRM->RTC_COUNT;
while ((CRM->RTC_COUNT - start) < ((msec * rtc_freq) / 1000))
continue;
}

View file

@ -11,7 +11,9 @@ TARGETS := blink-red blink-green blink-blue blink-white blink-allio \
tmr tmr-ints \
sleep \
printf \
asm
asm \
adc \
pwm
# these targets are built with space reserved for variables needed by ROM services
# this space is initialized with a rom call to rom_data_init

63
cpu/mc1322x/tests/adc.c Normal file
View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* 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 libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
#include <mc1322x.h>
#include <board.h>
#include <stdio.h>
#include "config.h"
#include "adc.h"
int main(void)
{
uint8_t c;
trim_xtal();
uart1_init(INC,MOD,SAMP);
adc_init();
printf("adc test\r\n");
printf("\x1B[2J"); // clear screen
for(;;) {
printf("\x1B[H"); // cursor home
printf("# Value\r\n");
for (c=0; c<NUM_ADC_CHAN; c++) {
adc_service();
printf("%u %04u\r\n", c, adc_reading[c]);
}
}
}

85
cpu/mc1322x/tests/pwm.c Normal file
View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* 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 libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
#include <mc1322x.h>
#include <board.h>
#include <stdio.h>
#include "config.h"
#include "pwm.h"
#include "rtc.h"
int main(void)
{
int x = 32768;
trim_xtal();
uart1_init(INC,MOD,SAMP);
rtc_init();
printf("pwm test\r\n");
pwm_init_stopped(TMR0, 12000000, x);
pwm_init_stopped(TMR1, 12000000, x);
TMR0->ENBL |= TMR_ENABLE_BIT(TMR0) | TMR_ENABLE_BIT(TMR1);
for(;;) {
printf("duty %d = %d%%\r\n", x, ((x * 100 + 32768) / 65536));
switch(uart1_getc()) {
case '[': x -= 1; break;
case ']': x += 1; break;
case '-': x -= 32; break;
case '=': x += 32; break;
case '_': x -= 512; break;
case '+': x += 512; break;
case '`': x = 65535 * 0/10; break;
case '1': x = 65535 * 1/10; break;
case '2': x = 65535 * 2/10; break;
case '3': x = 65535 * 3/10; break;
case '4': x = 65535 * 4/10; break;
case '5': x = 65535 * 5/10; break;
case '6': x = 65535 * 6/10; break;
case '7': x = 65535 * 7/10; break;
case '8': x = 65535 * 8/10; break;
case '9': x = 65535 * 9/10; break;
case '0': x = 65535 * 10/10; break;
}
x &= 65535;
pwm_duty(TMR0, x);
}
}

82
cpu/mc1322x/tools/bin2macbin.pl Executable file
View file

@ -0,0 +1,82 @@
#!/usr/bin/perl
use strict;
use File::Copy;
use Getopt::Long;
use File::Basename;
my $cmd;
my $oui;
my $iab;
GetOptions ('iab=s' => \$iab,
'oui=s' => \$oui,
) or die 'bad options';
my $address = shift;
my $infile = shift;
my $outfile = shift;
if (!defined($address) || !defined($infile)) {
print "Usage: $0 [--iab=a8c | --oui=abcdef ] address infile [outfile]\n";
print " iab is 12-bit and address is 28-bit e.g. --iab=a8c 1234567\n";
print " oui is 24-bit and address is 40-bit e.g. --oui=abcdef 123456789a\n";
print "\n";
print " if outfile is not specified, for infile foo.bin outfile will be\n";
print " foo-[macaddress].bin e.g:\n";
print " for --iab=a8c 1234567 foo.bin -> foo-0050c2a8c1234567.bin\n";
print " for --oui=abcdef 123456789a foo.bin -> foo-abcdef123456789a.bin\n";
exit;
}
my $mac_h;
my $mac_l;
if(defined($iab)) {
$iab = hex($iab);
$address = hex($address);
$mac_h = 0x0050C200 | ($iab >> 4);
$mac_l = (($iab & 0xf) << 28) | $address;
} else {
$address =~ /(.*?)(.{0,8})$/;
my ($addr_h, $addr_l) = ($1, $2);
if(!$addr_h) { $addr_h = 0 };
$oui = hex($oui);
$addr_l = hex($addr_l);
$addr_h = hex($addr_h);
$mac_h = ($oui << 8) | $addr_h;
$mac_l = $addr_l;
}
printf("mach %x macl %x\n", $mac_h, $mac_l);
my @words;
for(my $i=0; $i<4; $i++) {
push @words, ($mac_l >> ($i * 8)) & 0xff;
}
for(my $i=0; $i<4; $i++) {
push @words, ($mac_h >> ($i * 8)) & 0xff;
}
reverse @words;
#foreach my $byte (@words) {
# printf("%02X",$byte);
#}
#print "\n";
if(!defined($outfile))
{
my $basename = basename($infile,(".bin"));
$outfile = sprintf("-%08x%08x.bin",$mac_h, $mac_l);
$outfile = $basename . $outfile;
print "outfile $outfile\n";
}
copy($infile, $outfile) or die("Couldn't copy $infile to $outfile");
$cmd = sprintf("echo -n -e '\\x%02X\\x%02X\\x%02X\\x%02X\\x%02X\\x%02X\\x%02X\\x%02X' | dd of=$outfile bs=1 seek=122872 conv=notrunc",
$words[7],$words[6],$words[5],$words[4],
$words[3],$words[2],$words[1],$words[0]);
print "$cmd\n";
system("bash -c \"$cmd\"");

65
cpu/mc1322x/tools/burn-mac.pl Executable file
View file

@ -0,0 +1,65 @@
#!/usr/bin/perl
use strict;
use Getopt::Long;
my $oui;
my $addr = "0x1e000";
my $iab;
my $term = "/dev/ttyUSB1";
GetOptions ('iab=s' => \$iab,
'oui=s' => \$oui,
'term=s' => \$term,
) or die 'bad options';
my $bin = shift;
my $address = shift;
if (!defined($address) || !defined($bin)) {
print "Usage: $0 [--iab=a8c | --oui=abcdef | --term device] flasher.bin address\n";
print " iab is 12-bit and address is 28-bit e.g. --iab=a8c 1234567\n";
print " oui is 24-bit and address is 40-bit e.g. --oui=abcdef 123456789a\n";
exit;
}
my $mac_h;
my $mac_l;
if(defined($iab)) {
$iab = hex($iab);
$address = hex($address);
$mac_h = 0x0050C200 | ($iab >> 4);
$mac_l = (($iab & 0xf) << 28) | $address;
} else {
$address =~ /(.*?)(.{0,8})$/;
my ($addr_h, $addr_l) = ($1, $2);
if(!$addr_h) { $addr_h = 0 };
$oui = hex($oui);
$addr_l = hex($addr_l);
$addr_h = hex($addr_h);
$mac_h = ($oui << 8) | $addr_h;
$mac_l = $addr_l;
}
printf("mach %x macl %x\n", $mac_h, $mac_l);
my @words;
for(my $i=0; $i<4; $i++) {
push @words, ($mac_l >> ($i * 8)) & 0xff;
}
for(my $i=0; $i<4; $i++) {
push @words, ($mac_h >> ($i * 8)) & 0xff;
}
reverse @words;
#foreach my $byte (@words) {
# printf("%02X",$byte);
#}
#print "\n";
my $word1 = sprintf("%02X%02X%02X%02X",$words[4],$words[5],$words[6],$words[7]);
my $word2 = sprintf("%02X%02X%02X%02X",$words[0],$words[1],$words[2],$words[3]);
my $cmd = "mc1322x-load.pl -e -f $bin -z -t $term -c 'bbmc -l redbee-econotag reset' $addr,0x$word1,0x$word2 &";
print "$cmd\n";
system($cmd);

View file

@ -5,11 +5,14 @@ my $bin = shift;
my $terms = shift;
my $addr = "0x1e000";
my $company_id;
my $iab = 0xabc; # Redwire, LLC's IAB
my $iab = 0xa8c; # Redwire, LLC's IAB
my $mac_h;
my $mac_l;
if(defined($iab)) {
$company_id = (0x0050C2 << 12) | $iab;
$mac_h = 0x0050C200 | ($iab >> 4);
$mac_l = ($iab & 0xf) << 28;
}
if (! $terms) {
@ -19,15 +22,17 @@ if (! $terms) {
for (my $t=0; $t<$terms; $t++) {
my $dev_num = 2 * $t + 1;
$mac_l |= $dev_num;
#stupid 32-bit thing...
my $mac;
if(defined($iab)) {
$mac = ($company_id << 28) | $dev_num;
} else {
$mac = ($company_id << 40) | $dev_num;
}
printf("mac_h %x\n", $mac_h);
printf("mac_l %x\n", $mac_l);
my @words;
for(my $i=0; $i<8; $i++) {
push @words, ($mac >> ($i * 8)) & 0xff;
for(my $i=0; $i<4; $i++) {
push @words, ($mac_h >> ($i * 8)) & 0xff;
}
for(my $i=0; $i<4; $i++) {
push @words, ($mac_l >> ($i * 8)) & 0xff;
}
reverse @words;
foreach my $byte (@words) {

View file

@ -5,10 +5,17 @@ CONTIKI=../../..
WITH_UIP6=1
UIP_CONF_IPV6=1
APPS += webserver
#Override inclusion of internal webserver with make WITH_WEBSERVER=0
WITH_WEBSERVER=1
ifeq ($(WITH_WEBSERVER), 0)
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
PROJECT_SOURCEFILES += slip-bridge.c
else
APPS += webserver
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -DWEBSERVER
PROJECT_SOURCEFILES += slip-bridge.c httpd-simple.c
endif
include $(CONTIKI)/Makefile.include

View file

@ -45,8 +45,13 @@
#include "net/netstack.h"
#include "dev/button-sensor.h"
#include "dev/slip.h"
/* For internal webserver Makefile must set APPS += webserver and PROJECT_SOURCEFILES += httpd-simple.c */
#if WEBSERVER
#include "webserver-nogui.h"
#include "httpd-simple.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -65,6 +70,8 @@ static uint8_t prefix_set;
PROCESS(border_router_process, "Border router process");
AUTOSTART_PROCESSES(&border_router_process);
#if WEBSERVER
/*---------------------------------------------------------------------------*/
/* Only one single web request at time */
static const char *TOP = "<html><head><title>ContikiRPL</title></head><body>\n";
@ -151,6 +158,9 @@ httpd_simple_get_script(const char *name)
{
return generate_routes;
}
#endif /* WEBSERVER */
/*---------------------------------------------------------------------------*/
static void
print_local_addresses(void)
@ -158,14 +168,14 @@ print_local_addresses(void)
int i;
uint8_t state;
PRINTF("Server IPv6 addresses:\n");
PRINTA("Server IPv6 addresses:\n");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused &&
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
blen = 0;
ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF(" %s\n", buf);
PRINTA(" ");
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
PRINTA("\n");
}
}
}
@ -202,7 +212,10 @@ PROCESS_THREAD(border_router_process, ev, data)
PROCESS_PAUSE();
#if WEBSERVER
process_start(&webserver_nogui_process, NULL);
#endif
SENSORS_ACTIVATE(button_sensor);
PRINTF("RPL-Border router started\n");
@ -220,7 +233,9 @@ PROCESS_THREAD(border_router_process, ev, data)
PRINTF("created a new RPL dag\n");
}
#if DEBUG || 1
print_local_addresses();
#endif
/* The border router runs with a 100% duty cycle in order to ensure high
packet reception rates. */

View file

@ -3,6 +3,8 @@ CONTIKI_TARGET_DIRS = . apps net loader
CONTIKI_CORE=contiki-main
CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o
CONTIKI_TARGET_SOURCEFILES += contiki-main.c
#Needed for slip
CONTIKI_TARGET_SOURCEFILES += button-sensor.c sensors.c slip_uart0.c slip.c
CONTIKIAVR=$(CONTIKI)/cpu/avr
CONTIKIBOARD=.

View file

@ -0,0 +1,45 @@
/* Dummy sensor routine */
#include "lib/sensors.h"
#include "dev/button-sensor.h"
const struct sensors_sensor button_sensor;
static int status(int type);
struct sensors_sensor *sensors[1];
unsigned char sensors_flags[1];
static int
value(int type)
{
return 0;
}
static int
configure(int type, int c)
{
switch (type) {
case SENSORS_ACTIVE:
if (c) {
if(!status(SENSORS_ACTIVE)) {
}
} else {
}
return 1;
}
return 0;
}
static int
status(int type)
{
switch (type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return 1;
}
return 0;
}
SENSORS_SENSOR(button_sensor, BUTTON_SENSOR,
value, configure, status);

View file

@ -28,19 +28,14 @@
*
* This file is part of the Contiki operating system.
*
* @(#)$$
*/
#ifndef LED_ON_PORT1E
#define LED_ON_PORTE1 0 //for Michael Hartman's prototype board
#endif
#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size
#define DEBUG 0
#if DEBUG
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#define PRINTSHORT(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTF(...)
#define PRINTSHORT(...)
#endif
#define DEBUG DEBUG_PRINT
#include "uip-debug.h" ////Does #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) for AVR
#include <avr/pgmspace.h>
#include <avr/fuse.h>
@ -96,6 +91,21 @@
#include "net/rime.h"
/* Test rtimers, also for pings, stack monitor, neighbor/route printout and time stamps */
#define TESTRTIMER 1
#if TESTRTIMER
//#define PINGS 64
#define ROUTES 64
#define STAMPS 30
#define STACKMONITOR 128
uint8_t rtimerflag=1;
uint16_t rtime;
struct rtimer rt;
void rtimercycle(void) {rtimerflag=1;}
#endif /* TESTRTIMER */
/*-------------------------------------------------------------------------*/
/*----------------------Configuration of the .elf file---------------------*/
typedef struct {unsigned char B2;unsigned char B1;unsigned char B0;} __signature_t;
@ -120,7 +130,7 @@ extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via mak
extern uint8_t server_name[16];
extern uint8_t domain_name[30];
#else
uint8_t mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
#endif
@ -171,15 +181,16 @@ extern uint8_t osccal_calibrated;
/*------Done in a subroutine to keep main routine stack usage small--------*/
void initialize(void)
{
watchdog_init();
watchdog_start();
#ifdef RAVEN_LCD_INTERFACE
#if !LED_ON_PORTE1 //Conflicts with USART0
#if RAVEN_LCD_INTERFACE
/* First rs232 port for Raven 3290 port */
//conflicts with led on Hartmann's board, so bypass for now
// rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
/* Set input handler for 3290 port */
// rs232_set_input(0,raven_lcd_serial_input);
rs232_set_input(0,raven_lcd_serial_input);
#else
//Slip border router on uart0
rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
#endif
#endif
/* Second rs232 port for debugging */
@ -187,27 +198,55 @@ void initialize(void)
/* Redirect stdout to second port */
rs232_redirect_stdout(RS232_PORT_1);
clock_init();
#if 1
if(MCUSR & (1<<PORF )) PRINTA("Power-on reset.\n");
if(MCUSR & (1<<EXTRF)) PRINTA("External reset!\n");
if(MCUSR & (1<<BORF )) PRINTA("Brownout reset!\n");
if(MCUSR & (1<<WDRF )) PRINTA("Watchdog reset!\n");
if(MCUSR & (1<<JTRF )) PRINTA("JTAG reset!\n");
#endif
watchdog_init();
watchdog_start();
#define CONF_CALIBRATE_OSCCAL 1
#if STACKMONITOR
/* Simple stack pointer highwater monitor. Checks for magic numbers in the main
* loop. In conjuction with TESTRTIMER, never-used stack will be printed
* every STACKMONITOR seconds.
*/
{
extern uint16_t __bss_end;
uint16_t p=(uint16_t)&__bss_end;
do {
*(uint16_t *)p = 0x4242;
p+=10;
} while (p<SP-10); //don't overwrite our own stack
}
#endif
#define CONF_CALIBRATE_OSCCAL 0
#if CONF_CALIBRATE_OSCCAL
{
uint8_t i;
printf_P(PSTR("\nBefore calibration OSCCAL=%x\n"),OSCCAL);
watchdog_stop();
PRINTA("\nBefore calibration OSCCAL=%x\n",OSCCAL);
for (i=0;i<10;i++) {
calibrate_rc_osc_32k();
printf_P(PSTR("Calibrated=%x\n"),osccal_calibrated);
PRINTA("Calibrated=%x\n",osccal_calibrated);
//#include <util/delay_basic.h>
//#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) )
// delay_us(50000);
}
clock_init();
watchdog_start();
}
#endif
#if ANNOUNCE_BOOT
printf_P(PSTR("\n*******Booting %s*******\n"),CONTIKI_VERSION_STRING);
PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
#endif
watchdog_start();
/* rtimers needed for radio cycling */
rtimer_init();
@ -249,19 +288,19 @@ uint8_t i;
NETSTACK_NETWORK.init();
#if ANNOUNCE_BOOT
printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
PRINTA("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac
unsigned short tmp;
tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
NETSTACK_RDC.channel_check_interval());
if (tmp<65535) printf_P(PSTR(", check rate %u Hz"),tmp);
if (tmp<65535) PRINTA(", check rate %u Hz",tmp);
}
printf_P(PSTR("\n"));
PRINTA("\n");
#endif
#if UIP_CONF_ROUTER
#if ANNOUNCE_BOOT
printf_P(PSTR("Routing Enabled\n"));
PRINTA("Routing Enabled\n");
#endif
// rime_init(rime_udp_init(NULL));
// uip_router_register(&rimeroute);
@ -289,13 +328,13 @@ uint8_t i;
#if COFFEE_FILES
int fa = cfs_open( "/index.html", CFS_READ);
if (fa<0) { //Make some default web content
printf_P(PSTR("No index.html file found, creating upload.html!\n"));
printf_P(PSTR("Formatting FLASH file system for coffee..."));
PRINTF("No index.html file found, creating upload.html!\n");
PRINTA("Formatting FLASH file system for coffee...");
cfs_coffee_format();
printf_P(PSTR("Done!\n"));
PRINTA("Done!\n");
fa = cfs_open( "/index.html", CFS_WRITE);
int r = cfs_write(fa, &"It works!", 9);
if (r<0) printf_P(PSTR("Can''t create /index.html!\n"));
if (r<0) PRINTF("Can''t create /index.html!\n");
cfs_close(fa);
// fa = cfs_open("upload.html"), CFW_WRITE);
// <html><body><form action="upload.html" enctype="multipart/form-data" method="post"><input name="userfile" type="file" size="50" /><input value="Upload" type="submit" /></form></body></html>
@ -323,29 +362,29 @@ uint8_t i;
for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) {
httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf);
printf_P(PSTR("IPv6 Address: %s\n"),buf);
PRINTA("IPv6 Address: %s\n",buf);
}
}
eeprom_read_block (buf,server_name, sizeof(server_name));
buf[sizeof(server_name)]=0;
printf_P(PSTR("%s"),buf);
PRINTA("%s",buf);
eeprom_read_block (buf,domain_name, sizeof(domain_name));
buf[sizeof(domain_name)]=0;
size=httpd_fs_get_size();
#ifndef COFFEE_FILES
printf_P(PSTR(".%s online with fixed %u byte web content\n"),buf,size);
PRINTA(".%s online with fixed %u byte web content\n",buf,size);
#elif COFFEE_FILES==1
printf_P(PSTR(".%s online with static %u byte EEPROM file system\n"),buf,size);
PRINTA(".%s online with static %u byte EEPROM file system\n",buf,size);
#elif COFFEE_FILES==2
printf_P(PSTR(".%s online with dynamic %u KB EEPROM file system\n"),buf,size>>10);
PRINTA(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10);
#elif COFFEE_FILES==3
printf_P(PSTR(".%s online with static %u byte program memory file system\n"),buf,size);
PRINTA(".%s online with static %u byte program memory file system\n",buf,size);
#elif COFFEE_FILES==4
printf_P(PSTR(".%s online with dynamic %u KB program memory file system\n"),buf,size>>10);
PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
#endif /* COFFEE_FILES */
#else
printf_P(PSTR("Online\n"));
PRINTA("Online\n");
#endif /* WEBSERVER */
#endif /* ANNOUNCE_BOOT */
@ -354,18 +393,8 @@ uint8_t i;
/*---------------------------------------------------------------------------*/
void log_message(char *m1, char *m2)
{
printf_P(PSTR("%s%s\n"), m1, m2);
PRINTA("%s%s\n", m1, m2);
}
/* Test rtimers, also useful for pings and time stamps in simulator */
#define TESTRTIMER 0
#if TESTRTIMER
#define PINGS 60
#define STAMPS 30
uint8_t rtimerflag=1;
uint16_t rtime;
struct rtimer rt;
void rtimercycle(void) {rtimerflag=1;}
#endif /* TESTRTIMER */
#if RF230BB
extern char rf230_interrupt_flag, rf230processflag;
@ -379,98 +408,152 @@ uint16_t ledtimer;
int
main(void)
{
#define CONFIG_STACK_MONITOR 1
#if CONFIG_STACK_MONITOR
extern uint16_t __bss_end;
__bss_end = 0x4242;
*(uint16_t *)(&__bss_end+100) = 0x4242;
#endif
initialize();
#if LED_ON_PORTE1
/* NB: PORTE1 conflicts with UART0 */
DDRE|=(1<<DDE1); //set led pin to output
DDRE|=(1<<DDE1); //set led pin to output (Micheal Hatrtman board)
PORTE&=~(1<<PE1); //and low to turn led off
#endif
while(1) {
process_run();
#if LED_ON_PORTE1
/* Turn off LED after a while */
if (ledtimer) {
if (--ledtimer==0) {
PORTE&=~(1<<PE1);
PORTE&=~(1<<PE1);
/* Currently LED was turned on by received ping; ping the other way for testing */
extern void raven_ping6(void);
raven_ping6(); //ping back
// raven_ping6(); //ping back
}
}
#if CONFIG_STACK_MONITOR
if (*(uint16_t *)(&__bss_end+100) != 0x4242) {
printf_P(PSTR("\nStack Warning, overflow within 100 bytes!\n"));
if (__bss_end != 0x4242) {
__bss_end = 0x4242;
printf_P(PSTR("\n!!!!!!!Stack Overflow!!!!!!!!\n"));
}
*(uint16_t *)(&__bss_end+100) = 0x4242;
}
#endif
#if 0
extern uint8_t rf230_calibrated;
/* Various entry points for debugging in the AVR Studio simulator.
* Set as next statement and step into the routine.
*/
NETSTACK_RADIO.send(packetbuf_hdrptr(), 42);
process_poll(&rf230_process);
packetbuf_clear();
len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
packetbuf_set_datalen(42);
NETSTACK_RDC.input();
#endif
watchdog_periodic();
#if 0
/* Clock.c can trigger a periodic PLL calibration in the RF230BB driver.
* This can show when that happens.
*/
extern uint8_t rf230_calibrated;
if (rf230_calibrated) {
printf_P(PSTR("\nRF230 calibrated!"));
PRINTA("\nRF230 calibrated!\n");
rf230_calibrated=0;
}
#endif
//Various entry points for debugging in AVR simulator
// NETSTACK_RADIO.send(packetbuf_hdrptr(), 42);
// process_poll(&rf230_process);
// packetbuf_clear();
// len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
// packetbuf_set_datalen(42);
// NETSTACK_RDC.input();
watchdog_periodic();
#endif
#if TESTRTIMER
if (rtimerflag) { //8 seconds is maximum interval, my raven 6% slow
/* Timeout can be increased up to 8 seconds maximum.
* A one second cycle is convenient for triggering the various debug printouts.
* The triggers are staggered to avoid printing everything at once.
* My raven is 6% slow.
*/
if (rtimerflag) {
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
rtimerflag=0;
#if STAMPS
if ((rtime%STAMPS)==0) {
printf("%us ",rtime);
#if 0 //test timer0
extern unsigned long seconds;
printf("clock= %lus ",clock_seconds());
printf("scount=%us",scount);
printf(" %us %us",(unsigned int)(seconds&0xffff),(unsigned int)(seconds>>16));
#endif
}
#if STAMPS
if ((rtime%STAMPS)==0) {
PRINTA("%us ",rtime);
}
#endif
rtime+=1;
#if PINGS
if ((rtime%PINGS)==0) {
PRINTF("**Ping\n");
raven_ping6();
}
extern void raven_ping6(void);
if ((rtime%PINGS)==1) {
PRINTA("**Ping\n");
raven_ping6();
}
#endif
#if ROUTES
if ((rtime%ROUTES)==2) {
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j;
PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
PRINTA("\n");
}
}
PRINTA("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
PRINTA("\n");
j=0;
}
}
if (j) PRINTA(" <none>");
PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
PRINTA("/%u (via ", uip_ds6_routing_table[i].length);
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
PRINTA(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
// } else {
// PRINTA(")\n");
// }
j=0;
}
}
if (j) PRINTA(" <none>");
PRINTA("\n---------\n");
}
#endif
#if STACKMONITOR
if ((rtime%STACKMONITOR)==3) {
extern uint16_t __bss_end;
uint16_t p=(uint16_t)&__bss_end;
do {
if (*(uint16_t *)p != 0x4242) {
PRINTA("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
break;
}
p+=10;
} while (p<RAMEND-10);
}
#endif
}
#endif /* TESTRTIMER */
//Use with RF230BB DEBUGFLOW to show path through driver
#if RF230BB&&0
extern uint8_t debugflowsize,debugflow[];
if (debugflowsize) {
debugflow[debugflowsize]=0;
printf("%s",debugflow);
PRINTA("%s",debugflow);
debugflowsize=0;
}
#endif
#if RF230BB&&0
if (rf230processflag) {
printf("rf230p%d",rf230processflag);
PRINTA("rf230p%d",rf230processflag);
rf230processflag=0;
}
#endif
@ -478,11 +561,11 @@ extern uint8_t debugflowsize,debugflow[];
#if RF230BB&&0
if (rf230_interrupt_flag) {
// if (rf230_interrupt_flag!=11) {
PRINTSHORT("**RI%u",rf230_interrupt_flag);
PRINTA("**RI%u",rf230_interrupt_flag);
// }
rf230_interrupt_flag=0;
}
#endif
}
return 0;
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2010, University of Colombo School of Computing
* 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
* Machine dependent AVR SLIP routines for UART0.
* \author
* Kasun Hewage <kasun.ch@gmail.com>
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/rs232.h"
#include "slip.h"
/*---------------------------------------------------------------------------*/
static int
slip_putchar(char c, FILE *stream)
{
#define SLIP_END 0300
static char debug_frame = 0;
if (!debug_frame) { /* Start of debug output */
slip_arch_writeb(SLIP_END);
slip_arch_writeb('\r'); /* Type debug line == '\r' */
debug_frame = 1;
}
slip_arch_writeb((unsigned char)c);
/*
* Line buffered output, a newline marks the end of debug output and
* implicitly flushes debug output.
*/
if (c == '\n') {
slip_arch_writeb(SLIP_END);
debug_frame = 0;
}
return c;
}
/*---------------------------------------------------------------------------*/
static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL,
_FDEV_SETUP_WRITE);
/*---------------------------------------------------------------------------*/
void
slip_arch_init(unsigned long ubr)
{
rs232_set_input(RS232_PORT_0, slip_input_byte);
stdout = &slip_stdout;
}
/*---------------------------------------------------------------------------*/
/*
XXX:
Currently, the following function is in cpu/avr/dev/rs232.c file. this
should be moved to here from there hence this is a platform specific slip
related function.
void
slip_arch_writeb(unsigned char c)
{
rs232_send(RS232_PORT_0, c);
}
*/

View file

@ -4,7 +4,9 @@ CONTIKI_CORE=contiki-raven-main
CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o
CONTIKI_TARGET_SOURCEFILES += contiki-raven-main.c contiki-raven-default-init-net.c
#The avr cpu makefile will also add these files if COFFEE_FILES is specified.
CONTIKI_TARGET_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c
#CONTIKI_TARGET_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c
#Needed for slip
CONTIKI_TARGET_SOURCEFILES += button-sensor.c sensors.c slip_uart0.c slip.c
CONTIKIAVR=$(CONTIKI)/cpu/avr
CONTIKIBOARD=.

View file

@ -0,0 +1,45 @@
/* Dummy sensor routine */
#include "lib/sensors.h"
#include "dev/button-sensor.h"
const struct sensors_sensor button_sensor;
static int status(int type);
struct sensors_sensor *sensors[1];
unsigned char sensors_flags[1];
static int
value(int type)
{
return 0;
}
static int
configure(int type, int c)
{
switch (type) {
case SENSORS_ACTIVE:
if (c) {
if(!status(SENSORS_ACTIVE)) {
}
} else {
}
return 1;
}
return 0;
}
static int
status(int type)
{
switch (type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return 1;
}
return 0;
}
SENSORS_SENSOR(button_sensor, BUTTON_SENSOR,
value, configure, status);

View file

@ -130,7 +130,7 @@ extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via mak
extern uint8_t server_name[16];
extern uint8_t domain_name[30];
#else
uint8_t mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
#endif

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2010, University of Colombo School of Computing
* 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
* Machine dependent AVR SLIP routines for UART0.
* \author
* Kasun Hewage <kasun.ch@gmail.com>
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/rs232.h"
#include "slip.h"
/*---------------------------------------------------------------------------*/
static int
slip_putchar(char c, FILE *stream)
{
#define SLIP_END 0300
static char debug_frame = 0;
if (!debug_frame) { /* Start of debug output */
slip_arch_writeb(SLIP_END);
slip_arch_writeb('\r'); /* Type debug line == '\r' */
debug_frame = 1;
}
slip_arch_writeb((unsigned char)c);
/*
* Line buffered output, a newline marks the end of debug output and
* implicitly flushes debug output.
*/
if (c == '\n') {
slip_arch_writeb(SLIP_END);
debug_frame = 0;
}
return c;
}
/*---------------------------------------------------------------------------*/
static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL,
_FDEV_SETUP_WRITE);
/*---------------------------------------------------------------------------*/
void
slip_arch_init(unsigned long ubr)
{
rs232_set_input(RS232_PORT_0, slip_input_byte);
stdout = &slip_stdout;
}
/*---------------------------------------------------------------------------*/
/*
XXX:
Currently, the following function is in cpu/avr/dev/rs232.c file. this
should be moved to here from there hence this is a platform specific slip
related function.
void
slip_arch_writeb(unsigned char c)
{
rs232_send(RS232_PORT_0, c);
}
*/

View file

@ -230,11 +230,11 @@ void iab_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint16_t iab, uint32_t ext) {
/* IAB */
eui64->u8[3] = (iab >> 4) & 0xff;
eui64->u8[4] = (iab & 0xf) << 4;
eui64->u8[4] = (iab << 4) & 0xf0;
/* EXT */
eui64->u8[4] = (ext >> 24) & 0xff;
eui64->u8[4] |= (ext >> 24) & 0xf;
eui64->u8[5] = (ext >> 16) & 0xff;
eui64->u8[6] = (ext >> 8) & 0xff;
eui64->u8[7] = ext & 0xff;

View file

@ -7,14 +7,26 @@
/* Started plugins are available from the GUI object */
while (true) {
TIMEOUT(60000);
counter=0;
plugins=0;
timeout_function = function my_fun() {
log.log("Script timed out.\n");
log.log(plugins + " plugins were referenced\n");
}
while (counter<10) {
counter++;
GENERATE_MSG(1000, "wait");
YIELD_THEN_WAIT_UNTIL(msg.equals("wait"));
/* Toggle Log Listener filter */
plugin = mote.getSimulation().getGUI().getStartedPlugin("se.sics.cooja.plugins.LogListener");
if (plugin != null) {
plugins++;
log.log("LogListener: Setting filter: " + plugin.getFilter() + "\n");
if (plugin.getFilter() == null || !plugin.getFilter().equals("Contiki")) {
plugin.setFilter("Contiki");
@ -29,6 +41,7 @@ while (true) {
/* Extract Timeline statistics */
plugin = mote.getSimulation().getGUI().getStartedPlugin("se.sics.cooja.plugins.TimeLine");
if (plugin != null) {
plugins++;
stats = plugin.extractStatistics();
if (stats.length() > 40) {
/* Stripping */
@ -43,6 +56,7 @@ while (true) {
/* Select time in Radio Logger */
plugin = mote.getSimulation().getGUI().getStartedPlugin("se.sics.cooja.plugins.RadioLogger");
if (plugin != null) {
plugins++;
log.log("RadioLogger: Showing logged radio packet at mid simulation\n");
plugin.trySelectTime(time/2);
}

View file

@ -1882,19 +1882,30 @@ public class GUI extends Observable {
}
/**
* Returns started plugin with given class name, if any.
* Returns started plugin that ends with given class name, if any.
*
* @param classname Class name
* @return Plugin instance
*/
public Plugin getStartedPlugin(String classname) {
public Plugin getPlugin(String classname) {
for (Plugin p: startedPlugins) {
if (p.getClass().getName().equals(classname)) {
if (p.getClass().getName().endsWith(classname)) {
return p;
}
}
return null;
}
/**
* Returns started plugin with given class name, if any.
*
* @param classname Class name
* @return Plugin instance
* @deprecated
*/
public Plugin getStartedPlugin(String classname) {
return getPlugin(classname);
}
public Plugin[] getStartedPlugins() {
return startedPlugins.toArray(new Plugin[0]);

View file

@ -434,6 +434,8 @@ public class LogScriptEngine {
Hashtable<Object, Object> hash = new Hashtable<Object, Object>();
engine.put("global", hash);
engine.put("sim", simulation);
engine.put("gui", simulation.getGUI());
scriptMote = new ScriptMote();
engine.put("node", scriptMote);