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

Makefile.z1 is broken into .common and .z1 to share it with Z1 Starter Platform

Conflicts:
	.gitignore
	platform/z1/Makefile.z1
This commit is contained in:
Enric M. Calvo 2011-03-25 17:46:38 +01:00
commit 1716d837fc
241 changed files with 6193 additions and 3413 deletions

25
.gitignore vendored
View File

@ -1,16 +1,13 @@
*~
*.swp
.a
*.bin
*.map
*.png
*.log
*.elf
*.ihex
obj_*
*.z1
!Makefile.z1
*.sky
*.map
*.a
*pyc
*.pyc
symbols.c
symbols.h
*_del*
tools/
*.class
symbols.*
Makefile.target
doc/html
patches-*
tools/tunslip6

View File

@ -36,9 +36,6 @@ savedefines:
@echo >Makefile.$(TARGET).defines "DEFINES = $(DEFINES)"
OBJECTDIR = obj_$(TARGET)
ifeq (${wildcard $(OBJECTDIR)},)
DUMMY := ${shell mkdir $(OBJECTDIR)}
endif
LOWERCASE = -abcdefghijklmnopqrstuvwxyz
UPPERCASE = _ABCDEFGHIJKLMNOPQRSTUVWXYZ
@ -109,10 +106,13 @@ endif
target_makefile := $(wildcard $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET))
# Check if the target makefile exists
# Check if the target makefile exists, and create the object directory if necessary.
ifeq ($(strip $(target_makefile)),)
${error The target platform "$(TARGET)" does not exist (maybe it was misspelled?)}
else
ifeq (${wildcard $(OBJECTDIR)},)
DUMMY := ${shell mkdir $(OBJECTDIR)}
endif
include $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET)
endif

0
apps/rest-coap/Makefile.rest-coap Executable file → Normal file
View File

0
apps/rest-common/Makefile.rest-common Executable file → Normal file
View File

0
apps/rest-common/rest.c Executable file → Normal file
View File

0
apps/rest-common/rest.h Executable file → Normal file
View File

0
apps/rest-http/Makefile.rest-http Executable file → Normal file
View File

0
apps/rest-http/http-common.c Executable file → Normal file
View File

0
apps/rest-http/http-common.h Executable file → Normal file
View File

0
apps/rest-http/http-server.c Executable file → Normal file
View File

0
apps/rest-http/http-server.h Executable file → Normal file
View File

View File

@ -146,7 +146,7 @@ print_remote_stats(struct stats *s)
{
unsigned long total_time;
printf("%d 1 %d %d %d %u %lu %lu %lu %lu %lu %lu # for automatic processing\n",
printf("%d 1 %d %d %d %lu %lu %lu %lu %lu %lu %lu # for automatic processing\n",
current_type,
s->sent, s->received, s->timedout,
s->end - s->start,
@ -173,7 +173,7 @@ print_local_stats(struct stats *s)
{
unsigned long total_time;
printf("%d 0 %d %d %d %u %lu %lu %lu %lu %lu %lu # for automatic processing\n",
printf("%d 0 %d %d %d %lu %lu %lu %lu %lu %lu %lu # for automatic processing\n",
current_type,
s->sent, s->received, s->timedout,
s->end - s->start,
@ -185,12 +185,12 @@ print_local_stats(struct stats *s)
printf("Local node statistics:\n");
printf(" Total transfer time: %d.%d seconds, %d.%02d packets/second\n",
printf(" Total transfer time: %lu.%02lu seconds, %lu.%02lu packets/second\n",
(s->end - s->start) / CLOCK_SECOND,
((10 * (s->end - s->start)) / CLOCK_SECOND) % 10,
CLOCK_SECOND * s->sent / (s->end - s->start),
(100 * CLOCK_SECOND * s->sent / (s->end - s->start)) % 100);
((1UL * CLOCK_SECOND * s->sent) / (s->end - s->start)),
(((100UL * CLOCK_SECOND * s->sent) / (s->end - s->start)) % 100));
printf(" Average round-trip-time: %lu ms (%lu + %lu)\n",
(1000 * (s->total_rx_latency + s->total_tx_latency) / s->received) /
RTIMER_ARCH_SECOND,

View File

@ -174,6 +174,17 @@ typedef struct unit_test {
} \
} while(0)
/**
* Obtain the result of a certain unit test.
*
* If the unit test has not yet been executed, this macro returns
* unit_test_failed. Otherwise it returns the result of the last
* execution of the unit test.
*
* \param name The name of the unit test.
*/
#define UNIT_TEST_RESULT(name) (unit_test_##name.result)
/* The default print function. */
void unit_test_print_report(const unit_test_t *utp);

0
core/cfs/cfs-coffee.c Executable file → Normal file
View File

View File

@ -50,7 +50,6 @@
#include <string.h>
#include <signal.h>
#include <io.h>
#include "contiki.h"

View File

@ -121,7 +121,3 @@ leds_invert(unsigned char ledv) {
show_leds(ledv);
}
/*---------------------------------------------------------------------------*/
void leds_green(int o) { o?leds_on(LEDS_GREEN):leds_off(LEDS_GREEN); }
void leds_yellow(int o) { o?leds_on(LEDS_YELLOW):leds_off(LEDS_YELLOW); }
void leds_red(int o) { o?leds_on(LEDS_RED):leds_off(LEDS_RED); }
/*---------------------------------------------------------------------------*/

View File

@ -55,11 +55,18 @@ void leds_init(void);
*/
void leds_blink(void);
#ifndef LEDS_GREEN
#define LEDS_GREEN 1
#define LEDS_YELLOW 2
#define LEDS_RED 4
#define LEDS_BLUE LEDS_YELLOW /* Tmote Sky is colorblind? */
#define leds_blue leds_yellow
#endif /* LEDS_GREEN */
#ifndef LEDS_YELLOW
#define LEDS_YELLOW 2
#endif /* LEDS_YELLOW */
#ifndef LEDS_RED
#define LEDS_RED 4
#endif /* LEDS_RED */
#ifndef LEDS_BLUE
#define LEDS_BLUE LEDS_YELLOW
#endif /* LEDS_BLUE */
#ifdef LEDS_CONF_ALL
#define LEDS_ALL LEDS_CONF_ALL
@ -76,18 +83,6 @@ void leds_off(unsigned char leds);
void leds_toggle(unsigned char leds);
void leds_invert(unsigned char leds);
void leds_green(int onoroff);
void leds_red(int onoroff);
void leds_yellow(int onoroff);
#define LEDS_ON 1
#define LEDS_OFF 0
/**
* Leds implementation
*/

View File

@ -46,41 +46,40 @@
#define ETX_LIMIT 15
#define ETX_SCALE 100
#define ETX_ALPHA 90
#define ETX_FIRST_GUESS 5
#define NOACK_PACKET_ETX 8
#define ETX_NOACK_PENALTY ETX_LIMIT
/*---------------------------------------------------------------------------*/
NEIGHBOR_ATTRIBUTE(uint8_t, etx, NULL);
NEIGHBOR_ATTRIBUTE(link_metric_t, etx, NULL);
static neighbor_info_subscriber_t subscriber_callback;
/*---------------------------------------------------------------------------*/
static void
update_etx(const rimeaddr_t *dest, int packet_etx)
update_metric(const rimeaddr_t *dest, int packet_metric)
{
uint8_t *etxp;
uint8_t recorded_etx, new_etx;
link_metric_t *metricp;
link_metric_t recorded_metric, new_metric;
etxp = (uint8_t *)neighbor_attr_get_data(&etx, dest);
if(etxp == NULL || *etxp == 0) {
recorded_etx = NEIGHBOR_INFO_ETX2FIX(ETX_FIRST_GUESS);
metricp = (link_metric_t *)neighbor_attr_get_data(&etx, dest);
packet_metric = NEIGHBOR_INFO_ETX2FIX(packet_metric);
if(metricp == NULL || *metricp == 0) {
recorded_metric = NEIGHBOR_INFO_ETX2FIX(ETX_LIMIT);
new_metric = packet_metric;
} else {
recorded_etx = *etxp;
recorded_metric = *metricp;
/* Update the EWMA of the ETX for the neighbor. */
new_metric = ((uint16_t)recorded_metric * ETX_ALPHA +
(uint16_t)packet_metric * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
}
/* Update the EWMA of the ETX for the neighbor. */
packet_etx = NEIGHBOR_INFO_ETX2FIX(packet_etx);
new_etx = ((uint16_t)recorded_etx * ETX_ALPHA +
(uint16_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
PRINTF("neighbor-info: ETX changed from %d to %d (packet ETX = %d) %d\n",
NEIGHBOR_INFO_FIX2ETX(recorded_etx),
NEIGHBOR_INFO_FIX2ETX(new_etx),
NEIGHBOR_INFO_FIX2ETX(packet_etx),
NEIGHBOR_INFO_FIX2ETX(recorded_metric),
NEIGHBOR_INFO_FIX2ETX(new_metric),
NEIGHBOR_INFO_FIX2ETX(packet_metric),
dest->u8[7]);
if(neighbor_attr_has_neighbor(dest)) {
neighbor_attr_set_data(&etx, dest, &new_etx);
if(new_etx != recorded_etx && subscriber_callback != NULL) {
subscriber_callback(dest, 1, new_etx);
neighbor_attr_set_data(&etx, dest, &new_metric);
if(new_metric != recorded_metric && subscriber_callback != NULL) {
subscriber_callback(dest, 1, new_metric);
}
}
}
@ -96,9 +95,6 @@ add_neighbor(const rimeaddr_t *addr)
PRINTF("neighbor-info: The neighbor is already known\n");
break;
default:
if(subscriber_callback != NULL) {
subscriber_callback(addr, 1, NEIGHBOR_INFO_ETX2FIX(ETX_FIRST_GUESS));
}
break;
}
}
@ -107,7 +103,7 @@ void
neighbor_info_packet_sent(int status, int numtx)
{
const rimeaddr_t *dest;
uint8_t packet_etx;
link_metric_t packet_metric;
dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
if(rimeaddr_cmp(dest, &rimeaddr_null)) {
@ -120,25 +116,22 @@ neighbor_info_packet_sent(int status, int numtx)
switch(status) {
case MAC_TX_OK:
packet_etx = numtx;
packet_metric = numtx;
add_neighbor(dest);
break;
case MAC_TX_COLLISION:
packet_etx = numtx;
packet_metric = numtx;
break;
case MAC_TX_NOACK:
packet_etx = NOACK_PACKET_ETX;
/* error and collissions will not cause high hits ??? */
packet_metric = ETX_NOACK_PENALTY;
break;
case MAC_TX_ERR:
default:
packet_etx = 0;
break;
/* Do not penalize the ETX when collisions or transmission
errors occur. */
return;
}
if(packet_etx > 0) {
update_etx(dest, packet_etx);
}
update_metric(dest, packet_metric);
}
/*---------------------------------------------------------------------------*/
void
@ -169,12 +162,12 @@ neighbor_info_subscribe(neighbor_info_subscriber_t s)
return 0;
}
/*---------------------------------------------------------------------------*/
uint8_t
neighbor_info_get_etx(const rimeaddr_t *addr)
link_metric_t
neighbor_info_get_metric(const rimeaddr_t *addr)
{
uint8_t *etxp;
link_metric_t *metricp;
etxp = (uint8_t *)neighbor_attr_get_data(&etx, addr);
return etxp == NULL ? 0 : *etxp;
metricp = (link_metric_t *)neighbor_attr_get_data(&etx, addr);
return metricp == NULL ? ETX_LIMIT : *metricp;
}
/*---------------------------------------------------------------------------*/

View File

@ -52,6 +52,7 @@
#define NEIGHBOR_INFO_FIX2ETX(fix) ((fix) / NEIGHBOR_INFO_ETX_DIVISOR)
typedef void (*neighbor_info_subscriber_t)(const rimeaddr_t *, int known, int etx);
typedef uint8_t link_metric_t;
/**
* Notify the neighbor information module about the status of
@ -85,6 +86,6 @@ int neighbor_info_subscribe(neighbor_info_subscriber_t);
*
* \return Returns ETX if the neighbor exists, and 0 if not.
*/
uint8_t neighbor_info_get_etx(const rimeaddr_t *addr);
link_metric_t neighbor_info_get_etx(const rimeaddr_t *addr);
#endif /* NEIGHBOR_INFO_H */

View File

@ -286,31 +286,34 @@ PT_THREAD(psock_readto(CC_REGISTER_ARG struct psock *psock, unsigned char c))
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_readbuf(CC_REGISTER_ARG struct psock *psock))
PT_THREAD(psock_readbuf_len(CC_REGISTER_ARG struct psock *psock, uint16_t len))
{
PT_BEGIN(&psock->psockpt);
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
/* XXX: Should add buf_checkmarker() before do{} loop, if
incoming data has been handled while waiting for a write. */
if(psock->readlen == 0) {
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
psock->state = STATE_READ;
psock->readptr = (u8_t *)uip_appdata;
psock->readlen = uip_datalen();
}
buf_bufdata(&psock->buf, psock->bufsize,
&psock->readptr,
&psock->readlen);
/* read len bytes or to end of data */
do {
if(psock->readlen == 0) {
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
psock->state = STATE_READ;
psock->readptr = (u8_t *)uip_appdata;
psock->readlen = uip_datalen();
}
} while(buf_bufdata(&psock->buf, psock->bufsize,
&psock->readptr, &psock->readlen) == BUF_NOT_FULL &&
psock_datalen(psock) < len);
if(psock_datalen(psock) == 0) {
psock->state = STATE_NONE;
PT_RESTART(&psock->psockpt);
}
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
void
psock_init(CC_REGISTER_ARG struct psock *psock,

View File

@ -241,7 +241,7 @@ PT_THREAD(psock_generator_send(struct psock *psock,
*/
#define PSOCK_CLOSE(psock) uip_close()
PT_THREAD(psock_readbuf(struct psock *psock));
PT_THREAD(psock_readbuf_len(struct psock *psock, uint16_t len));
/**
* Read data until the buffer is full.
*
@ -255,7 +255,24 @@ PT_THREAD(psock_readbuf(struct psock *psock));
* \hideinitializer
*/
#define PSOCK_READBUF(psock) \
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, 1))
/**
* Read data until at least len bytes have been read.
*
* This macro will block waiting for data and read the data into the
* input buffer specified with the call to PSOCK_INIT(). Data is read
* until the buffer is full or len bytes have been read.
*
* \param psock (struct psock *) A pointer to the protosocket from which
* data should be read.
* \param len (uint16_t) The minimum number of bytes to read.
*
* \hideinitializer
*/
#define PSOCK_READBUF_LEN(psock, len) \
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, len))
PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
/**

View File

@ -94,8 +94,6 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF};
#define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS
#endif /* !RPL_CONF_DIO_INTERVAL_DOUBLINGS */
#define INITIAL_ETX NEIGHBOR_INFO_ETX_DIVISOR * 5
/************************************************************************/
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */
MEMB(parent_memb, struct rpl_parent, RPL_MAX_PARENTS);
@ -309,7 +307,7 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
memcpy(&p->addr, addr, sizeof(p->addr));
p->dag = dag;
p->rank = dio->rank;
p->etx = INITIAL_ETX;
p->link_metric = INITIAL_LINK_METRIC;
p->dtsn = 0;
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
@ -358,6 +356,7 @@ rpl_select_parent(rpl_dag_t *dag)
rpl_reset_dio_timer(dag, 1);
PRINTF("RPL: New preferred parent, rank changed from %u to %u\n",
(unsigned)dag->rank, dag->of->calculate_rank(best, 0));
RPL_STAT(rpl_stats.parent_switch++);
}
/* Update the DAG rank, since link-layer information may have changed
@ -458,8 +457,6 @@ join_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
}
PRINTF("succeeded\n");
p->etx = INITIAL_ETX; /* The lowest confidence for new parents. */
/* Determine the objective function by using the
objective code point of the DIO. */
of = rpl_find_of(dio->ocp);
@ -732,7 +729,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
PRINTF(")\n");
return;
}
PRINTF("RPL: New candidate parent with rank %u: ", (unsigned)p->rank);
PRINT6ADDR(from);
PRINTF("\n");
@ -742,7 +739,8 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
}
/* We have allocated a candidate parent; process the DIO further. */
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
p->rank = dio->rank;
if(rpl_process_parent_event(dag, p) == 0) {
/* The candidate parent no longer exists. */

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);
@ -459,6 +467,8 @@ dao_input(void)
uint8_t prefixlen;
uint8_t flags;
uint8_t subopt_type;
uint8_t pathcontrol;
uint8_t pathsequence;
uip_ipaddr_t prefix;
uip_ds6_route_t *rep;
uint8_t buffer_length;
@ -523,7 +533,9 @@ dao_input(void)
break;
case RPL_DIO_SUBOPT_TRANSIT:
/* path sequence and control ignored */
lifetime = get32(buffer, i + 4);
pathcontrol = buffer[i + 3];
pathsequence = buffer[i + 4];
lifetime = buffer[i + 5];
/* parent address also ignored */
break;
}
@ -567,11 +579,11 @@ dao_input(void)
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
if(rep == NULL) {
RPL_STAT(rpl_stats.memory_overflows++);
RPL_STAT(rpl_stats.mem_overflows++);
PRINTF("RPL: Could not add a route after receiving a DAO\n");
return;
} else {
rep->state.lifetime = lifetime;
rep->state.lifetime = lifetime * dag->lifetime_unit;
rep->state.learned_from = learned_from;
}
@ -637,13 +649,13 @@ dao_output(rpl_parent_t *n, uint32_t lifetime)
memcpy(buffer + pos, &prefix, (prefixlen + 7) / CHAR_BIT);
pos += ((prefixlen + 7) / CHAR_BIT);
/* create a transit information subopt */
/* create a transit information subopt (RPL-18)*/
buffer[pos++] = RPL_DIO_SUBOPT_TRANSIT;
buffer[pos++] = 6;
buffer[pos++] = 0; /* path seq - ignored */
buffer[pos++] = 4;
buffer[pos++] = 0; /* flags - ignored */
buffer[pos++] = 0; /* path control - ignored */
set32(buffer, pos, lifetime);
pos += 4;
buffer[pos++] = 0; /* path seq - ignored */
buffer[pos++] = (lifetime / dag->lifetime_unit) & 0xff;
if(n == NULL) {
uip_create_linklocal_rplnodes_mcast(&addr);

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_ETX_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. */
@ -75,22 +75,21 @@ rpl_of_t rpl_of_etx = {
/* Reject parents that have a higher path cost than the following. */
#define MAX_PATH_COST 100
/* An initial guess of the link metric. */
#define INITIAL_LINK_METRIC 3
/*
* The rank must differ more than 1/PARENT_SWITCH_THRESHOLD_DIV in order
* to switch preferred parent.
*/
#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);
if(p->mc.obj.etx == 0 && p->rank > ROOT_RANK(p->dag)) {
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
}
return p->mc.obj.etx + NI_ETX_TO_RPL_ETX(p->link_metric);
}
static void
@ -113,12 +112,9 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
if(base_rank == 0) {
return INFINITE_RANK;
}
rank_increase = INITIAL_LINK_METRIC * DEFAULT_MIN_HOPRANKINC;
rank_increase = NEIGHBOR_INFO_FIX2ETX(INITIAL_LINK_METRIC) * DEFAULT_MIN_HOPRANKINC;
} else {
if(p->etx == 0) {
p->etx = INITIAL_LINK_METRIC * NEIGHBOR_INFO_ETX_DIVISOR;
}
rank_increase = (p->etx * p->dag->min_hoprankinc) / NEIGHBOR_INFO_ETX_DIVISOR;
rank_increase = NEIGHBOR_INFO_FIX2ETX(p->link_metric) * p->dag->min_hoprankinc;
if(base_rank == 0) {
base_rank = p->rank;
}
@ -140,46 +136,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_etx < p2_etx + min_diff &&
p1_etx > p2_etx - min_diff) {
PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
p2_etx - min_diff,
p1_etx,
p2_etx + min_diff);
return dag->preferred_parent;
if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
if(p1_metric < p2_metric + min_diff &&
p1_metric > p2_metric - min_diff) {
PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
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);
}
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);
#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 */
}

View File

@ -127,6 +127,8 @@
#define INFINITE_RANK 0xffff
#define INITIAL_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(5)
/* Represents 2^n ms. */
/* Default value according to the specification is 3 which
means 8 milliseconds, but that is an unreasonable value if
@ -218,6 +220,7 @@ struct rpl_stats {
uint16_t global_repairs;
uint16_t malformed_msgs;
uint16_t resets;
uint16_t parent_switch;
};
typedef struct rpl_stats rpl_stats_t;

View File

@ -112,7 +112,7 @@ new_dio_interval(rpl_dag_t *dag)
dag->version,
dag->dio_totint, dag->dio_totsend,
dag->dio_totrecv,dag->dio_intcurrent,
dag->rank == ROOT_RANK ? "BLUE" : "ORANGE");
dag->rank == ROOT_RANK(dag) ? "BLUE" : "ORANGE");
#endif /* RPL_CONF_STATS */
/* reset the redundancy counter */
@ -205,7 +205,8 @@ handle_dao_timer(void *ptr)
fan-out as being under investigation. */
if(dag->preferred_parent != NULL) {
PRINTF("RPL: handle_dao_timer - sending DAO\n");
dao_output(dag->preferred_parent, DEFAULT_ROUTE_LIFETIME);
/* set time to maxtime */
dao_output(dag->preferred_parent, dag->lifetime_unit * 0xffUL);
} else {
PRINTF("RPL: Could not find a parent to send a DAO to \n");
}

View File

@ -148,11 +148,10 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
return;
}
if(etx != parent->etx) {
/* Trigger DAG rank recalculation. */
parent->updated = 1;
}
parent->etx = etx;
/* Trigger DAG rank recalculation. */
parent->updated = 1;
parent->link_metric = etx;
if(dag->of->parent_state_callback != NULL) {
dag->of->parent_state_callback(parent, known, etx);
@ -163,7 +162,6 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
PRINT6ADDR(&parent->addr);
PRINTF(" because of bad connectivity (ETX %d)\n", etx);
parent->rank = INFINITE_RANK;
parent->updated = 1;
}
}
/************************************************************************/

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;
/*---------------------------------------------------------------------------*/
@ -125,7 +147,7 @@ struct rpl_parent {
rpl_metric_container_t mc;
uip_ipaddr_t addr;
rpl_rank_t rank;
uint8_t etx;
uint8_t link_metric;
uint8_t dtsn;
uint8_t updated;
};

View File

@ -268,7 +268,7 @@ static uint8_t *hc06_ptr;
/* Uncompression of linklocal */
/* 0 -> 16 bytes from packet */
/* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet */
/* 2 -> 2 bytes from prefix - zeroes + 2 from packet */
/* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet */
/* 3 -> 2 bytes from prefix - infer 8 bytes from lladdr */
/* NOTE: => the uncompress function does change 0xf to 0x10 */
/* NOTE: 0x00 => no-autoconfig => unspecified */
@ -277,7 +277,7 @@ const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
/* Uncompression of ctx-based */
/* 0 -> 0 bits from packet [unspecified / reserved] */
/* 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet */
/* 2 -> 8 bytes from prefix - zeroes + 2 from packet */
/* 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX + 2 from packet */
/* 3 -> 8 bytes from prefix - infer 8 bytes from lladdr */
const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
@ -338,7 +338,7 @@ compress_addr_64(uint8_t bitpos, uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
if(uip_is_addr_mac_addr_based(ipaddr, lladdr)) {
return 3 << bitpos; /* 0-bits */
} else if(sicslowpan_is_iid_16_bit_compressable(ipaddr)) {
/* compress IID to 16 bits xxxx::XXXX */
/* compress IID to 16 bits xxxx::0000:00ff:fe00:XXXX */
memcpy(hc06_ptr, &ipaddr->u16[7], 2);
hc06_ptr += 2;
return 2 << bitpos; /* 16-bits */
@ -377,6 +377,11 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
}
if(postcount > 0) {
memcpy(&ipaddr->u8[16 - postcount], hc06_ptr, postcount);
if(postcount == 2 && prefcount < 11) {
/* 16 bits uncompression => 0000:00ff:fe00:XXXX */
ipaddr->u8[11] = 0xff;
ipaddr->u8[12] = 0xfe;
}
hc06_ptr += postcount;
} else if (prefcount > 0) {
/* no IID based configuration if no prefix and no data => unspec */

View File

@ -233,13 +233,15 @@ struct sicslowpan_addr_context {
* \brief check whether we can compress the IID in
* address 'a' to 16 bits.
* This is used for unicast addresses only, and is true
* if first 49 bits of IID are 0
* if the address is on the format <PREFIX>::0000:00ff:fe00:XXXX
* NOTE: we currently assume 64-bits prefixes
*/
#define sicslowpan_is_iid_16_bit_compressable(a) \
((((a)->u16[4]) == 0) && \
(((a)->u16[5]) == 0) && \
(((a)->u16[6]) == 0) && \
((((a)->u8[14]) & 0x80) == 0))
(((a)->u8[10]) == 0)&& \
(((a)->u8[11]) == 0xff)&& \
(((a)->u8[12]) == 0xfe)&& \
(((a)->u8[13]) == 0))
/**
* \brief check whether the 9-bit group-id of the

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,16 +53,30 @@ void uip_debug_lladdr_print(const uip_lladdr_t *addr);
#define DEBUG_ANNOTATE 2
#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT
/* 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
#include <stdio.h>
#ifdef __AVR__
#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define ANNOTATE(...) printf(__VA_ARGS__)
#endif
#else
#define ANNOTATE(...)
#endif /* (DEBUG) & DEBUG_ANNOTATE */
#if (DEBUG) & DEBUG_PRINT
#include <stdio.h>
#ifdef __AVR__
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTF(...) printf(__VA_ARGS__)
#endif
#define PRINT6ADDR(addr) uip_debug_ipaddr_print(addr)
#define PRINTLLADDR(lladdr) uip_debug_lladdr_print(lladdr)
#else

203
core/net/uip-ds6.c Executable file → Normal file
View File

@ -174,60 +174,60 @@ uip_ds6_periodic(void)
#if !UIP_CONF_ROUTER
/* Periodic processing on prefixes */
for(locprefix = uip_ds6_prefix_list;
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
if((locprefix->isused) && (!locprefix->isinfinite)
&& (stimer_expired(&(locprefix->vlifetime)))) {
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB;
locprefix++) {
if(locprefix->isused && !locprefix->isinfinite
&& stimer_expired(&(locprefix->vlifetime))) {
uip_ds6_prefix_rm(locprefix);
}
}
#endif /* !UIP_CONF_ROUTER */
/* Periodic processing on neighbors */
for(locnbr = uip_ds6_nbr_cache; locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB;
for(locnbr = uip_ds6_nbr_cache;
locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB;
locnbr++) {
if(locnbr->isused) {
switch (locnbr->state) {
switch(locnbr->state) {
case NBR_INCOMPLETE:
if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
uip_ds6_nbr_rm(locnbr);
} else if(stimer_expired(&(locnbr->sendns))) {
} else if(stimer_expired(&locnbr->sendns)) {
locnbr->nscount++;
PRINTF("NBR_INCOMPLETE: NS %u\n", locnbr->nscount);
uip_nd6_ns_output(NULL, NULL, &locnbr->ipaddr);
stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000);
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
case NBR_REACHABLE:
if(stimer_expired(&(locnbr->reachable))) {
if(stimer_expired(&locnbr->reachable)) {
PRINTF("REACHABLE: moving to STALE (");
PRINT6ADDR(&locnbr->ipaddr);
PRINTF(")\n");
locnbr->state = NBR_STALE;
/* NEIGHBOR_STATE_CHANGED(locnbr); */
}
break;
case NBR_DELAY:
if(stimer_expired(&(locnbr->reachable))) {
if(stimer_expired(&locnbr->reachable)) {
locnbr->state = NBR_PROBE;
locnbr->nscount = 1;
/* NEIGHBOR_STATE_CHANGED(locnbr); */
PRINTF("DELAY: moving to PROBE + NS %u\n", locnbr->nscount);
uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr);
stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000);
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
case NBR_PROBE:
if(locnbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
PRINTF("PROBE END \n");
PRINTF("PROBE END\n");
if((locdefrt = uip_ds6_defrt_lookup(&locnbr->ipaddr)) != NULL) {
uip_ds6_defrt_rm(locdefrt);
}
uip_ds6_nbr_rm(locnbr);
} else if(stimer_expired(&(locnbr->sendns))) {
} else if(stimer_expired(&locnbr->sendns)) {
locnbr->nscount++;
PRINTF("PROBE: NS %u\n", locnbr->nscount);
uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr);
stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000);
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
default:
@ -248,9 +248,9 @@ uip_ds6_periodic(void)
/*---------------------------------------------------------------------------*/
uint8_t
uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size,
uint16_t elementsize, uip_ipaddr_t * ipaddr,
uint8_t ipaddrlen, uip_ds6_element_t ** out_element)
uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
uint16_t elementsize, uip_ipaddr_t *ipaddr,
uint8_t ipaddrlen, uip_ds6_element_t **out_element)
{
uip_ds6_element_t *element;
@ -258,11 +258,10 @@ uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size,
for(element = list;
element <
(uip_ds6_element_t *) ((uint8_t *) list + (size * elementsize));
element = (uip_ds6_element_t *) ((uint8_t *) element + elementsize)) {
// printf("+ %p %d\n", &element->isused, element->isused);
(uip_ds6_element_t *)((uint8_t *)list + (size * elementsize));
element = (uip_ds6_element_t *)((uint8_t *)element + elementsize)) {
if(element->isused) {
if(uip_ipaddr_prefixcmp(&(element->ipaddr), ipaddr, ipaddrlen)) {
if(uip_ipaddr_prefixcmp(&element->ipaddr, ipaddr, ipaddrlen)) {
*out_element = element;
return FOUND;
}
@ -271,33 +270,28 @@ uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size,
}
}
if(*out_element != NULL) {
return FREESPACE;
} else {
return NOSPACE;
}
return *out_element != NULL ? FREESPACE : NOSPACE;
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr,
uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t * lladdr,
uint8_t isrouter, uint8_t state)
{
int r;
r = uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
sizeof(uip_ds6_nbr_t), ipaddr, 128,
(uip_ds6_element_t **) &locnbr);
// printf("r %d\n", r);
(uip_ds6_element_t **)&locnbr);
if(r == FREESPACE) {
locnbr->isused = 1;
uip_ipaddr_copy(&(locnbr->ipaddr), ipaddr);
uip_ipaddr_copy(&locnbr->ipaddr, ipaddr);
if(lladdr != NULL) {
memcpy(&(locnbr->lladdr), lladdr, UIP_LLADDR_LEN);
memcpy(&locnbr->lladdr, lladdr, UIP_LLADDR_LEN);
} else {
memset(&(locnbr->lladdr), 0, UIP_LLADDR_LEN);
memset(&locnbr->lladdr, 0, UIP_LLADDR_LEN);
}
locnbr->isrouter = isrouter;
locnbr->state = state;
@ -305,18 +299,17 @@ uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr,
uip_packetqueue_new(&locnbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
/* timers are set separately, for now we put them in expired state */
stimer_set(&(locnbr->reachable), 0);
stimer_set(&(locnbr->sendns), 0);
stimer_set(&locnbr->reachable, 0);
stimer_set(&locnbr->sendns, 0);
locnbr->nscount = 0;
PRINTF("Adding neighbor with ip addr");
PRINTF("Adding neighbor with ip addr ");
PRINT6ADDR(ipaddr);
PRINTF("link addr");
PRINTF("link addr ");
PRINTLLADDR((&(locnbr->lladdr)));
PRINTF("state %u\n", state);
NEIGHBOR_STATE_CHANGED(locnbr);
locnbr->last_lookup = clock_time();
// printf("add %p\n", locnbr);
return locnbr;
} else if(r == NOSPACE) {
/* We did not find any empty slot on the neighbor list, so we need
@ -338,7 +331,6 @@ uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr,
}
}
if(oldest != NULL) {
// printf("rm3\n");
uip_ds6_nbr_rm(oldest);
return uip_ds6_nbr_add(ipaddr, lladdr, isrouter, state);
}
@ -354,7 +346,6 @@ uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
if(nbr != NULL) {
nbr->isused = 0;
#if UIP_CONF_IPV6_QUEUE_PKT
// printf("rm %p\n", &nbr->isused);
uip_packetqueue_free(&nbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
NEIGHBOR_STATE_CHANGED(nbr);
@ -367,9 +358,9 @@ uip_ds6_nbr_t *
uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
sizeof(uip_ds6_nbr_t), ipaddr, 128,
(uip_ds6_element_t **) & locnbr) == FOUND) {
(uip_ds6_element_t **)&locnbr) == FOUND) {
return locnbr;
}
return NULL;
@ -380,19 +371,19 @@ uip_ds6_defrt_t *
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_defrt_list, UIP_DS6_DEFRT_NB,
((uip_ds6_element_t *)uip_ds6_defrt_list, UIP_DS6_DEFRT_NB,
sizeof(uip_ds6_defrt_t), ipaddr, 128,
(uip_ds6_element_t **) & locdefrt) == FREESPACE) {
(uip_ds6_element_t **)&locdefrt) == FREESPACE) {
locdefrt->isused = 1;
uip_ipaddr_copy(&(locdefrt->ipaddr), ipaddr);
uip_ipaddr_copy(&locdefrt->ipaddr, ipaddr);
if(interval != 0) {
stimer_set(&(locdefrt->lifetime), interval);
stimer_set(&locdefrt->lifetime, interval);
locdefrt->isinfinite = 0;
} else {
locdefrt->isinfinite = 1;
}
PRINTF("Adding defrouter with ip addr");
PRINTF("Adding defrouter with ip addr ");
PRINT6ADDR(&locdefrt->ipaddr);
PRINTF("\n");
@ -405,7 +396,7 @@ uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
/*---------------------------------------------------------------------------*/
void
uip_ds6_defrt_rm(uip_ds6_defrt_t * defrt)
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
{
if(defrt != NULL) {
defrt->isused = 0;
@ -416,11 +407,11 @@ uip_ds6_defrt_rm(uip_ds6_defrt_t * defrt)
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_lookup(uip_ipaddr_t * ipaddr)
uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop((uip_ds6_element_t *) uip_ds6_defrt_list,
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_defrt_list,
UIP_DS6_DEFRT_NB, sizeof(uip_ds6_defrt_t), ipaddr, 128,
(uip_ds6_element_t **) & locdefrt) == FOUND) {
(uip_ds6_element_t **)&locdefrt) == FOUND) {
return locdefrt;
}
return NULL;
@ -440,7 +431,7 @@ uip_ds6_defrt_choose(void)
PRINT6ADDR(&locdefrt->ipaddr);
PRINTF("\n");
bestnbr = uip_ds6_nbr_lookup(&locdefrt->ipaddr);
if((bestnbr != NULL) && (bestnbr->state != NBR_INCOMPLETE)) {
if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) {
PRINTF("Defrt found, IP address ");
PRINT6ADDR(&locdefrt->ipaddr);
PRINTF("\n");
@ -459,16 +450,16 @@ uip_ds6_defrt_choose(void)
#if UIP_CONF_ROUTER
/*---------------------------------------------------------------------------*/
uip_ds6_prefix_t *
uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen,
uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
uint8_t advertise, uint8_t flags, unsigned long vtime,
unsigned long ptime)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
((uip_ds6_element_t *)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen,
(uip_ds6_element_t **) & locprefix) == FREESPACE) {
(uip_ds6_element_t **)&locprefix) == FREESPACE) {
locprefix->isused = 1;
uip_ipaddr_copy(&(locprefix->ipaddr), ipaddr);
uip_ipaddr_copy(&locprefix->ipaddr, ipaddr);
locprefix->length = ipaddrlen;
locprefix->advertise = advertise;
locprefix->l_a_reserved = flags;
@ -488,15 +479,15 @@ uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen,
#else /* UIP_CONF_ROUTER */
uip_ds6_prefix_t *
uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen,
uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
unsigned long interval)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
((uip_ds6_element_t *)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen,
(uip_ds6_element_t **) & locprefix) == FREESPACE) {
(uip_ds6_element_t **)&locprefix) == FREESPACE) {
locprefix->isused = 1;
uip_ipaddr_copy(&(locprefix->ipaddr), ipaddr);
uip_ipaddr_copy(&locprefix->ipaddr, ipaddr);
locprefix->length = ipaddrlen;
if(interval != 0) {
stimer_set(&(locprefix->vlifetime), interval);
@ -523,7 +514,7 @@ uip_ds6_prefix_rm(uip_ds6_prefix_t * prefix)
}
/*---------------------------------------------------------------------------*/
uip_ds6_prefix_t *
uip_ds6_prefix_lookup(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen)
uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen)
{
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_prefix_list,
UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix_t),
@ -536,7 +527,7 @@ uip_ds6_prefix_lookup(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen)
/*---------------------------------------------------------------------------*/
uint8_t
uip_ds6_is_addr_onlink(uip_ipaddr_t * ipaddr)
uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr)
{
for(locprefix = uip_ds6_prefix_list;
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
@ -550,12 +541,12 @@ uip_ds6_is_addr_onlink(uip_ipaddr_t * ipaddr)
/*---------------------------------------------------------------------------*/
uip_ds6_addr_t *
uip_ds6_addr_add(uip_ipaddr_t * ipaddr, unsigned long vlifetime, uint8_t type)
uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
((uip_ds6_element_t *)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
sizeof(uip_ds6_addr_t), ipaddr, 128,
(uip_ds6_element_t **) & locaddr) == FREESPACE) {
(uip_ds6_element_t **)&locaddr) == FREESPACE) {
locaddr->isused = 1;
uip_ipaddr_copy(&locaddr->ipaddr, ipaddr);
locaddr->state = ADDR_TENTATIVE;
@ -579,7 +570,7 @@ uip_ds6_addr_add(uip_ipaddr_t * ipaddr, unsigned long vlifetime, uint8_t type)
/*---------------------------------------------------------------------------*/
void
uip_ds6_addr_rm(uip_ds6_addr_t * addr)
uip_ds6_addr_rm(uip_ds6_addr_t *addr)
{
if(addr != NULL) {
uip_create_solicited_node(&addr->ipaddr, &loc_fipaddr);
@ -593,12 +584,12 @@ uip_ds6_addr_rm(uip_ds6_addr_t * addr)
/*---------------------------------------------------------------------------*/
uip_ds6_addr_t *
uip_ds6_addr_lookup(uip_ipaddr_t * ipaddr)
uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
((uip_ds6_element_t *)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
sizeof(uip_ds6_addr_t), ipaddr, 128,
(uip_ds6_element_t **) & locaddr) == FOUND) {
(uip_ds6_element_t **)&locaddr) == FOUND) {
return locaddr;
}
return NULL;
@ -615,7 +606,7 @@ uip_ds6_get_link_local(int8_t state)
{
for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
if((locaddr->isused) && (state == -1 || locaddr->state == state)
if(locaddr->isused && (state == -1 || locaddr->state == state)
&& (uip_is_addr_link_local(&locaddr->ipaddr))) {
return locaddr;
}
@ -634,7 +625,7 @@ uip_ds6_get_global(int8_t state)
{
for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
if((locaddr->isused) && (state == -1 || locaddr->state == state)
if(locaddr->isused && (state == -1 || locaddr->state == state)
&& !(uip_is_addr_link_local(&locaddr->ipaddr))) {
return locaddr;
}
@ -644,12 +635,12 @@ uip_ds6_get_global(int8_t state)
/*---------------------------------------------------------------------------*/
uip_ds6_maddr_t *
uip_ds6_maddr_add(uip_ipaddr_t * ipaddr)
uip_ds6_maddr_add(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
((uip_ds6_element_t *)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
sizeof(uip_ds6_maddr_t), ipaddr, 128,
(uip_ds6_element_t **) & locmaddr) == FREESPACE) {
(uip_ds6_element_t **)&locmaddr) == FREESPACE) {
locmaddr->isused = 1;
uip_ipaddr_copy(&locmaddr->ipaddr, ipaddr);
return locmaddr;
@ -669,12 +660,12 @@ uip_ds6_maddr_rm(uip_ds6_maddr_t * maddr)
/*---------------------------------------------------------------------------*/
uip_ds6_maddr_t *
uip_ds6_maddr_lookup(uip_ipaddr_t * ipaddr)
uip_ds6_maddr_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
((uip_ds6_element_t *)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
sizeof(uip_ds6_maddr_t), ipaddr, 128,
(uip_ds6_element_t **) & locmaddr) == FOUND) {
(uip_ds6_element_t **)&locmaddr) == FOUND) {
return locmaddr;
}
return NULL;
@ -683,12 +674,12 @@ uip_ds6_maddr_lookup(uip_ipaddr_t * ipaddr)
/*---------------------------------------------------------------------------*/
uip_ds6_aaddr_t *
uip_ds6_aaddr_add(uip_ipaddr_t * ipaddr)
uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB,
((uip_ds6_element_t *)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB,
sizeof(uip_ds6_aaddr_t), ipaddr, 128,
(uip_ds6_element_t **) & locaaddr) == FREESPACE) {
(uip_ds6_element_t **)&locaaddr) == FREESPACE) {
locaaddr->isused = 1;
uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr);
return locaaddr;
@ -708,9 +699,9 @@ uip_ds6_aaddr_rm(uip_ds6_aaddr_t * aaddr)
/*---------------------------------------------------------------------------*/
uip_ds6_aaddr_t *
uip_ds6_aaddr_lookup(uip_ipaddr_t * ipaddr)
uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop((uip_ds6_element_t *) uip_ds6_if.aaddr_list,
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_if.aaddr_list,
UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128,
(uip_ds6_element_t **)&locaaddr) == FOUND) {
return locaaddr;
@ -720,12 +711,12 @@ uip_ds6_aaddr_lookup(uip_ipaddr_t * ipaddr)
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t * destipaddr)
uip_ds6_route_lookup(uip_ipaddr_t *destipaddr)
{
uip_ds6_route_t *locrt = NULL;
uint8_t longestmatch = 0;
PRINTF("DS6: Looking up route for");
PRINTF("DS6: Looking up route for ");
PRINT6ADDR(destipaddr);
PRINTF("\n");
@ -747,7 +738,7 @@ uip_ds6_route_lookup(uip_ipaddr_t * destipaddr)
PRINT6ADDR(&locrt->nexthop);
PRINTF("\n");
} else {
PRINTF("DS6: No route found ...\n");
PRINTF("DS6: No route found\n");
}
return locrt;
@ -755,27 +746,25 @@ uip_ds6_route_lookup(uip_ipaddr_t * destipaddr)
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t * ipaddr, u8_t length, uip_ipaddr_t * nexthop,
u8_t metric)
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop,
uint8_t metric)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *) uip_ds6_routing_table, UIP_DS6_ROUTE_NB,
((uip_ds6_element_t *)uip_ds6_routing_table, UIP_DS6_ROUTE_NB,
sizeof(uip_ds6_route_t), ipaddr, length,
(uip_ds6_element_t **) & locroute) == FREESPACE) {
(uip_ds6_element_t **)&locroute) == FREESPACE) {
locroute->isused = 1;
uip_ipaddr_copy(&(locroute->ipaddr), ipaddr);
locroute->length = length;
uip_ipaddr_copy(&(locroute->nexthop), nexthop);
locroute->metric = metric;
PRINTF("DS6: adding route:");
PRINTF("DS6: adding route: ");
PRINT6ADDR(ipaddr);
PRINTF(" via ");
PRINT6ADDR(nexthop);
PRINTF("\n");
ANNOTATE("#L %u 1;blue\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
}
return locroute;
@ -790,9 +779,10 @@ uip_ds6_route_rm(uip_ds6_route_t *route)
/* we need to check if this was the last route towards "nexthop" */
/* if so - remove that link (annotation) */
for(locroute = uip_ds6_routing_table;
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
if((locroute->isused) && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
/* we did find another link using the specific nexthop, so keep the #L */
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
locroute++) {
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
/* we found another link using the specific nexthop, so keep the #L */
return;
}
}
@ -804,8 +794,9 @@ void
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
{
for(locroute = uip_ds6_routing_table;
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
if((locroute->isused) && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
locroute++) {
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
locroute->isused = 0;
}
}
@ -825,9 +816,9 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
/* Only preferred global (not link-local) addresses */
if((locaddr->isused) && (locaddr->state == ADDR_PREFERRED) &&
(!uip_is_addr_link_local(&locaddr->ipaddr))) {
n = get_match_length(dst, &(locaddr->ipaddr));
if(locaddr->isused && locaddr->state == ADDR_PREFERRED &&
!uip_is_addr_link_local(&locaddr->ipaddr)) {
n = get_match_length(dst, &locaddr->ipaddr);
if(n >= best) {
best = n;
matchaddr = locaddr;
@ -848,7 +839,7 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
/*---------------------------------------------------------------------------*/
void
uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr)
uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t * lladdr)
{
/* We consider only links with IEEE EUI-64 identifier or
* IEEE 48-bit MAC addresses */
@ -859,7 +850,7 @@ uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr)
memcpy(ipaddr->u8 + 8, lladdr, 3);
ipaddr->u8[11] = 0xff;
ipaddr->u8[12] = 0xfe;
memcpy(ipaddr->u8 + 13, (uint8_t *) lladdr + 3, 3);
memcpy(ipaddr->u8 + 13, (uint8_t *)lladdr + 3, 3);
ipaddr->u8[8] ^= 0x02;
#else
#error uip-ds6.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
@ -868,7 +859,7 @@ uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr)
/*---------------------------------------------------------------------------*/
uint8_t
get_match_length(uip_ipaddr_t * src, uip_ipaddr_t * dst)
get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst)
{
uint8_t j, k, x_or;
uint8_t len = 0;
@ -894,7 +885,7 @@ get_match_length(uip_ipaddr_t * src, uip_ipaddr_t * dst)
/*---------------------------------------------------------------------------*/
void
uip_ds6_dad(uip_ds6_addr_t * addr)
uip_ds6_dad(uip_ds6_addr_t *addr)
{
/* send maxdadns NS for DAD */
if(addr->dadnscount < uip_ds6_if.maxdadns) {

2
core/net/uip-ds6.h Executable file → Normal file
View File

@ -373,7 +373,7 @@ uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr);
/** @{ */
uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr);
uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
uip_ipaddr_t *next_hop, u8_t metric);
uip_ipaddr_t *next_hop, uint8_t metric);
void uip_ds6_route_rm(uip_ds6_route_t *route);
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);

View File

@ -53,15 +53,17 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
value = 0;
zero = -1;
if(*addrstr == '[') addrstr++;
for(len = 0; len < sizeof(uip_ipaddr_t) - 1; addrstr++) {
c = *addrstr;
if(c == ':' || c == '\0') {
if(c == ':' || c == '\0' || c == ']') {
ipaddr->u8[len] = (value >> 8) & 0xff;
ipaddr->u8[len + 1] = value & 0xff;
len += 2;
value = 0;
if(c == '\0') {
if(c == '\0' || c == ']') {
break;
}
@ -86,7 +88,7 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
value = (value << 4) + (tmp & 0xf);
}
}
if(c != '\0') {
if(c != '\0' && c != ']') {
PRINTF("uiplib: too large address\n");
return 0;
}

View File

@ -139,7 +139,7 @@ ifndef NOAVRSIZE
endif
%.hex: %.out
$(OBJCOPY) $^ -O ihex $@
$(OBJCOPY) $^ -j .text -j .data -O ihex $@
%.ihex: %.out
$(OBJCOPY) $^ -O ihex $@

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

@ -73,6 +73,12 @@
#define RG_CSMA_BE CSMA_BE
#define RG_CSMA_SEED_0 CSMA_SEED_0
#define RG_PHY_RSSI PHY_RSSI
#define SR_CCA_MODE 0x08, 0x60, 5
//#define SR_CCA_CS_THRES 0x09, 0xf0, 4
#define SR_CCA_ED_THRES 0x09, 0x0f, 0
#define SR_CCA_REQUEST 0x08, 0x80, 7
#define SR_CCA_DONE 0x01, 0x80, 7
#define SR_CCA_STATUS 0x01, 0x40, 6
/* RF230 register assignments, for reference */

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
@ -206,8 +209,7 @@ static int rf230_receiving_packet(void);
static int pending_packet(void);
static int rf230_cca(void);
signed char rf230_last_rssi;
uint8_t rf230_last_correlation;
uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
const struct radio_driver rf230_driver =
{
@ -700,6 +702,27 @@ rf230_init(void)
PRINTF("rf230: Unsupported manufacturer ID %u\n",tmanu);
PRINTF("rf230: Version %u, ID %u\n",tvers,tmanu);
rf230_warm_reset();
/* Start the packet receive process */
process_start(&rf230_process, NULL);
/* Leave radio in on state (?)*/
on();
return 1;
}
/*---------------------------------------------------------------------------*/
/* Used to reinitialize radio parameters without losing pan and mac address, channel, power, etc. */
void rf230_warm_reset(void) {
#if RF230_CONF_SNEEZER && JACKDAW
/* Take jackdaw radio out of test mode */
#warning Manipulating PORTB pins for RF230 Sneezer mode!
PORTB &= ~(1<<7);
DDRB &= ~(1<<7);
#endif
hal_register_write(RG_IRQ_MASK, RF230_SUPPORTED_INTERRUPT_MASK);
/* Set up number of automatic retries 0-15 (0 implies PLL_ON sends instead of the extended TX_ARET mode */
@ -711,6 +734,24 @@ rf230_init(void)
hal_register_write(RG_CSMA_SEED_0,hal_register_read(RG_PHY_RSSI) );//upper two RSSI reg bits RND_VALUE are random in rf231
// hal_register_write(CSMA_SEED_1,42 );
/* CCA Mode Mode 1=Energy above threshold 2=Carrier sense only 3=Both 0=Either (RF231 only) */
//hal_subregister_write(SR_CCA_MODE,1); //1 is the power-on default
/* Carrier sense threshold (not implemented in RF230 or RF231) */
// hal_subregister_write(SR_CCA_CS_THRES,1);
/* CCA energy threshold = -91dB + 2*SR_CCA_ED_THRESH. Reset defaults to -77dB */
/* Use RF230 base of -91; RF231 base is -90 according to datasheet */
#if RF230_CONF_CCA_THRES < -91
#warning RF230_CONF_CCA_THRES below hardware limit, setting to -91dBm
hal_subregister_write(SR_CCA_ED_THRES,0);
#elif RF230_CONF_CCA_THRES > -61
#warning RF230_CONF_CCA_THRES above hardware limit, setting to -61dBm
hal_subregister_write(SR_CCA_ED_THRES,15);
#else
hal_subregister_write(SR_CCA_ED_THRES,(RF230_CONF_CCA_THRES+91)/2);
#endif
/* Use automatic CRC unless manual is specified */
#if RF230_CONF_CHECKSUM
hal_subregister_write(SR_TX_AUTO_CRC_ON, 0);
@ -718,19 +759,10 @@ rf230_init(void)
hal_subregister_write(SR_TX_AUTO_CRC_ON, 1);
#endif
/* Start the packet receive process */
process_start(&rf230_process, NULL);
/* Limit tx power for testing miniature Raven mesh */
#ifdef RF230_MAX_TX_POWER
set_txpower(RF230_MAX_TX_POWER); //0=3dbm 15=-17.2dbm
#endif
/* Leave radio in on state (?)*/
on();
return 1;
}
/*---------------------------------------------------------------------------*/
static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH+AUX_LEN];
@ -758,6 +790,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 +799,7 @@ rf230_transmit(unsigned short payload_len)
rf230_calibrated=1;
delay_us(80); //?
}
#endif
}
/* Wait for any previous operation or state transition to finish */
@ -878,7 +912,6 @@ rf230_transmit(unsigned short payload_len)
}
RELEASE_LOCK();
if (tx_result==1) { //success, data pending from adressee
tx_result=0; //Just show success?
} else if (tx_result==3) { //CSMA channel access failure
@ -1327,6 +1360,10 @@ if (RF230_receive_on) {
#endif
#endif /* speed vs. generality */
/* Save the smallest rssi. The display routine can reset by setting it to zero */
if ((rf230_smallest_rssi==0) || (rf230_last_rssi<rf230_smallest_rssi))
rf230_smallest_rssi=rf230_last_rssi;
// rf230_last_correlation = rxframe[rxframe_head].lqi;
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf230_last_rssi);
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf230_last_correlation);
@ -1446,10 +1483,18 @@ rf230_cca(void)
rf230_on();
}
// cca = CCA_IS_1;
DEBUGFLOW('c');
cca=1;
/* CCA Mode Mode 1=Energy above threshold 2=Carrier sense only 3=Both 0=Either (RF231 only) */
/* Use the current mode. Note triggering a manual CCA is not recommended in extended mode */
//hal_subregister_write(SR_CCA_MODE,1);
/* Start the CCA, wait till done, return result */
hal_subregister_write(SR_CCA_REQUEST,1);
delay_us(TIME_CCA);
//while ((hal_register_read(RG_TRX_STATUS) & 0x80) == 0 ) {continue;}
while (!hal_subregister_read(SR_CCA_DONE)) {continue;}
cca=hal_subregister_read(SR_CCA_STATUS);
if(radio_was_off) {
rf230_off();
}
@ -1476,4 +1521,46 @@ pending_packet(void)
return pending;
}
/*---------------------------------------------------------------------------*/
#if RF230_CONF_SNEEZER && JACKDAW
/* See A.2 in the datasheet for the sequence needed.
* This version for RF230 only, hence Jackdaw.
* A full reset seems not necessary and allows keeping the pan address, etc.
* for an easy reset back to network mode.
*/
void rf230_start_sneeze(void) {
//write buffer with random data for uniform spectral noise
//uint8_t txpower = hal_register_read(0x05); //save auto_crc bit and power
// hal_set_rst_low();
// hal_set_slptr_low();
// delay_us(TIME_RESET);
// hal_set_rst_high();
hal_register_write(0x0E, 0x01);
hal_register_write(0x02, 0x03);
hal_register_write(0x03, 0x10);
// hal_register_write(0x08, 0x20+26); //channel 26
hal_subregister_write(SR_CCA_MODE,1); //leave channel unchanged
// hal_register_write(0x05, 0x00); //output power maximum
hal_subregister_write(SR_TX_AUTO_CRC_ON, 0); //clear AUTO_CRC, leave output power unchanged
hal_register_read(0x01); //should be trx-off state=0x08
hal_frame_write(buffer, 127); //maximum length, random for spectral noise
hal_register_write(0x36,0x0F); //configure continuous TX
hal_register_write(0x3D,0x00); //Modulated frame, other options are:
// hal_register_write(RG_TX_2,0x10); //CW -2MHz
// hal_register_write(RG_TX_2,0x80); //CW -500KHz
// hal_register_write(RG_TX_2,0xC0); //CW +500KHz
DDRB |= 1<<7; //Raven USB stick has PB7 connected to the RF230 TST pin.
PORTB |= 1<<7; //Raise it to enable continuous TX Test Mode.
hal_register_write(0x02,0x09); //Set TRX_STATE to PLL_ON
delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE);
delay_us(TIME_PLL_LOCK);
delay_us(TIME_PLL_LOCK);
// while (hal_register_read(0x0f)!=1) {continue;} //wait for pll lock-hangs
hal_register_write(0x02,0x02); //Set TRX_STATE to TX_START
}
#endif

View File

@ -202,6 +202,8 @@ typedef void (*radio_rx_callback) (uint16_t data);
const struct radio_driver rf230_driver;
int rf230_init(void);
void rf230_warm_reset(void);
void rf230_start_sneeze(void);
//int rf230_on(void);
//int rf230_off(void);
void rf230_set_channel(uint8_t channel);
@ -214,8 +216,7 @@ uint8_t rf230_get_txpower(void);
void rf230_set_promiscuous_mode(bool isPromiscuous);
bool rf230_is_ready_to_send();
extern signed char rf230_last_rssi;
extern uint8_t rf230_last_correlation;
extern uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
uint8_t rf230_get_raw_rssi(void);
@ -223,4 +224,4 @@ uint8_t rf230_get_raw_rssi(void);
#endif
/** @} */
/*EOF*/
/*EOF*/

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,7 +72,12 @@ CUSTOM_RULE_C_TO_O=yes
CFLAGS += -I$(OBJECTDIR) -I$(CONTIKI_CPU)/board -DBOARD=$(TARGET)
$(OBJECTDIR)/board.h: $(OBJECTDIR)
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
endif
$(OBJECTDIR)/isr.o: $(CONTIKI_CPU)/src/isr.c
@ -85,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,116 @@
/*
* 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 ASM_H
#define ASM_H
/* Structure-based register definitions */
/* Example use:
ASM->KEY0 = 0xaabbccdd;
ASM->CONTROL1bits = (struct ASM_CONTROL1) {
.MASK_IRQ = 1,
.CBC = 1,
};
ASM->CONTROL1bits.SELF_TEST = 1;
*/
struct ASM_struct {
uint32_t KEY0;
uint32_t KEY1;
uint32_t KEY2;
uint32_t KEY3;
uint32_t DATA0;
uint32_t DATA1;
uint32_t DATA2;
uint32_t DATA3;
uint32_t CTR0;
uint32_t CTR1;
uint32_t CTR2;
uint32_t CTR3;
uint32_t CTR0_RESULT;
uint32_t CTR1_RESULT;
uint32_t CTR2_RESULT;
uint32_t CTR3_RESULT;
uint32_t CBC0_RESULT;
uint32_t CBC1_RESULT;
uint32_t CBC2_RESULT;
uint32_t CBC3_RESULT;
union {
uint32_t CONTROL0;
struct ASM_CONTROL0 {
uint32_t :24;
uint32_t START:1;
uint32_t CLEAR:1;
uint32_t LOAD_MAC:1;
uint32_t :4;
uint32_t CLEAR_IRQ:1;
} CONTROL0bits;
};
union {
uint32_t CONTROL1;
struct ASM_CONTROL1 {
uint32_t ON:1;
uint32_t NORMAL_MODE:1;
uint32_t BYPASS:1;
uint32_t :21;
uint32_t CBC:1;
uint32_t CTR:1;
uint32_t SELF_TEST:1;
uint32_t :4;
uint32_t MASK_IRQ:1;
} CONTROL1bits;
};
union {
uint32_t STATUS;
struct ASM_STATUS {
uint32_t :24;
uint32_t DONE:1;
uint32_t TEST_PASS:1;
uint32_t :6;
} STATUSbits;
};
uint32_t reserved;
uint32_t MAC0;
uint32_t MAC1;
uint32_t MAC2;
uint32_t MAC3;
};
static volatile struct ASM_struct * const ASM = (void *) (0x80008000);
#endif

View File

@ -220,6 +220,11 @@ struct CRM_struct {
static volatile struct CRM_struct * const CRM = (void *) (CRM_BASE);
/* COP watchdog timer helpers */
/* set the cop timout in milliseconds */
#define cop_timeout_ms(x) (CRM->COP_CNTLbits.COP_TIMEOUT = x/87)
#define cop_service() (CRM->COP_SERVICE = 0xc0de5afe)
/* Old register definitions, for compatibility */
#ifndef REG_NO_COMPAT

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

@ -166,5 +166,7 @@ extern void uart1_isr(void) __attribute__((weak));
extern void maca_isr(void) __attribute__((weak));
extern void asm_isr(void) __attribute__((weak));
#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

@ -46,5 +46,6 @@
#include "packet.h"
#include "uart1.h"
#include "utils.h"
#include "asm.h"
#endif

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);
@ -368,7 +368,9 @@ void post_receive(void) {
( 4 << PRECOUNT) |
( fcs_mode << NOFC ) |
( prm_mode << PRM) |
#if 0 //dak says removing ctrl auto fixes the autoack checksum error --- doesn't cause a performance issue either
(1 << maca_ctrl_auto) |
#endif
(maca_ctrl_seq_rx));
/* status bit 10 is set immediately */
/* then 11, 10, and 9 get set */

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

@ -18,7 +18,7 @@ FIQ_STACK_SIZE = 256;
SVC_STACK_SIZE = 256;
ABT_STACK_SIZE = 16;
UND_STACK_SIZE = 16;
HEAP_SIZE = 1024;
HEAP_SIZE = 4096;
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = 0x00400000); . = 0x00400000;

View File

@ -87,6 +87,9 @@ void irq(void)
cal_isr();
}
}
if(bit_is_set(pending, INT_NUM_ASM)) {
if(asm_isr != 0) { asm_isr(); }
}
*INTFRC = 0; /* stop forcing interrupts */

View File

@ -10,7 +10,11 @@ TARGETS := blink-red blink-green blink-blue blink-white blink-allio \
uart1-loopback \
tmr tmr-ints \
sleep \
printf
printf \
asm \
adc \
pwm \
wdt
# 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]);
}
}
}

209
cpu/mc1322x/tests/asm.c Normal file
View File

@ -0,0 +1,209 @@
/*
* 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 "tests.h"
#include "config.h"
void asm_isr(void) {
printf("asm isr\n\r");
ASM->CONTROL0bits.CLEAR_IRQ = 1;
}
void main(void) {
volatile int i;
/* trim the reference osc. to 24MHz */
trim_xtal();
uart_init(INC, MOD, SAMP);
vreg_init();
enable_irq(ASM);
print_welcome("asm");
printf("ASM Control 0: %08x\n\r", (unsigned int)ASM->CONTROL0);
printf("ASM Control 1: %08x\n\r", (unsigned int)ASM->CONTROL1);
printf("ASM Status: %08x\n\r", (unsigned int)ASM->STATUS);
printf("ASM Test pass: %d\n\r", ASM->STATUSbits.TEST_PASS);
/* ASM module is disabled until self-test passes */
printf("\n\r*** ASM self-test ***\n\r");
ASM->CONTROL1bits.ON = 1;
ASM->CONTROL1bits.SELF_TEST = 1;
ASM->CONTROL0bits.START = 1;
/* Self test takes 3330 periph. clocks (default 24Mhz) */
/* to complete. This doesn't wait 3330 exactly, but should be long enough */
for(i = 0; i < 3330; i++) { continue; }
printf("ASM Test pass: %d\n\r", ASM->STATUSbits.TEST_PASS);
/* must clear the self test bit when done */
ASM->CONTROL1bits.SELF_TEST = 0;
/* ASM starts in "BOOT" mode which uses an internal secret key
* to load encrypted data from an external source */
/* must set to NORMAL mode */
ASM->CONTROL1bits.NORMAL_MODE = 1;
/* setting the bypass bit will disable the encryption */
/* bypass defaults to off */
ASM->CONTROL1bits.BYPASS = 0;
printf("\n\r*** set ASM key ***\n\r");
ASM->KEY0 = 0xccddeeff;
ASM->KEY1 = 0x8899aabb;
ASM->KEY2 = 0x44556677;
ASM->KEY3 = 0x00112233;
/* KEY registers appear to be write-only (which is a good thing) */
/* even though the datasheet says you can read them */
printf("ASM Key [3,2,1,0] : 0x%08x%08x%08x%08x\n",
(unsigned int) ASM->KEY3,
(unsigned int) ASM->KEY2,
(unsigned int) ASM->KEY1,
(unsigned int) ASM->KEY0);
printf("\n\r*** CTR test ***\n\r");
printf("Encrypt\n\r");
ASM->CONTROL1bits.CTR = 1;
ASM->DATA0 = 0xdeaddead;
ASM->DATA1 = 0xbeefbeef;
ASM->DATA2 = 0xfaceface;
ASM->DATA3 = 0x01234567;
printf("ASM Data [3,2,1,0] : 0x%08x%08x%08x%08x\n",
(unsigned int) ASM->DATA3,
(unsigned int) ASM->DATA2,
(unsigned int) ASM->DATA1,
(unsigned int) ASM->DATA0);
ASM->CTR0 = 0x33333333;
ASM->CTR1 = 0x22222222;
ASM->CTR2 = 0x11111111;
ASM->CTR3 = 0x00000000;
printf("ASM CTR [3,2,1,0] : 0x%08x%08x%08x%08x\n",
(unsigned int) ASM->CTR3,
(unsigned int) ASM->CTR2,
(unsigned int) ASM->CTR1,
(unsigned int) ASM->CTR0);
ASM->CONTROL0bits.START = 1;
while(ASM->STATUSbits.DONE == 0) { continue; }
printf("ASM CTR RESULT [3,2,1,0]: 0x%08x%08x%08x%08x\n",
(unsigned int) ASM->CTR3_RESULT,
(unsigned int) ASM->CTR2_RESULT,
(unsigned int) ASM->CTR1_RESULT,
(unsigned int) ASM->CTR0_RESULT);
printf("Decrypt\n\r");
ASM->DATA0 = ASM->CTR0_RESULT;
ASM->DATA1 = ASM->CTR1_RESULT;
ASM->DATA2 = ASM->CTR2_RESULT;
ASM->DATA3 = ASM->CTR3_RESULT;
ASM->CONTROL0bits.START = 1;
while(ASM->STATUSbits.DONE == 0) { continue; }
printf("ASM CTR RESULT [3,2,1,0]: 0x%08x%08x%08x%08x\n",
(unsigned int) ASM->CTR3_RESULT,
(unsigned int) ASM->CTR2_RESULT,
(unsigned int) ASM->CTR1_RESULT,
(unsigned int) ASM->CTR0_RESULT);
printf("\n\r*** CBC MAC generation ***\n\r");
ASM->CONTROL1bits.CTR = 0;
ASM->CONTROL1bits.CBC = 1;
/* CBC is like a hash */
/* it doesn't use the CTR data */
/* the accumulated MAC is in the MAC registers */
/* you must use the CLEAR bit to reset the MAC state */
ASM->DATA0 = 0xdeaddead;
ASM->DATA1 = 0xbeefbeef;
ASM->DATA2 = 0xfaceface;
ASM->DATA3 = 0x01234567;
ASM->CONTROL0bits.CLEAR = 1;
ASM->CONTROL0bits.START = 1;
while(ASM->STATUSbits.DONE == 0) { continue; }
printf("ASM CBC RESULT [3,2,1,0]: 0x%08x%08x%08x%08x\n",
(unsigned int) ASM->CBC3_RESULT,
(unsigned int) ASM->CBC2_RESULT,
(unsigned int) ASM->CBC1_RESULT,
(unsigned int) ASM->CBC0_RESULT);
printf("\n\r*** CCM (CTR+CBC) ***\n\r");
ASM->CONTROL1bits.CTR = 1;
ASM->CONTROL1bits.CBC = 1;
ASM->CONTROL0bits.CLEAR = 1;
ASM->CONTROL0bits.START = 1;
while(ASM->STATUSbits.DONE == 0) { continue; }
printf("ASM CTR RESULT [3,2,1,0]: 0x%08x%08x%08x%08x\n",
(unsigned int) ASM->CTR3_RESULT,
(unsigned int) ASM->CTR2_RESULT,
(unsigned int) ASM->CTR1_RESULT,
(unsigned int) ASM->CTR0_RESULT);
printf("ASM CBC RESULT [3,2,1,0]: 0x%08x%08x%08x%08x\n",
(unsigned int) ASM->CBC3_RESULT,
(unsigned int) ASM->CBC2_RESULT,
(unsigned int) ASM->CBC1_RESULT,
(unsigned int) ASM->CBC0_RESULT);
while(1) {
}
}

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);
}
}

76
cpu/mc1322x/tests/wdt.c Normal file
View File

@ -0,0 +1,76 @@
/*
* 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"
#define DELAY 400000
#define LED GPIO_LED_RED
void main(void) {
volatile uint32_t i;
uart1_init(INC,MOD,SAMP);
printf("reset\n\r");
/* set the watchdog timer timeout to 1 sec */
cop_timeout_ms(1000);
/* enable the watchdog timer */
CRM->COP_CNTLbits.COP_EN = 1;
GPIO->PAD_DIR.LED = 1;
while(1) {
/* uncomment cop_service for normal operation */
//cop_service();
GPIO->DATA.LED = 1;
for(i=0; i<DELAY; i++) { continue; }
GPIO->DATA.LED = 0;
for(i=0; i<DELAY; i++) { continue; }
};
}

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

@ -24,7 +24,7 @@ GetOptions ('file=s' => \$filename,
'zerolen' => \$zerolen,
'terminal=s' => \$term,
'verbose' => \$verbose,
'baud=s' => \$baud,
'u|baud=s' => \$baud,
'rts=s' => \$rts,
'command=s' => \$command,
'a=s' => \$first_delay,
@ -41,8 +41,8 @@ if($filename eq '') {
print " -f required: binary file to load\n";
print " -s optional: secondary binary file to send\n";
print " -z optional: send a zero length file as secondary\n";
print " -t terminal default: /dev/ttyUSB0\n";
print " -b baud rate default: 115200\n";
print " -t, terminal default: /dev/ttyUSB0\n";
print " -u, --baud baud rate default: 115200\n";
print " -r [none|rts] flow control default: rts\n";
print " -c command to run for autoreset: \n";
print " e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n";

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

@ -111,7 +111,7 @@ loader_arch_load(unsigned short startaddr)
/* If the checksum was wrong, we beep. The number of beeps indicate
the numerival value of the calculated checksum. */
if(sum != 0xff) {
leds_red(LEDS_ON);
leds_on(LEDS_RED);
for(i = 0; i < (sum >> 4); ++i) {
beep_beep(200);
@ -131,23 +131,23 @@ loader_arch_load(unsigned short startaddr)
}
}
leds_red(LEDS_OFF);
leds_off(LEDS_RED);
return;
} else {
leds_green(LEDS_ON);
leds_on(LEDS_GREEN);
for(i = 0; i < 4; ++i) {
beep_beep(200);
for(j = 0; j < 2; ++j) {
clock_delay(60000);
}
}
leds_green(LEDS_OFF);
leds_off(LEDS_GREEN);
}
leds_yellow(LEDS_ON);
leds_on(LEDS_YELLOW);
startaddr += 2;
/* Read the size of the code segment from the next two bytes in EEPROM. */
@ -185,9 +185,9 @@ loader_arch_load(unsigned short startaddr)
flash_done();
leds_yellow(LEDS_OFF);
leds_off(LEDS_YELLOW);
leds_green(LEDS_ON);
leds_on(LEDS_GREEN);
/* Read the size of the code segment from the first two bytes in EEPROM. */
eeprom_read(startaddr + 2 + codelen, (char *)&datalen, 2);
@ -205,7 +205,7 @@ loader_arch_load(unsigned short startaddr)
clock_delay(20000);
}
leds_green(LEDS_OFF);
leds_off(LEDS_GREEN);
/* Execute the loaded program. */
init = ((void (*)(void *))FLASHADDR);

View File

@ -45,9 +45,9 @@ ifdef IAR
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library.a
else
ifdef PRINTF_FLOAT
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library.a $(CONTIKI_CPU)/hal/micro/cortexm3/e_stdio_thumb2.a
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library-gnu.a $(CONTIKI_CPU)/hal/micro/cortexm3/e_stdio_thumb2.a
else
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library.a $(CONTIKI_CPU)/hal/micro/cortexm3/e_stdio_intonly_thumb2.a
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library-gnu.a $(CONTIKI_CPU)/lib/e_stdio_intonly_thumb2.a
endif
endif
# `$(CC) -print-file-name=thumb2/libc.a` `$(CC) -print-file-name=thumb2/libgcc.a`
@ -74,7 +74,7 @@ AROPTS = --create
ASFLAGS = -s+ -w+ --cpu Cortex-M3 -L$(OBJECTDIR)
LDFLAGS += --redirect _Printf=_PrintfSmall --redirect _Scanf=_ScanfSmall --map=contiki-$(TARGET).map
ifndef COFFEE
LDFLAGS+= --config $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/iar-cfg.icf
LDFLAGS+= --config $(CONTIKI_CPU)/iar-cfg.icf
endif
OBJOPTS = --bin
@ -101,7 +101,7 @@ ASFLAGS = -mthumb -mcpu=cortex-m3 -fsigned-char -c -g -Wall -Os -ffunction-secti
-mlittle-endian -fshort-enums -x assembler-with-cpp -Wa,-EL
LDFLAGS += -mcpu=cortex-m3 \
-mthumb \
-Wl,-T -Xlinker $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/gnu.ld \
-Wl,-T -Xlinker $(CONTIKI_CPU)/gnu.ld \
-Wl,-static \
-u Default_Handler \
-nostartfiles \
@ -118,8 +118,6 @@ OBJOPTS = -O binary
endif
ifndef IAR
ifdef COFFEE_ADDRESS
COFFEE = 1
endif
@ -147,15 +145,18 @@ ifeq ($(COFFEE),1)
else
# Coffee starts at the end of the flash, before NVM section.
COFFEE_ADDRESS = 0x801F400
COFFEE_ADDRESS = 0x801F800
endif
ifndef IAR
LDFLAGS+= -Wl,--section-start=.coffee=$(COFFEE_ADDRESS)
else #IAR
ifeq ($(COFFEE),1)
LDFLAGS+= --config $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/iar-cfg-coffee.icf
LDFLAGS+= --config $(CONTIKI_CPU)/iar-cfg-coffee.icf
endif
endif

View File

@ -67,7 +67,7 @@
/* If using IAR, COFFEE_ADDRESS reflects the static value in the linker script
iar-cfg-coffee.icf, so it can't be passed as a parameter for Make.*/
#ifdef __ICCARM__
#define COFFEE_ADDRESS 0x8010000
#define COFFEE_ADDRESS 0x8010c00
#endif
#if (COFFEE_ADDRESS & 0x3FF) !=0
#error "COFFEE_ADDRESS not aligned to a 1024-bytes page boundary."
@ -96,9 +96,10 @@
#define COFFEE_LOG_SIZE 128 // COFFEE_MICRO_LOGS is 0.
#if COFFEE_PAGES <= 0x100
#define coffee_page_t uint8_t
#elif COFFEE_PAGES <= 0x10000
#if COFFEE_PAGES <= 127
#define coffee_page_t int8_t
#elif COFFEE_PAGES <= 0x7FFF
#define coffee_page_t int16_t
#endif

View File

@ -1,5 +1,5 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : stm32f10x_conf.h
* File Name : stm32w_conf.h
* Author : MCD Application Team
* Version : V2.0.3
* Date : 09/22/2008
@ -18,7 +18,7 @@
#define __STM32F10x_CONF_H
/* Includes ------------------------------------------------------------------*/
#include "stm32w_type.h"
#include "stm32w108_type.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

View File

@ -1,5 +1,5 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : stm32f10x_systick.c
* File Name : stm32w108_systick.c
* Author : MCD Application Team
* Version : V2.0.3
* Date : 09/22/2008

View File

@ -18,7 +18,7 @@
#ifndef __STM32W_SYSTICK_H
#define __STM32W_SYSTICK_H
#include "stm32w_type.h"
#include "stm32w108_type.h"
#include "stm32w_conf.h"
#ifndef EXT

View File

@ -1,80 +0,0 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : stm32f10x_type.h
* Author : MCD Application Team
* Version : V2.0.3
* Date : 09/22/2008
* Description : This file contains all the common data types used for the
* STM32F10x firmware library.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F10x_TYPE_H
#define __STM32F10x_TYPE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef signed long s32;
typedef signed short s16;
typedef signed char s8;
typedef signed long const sc32; /* Read Only */
typedef signed short const sc16; /* Read Only */
typedef signed char const sc8; /* Read Only */
typedef volatile signed long vs32;
typedef volatile signed short vs16;
typedef volatile signed char vs8;
typedef volatile signed long const vsc32; /* Read Only */
typedef volatile signed short const vsc16; /* Read Only */
typedef volatile signed char const vsc8; /* Read Only */
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned long const uc32; /* Read Only */
typedef unsigned short const uc16; /* Read Only */
typedef unsigned char const uc8; /* Read Only */
typedef volatile unsigned long vu32;
typedef volatile unsigned short vu16;
typedef volatile unsigned char vu8;
typedef volatile unsigned long const vuc32; /* Read Only */
typedef volatile unsigned short const vuc16; /* Read Only */
typedef volatile unsigned char const vuc8; /* Read Only */
//typedef enum {FALSE = 0, TRUE = !FALSE} bool;
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
#define U8_MAX ((u8)255)
#define S8_MAX ((s8)127)
#define S8_MIN ((s8)-128)
#define U16_MAX ((u16)65535u)
#define S16_MAX ((s16)32767)
#define S16_MIN ((s16)-32768)
#define U32_MAX ((u32)4294967295uL)
#define S32_MAX ((s32)2147483647)
#define S32_MIN ((s32)-2147483648)
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __STM32F10x_TYPE_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: uart1.h,v 1.1 2010/10/25 09:03:39 salvopitru Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __UART1_H__
#define __UART1_H__
//#include "msp430.h"
//
//#define UART1_BAUD2UBR(baud) ((MSP430_CPU_SPEED)/(baud))
void uart1_set_input(int (*input)(unsigned char c));
void uart1_writeb(unsigned char c);
void uart1_init(unsigned long ubr);
//uint8_t uart1_active(void);
#endif /* __UART1_H__ */

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