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:
commit
1716d837fc
25
.gitignore
vendored
25
.gitignore
vendored
|
@ -1,16 +1,13 @@
|
||||||
*~
|
.a
|
||||||
*.swp
|
*.bin
|
||||||
|
*.map
|
||||||
|
*.png
|
||||||
|
*.log
|
||||||
|
*.elf
|
||||||
*.ihex
|
*.ihex
|
||||||
obj_*
|
obj_*
|
||||||
*.z1
|
symbols.*
|
||||||
!Makefile.z1
|
Makefile.target
|
||||||
*.sky
|
doc/html
|
||||||
*.map
|
patches-*
|
||||||
*.a
|
tools/tunslip6
|
||||||
*pyc
|
|
||||||
*.pyc
|
|
||||||
symbols.c
|
|
||||||
symbols.h
|
|
||||||
*_del*
|
|
||||||
tools/
|
|
||||||
*.class
|
|
||||||
|
|
|
@ -36,9 +36,6 @@ savedefines:
|
||||||
@echo >Makefile.$(TARGET).defines "DEFINES = $(DEFINES)"
|
@echo >Makefile.$(TARGET).defines "DEFINES = $(DEFINES)"
|
||||||
|
|
||||||
OBJECTDIR = obj_$(TARGET)
|
OBJECTDIR = obj_$(TARGET)
|
||||||
ifeq (${wildcard $(OBJECTDIR)},)
|
|
||||||
DUMMY := ${shell mkdir $(OBJECTDIR)}
|
|
||||||
endif
|
|
||||||
|
|
||||||
LOWERCASE = -abcdefghijklmnopqrstuvwxyz
|
LOWERCASE = -abcdefghijklmnopqrstuvwxyz
|
||||||
UPPERCASE = _ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
UPPERCASE = _ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||||
|
@ -109,10 +106,13 @@ endif
|
||||||
|
|
||||||
target_makefile := $(wildcard $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET))
|
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)),)
|
ifeq ($(strip $(target_makefile)),)
|
||||||
${error The target platform "$(TARGET)" does not exist (maybe it was misspelled?)}
|
${error The target platform "$(TARGET)" does not exist (maybe it was misspelled?)}
|
||||||
else
|
else
|
||||||
|
ifeq (${wildcard $(OBJECTDIR)},)
|
||||||
|
DUMMY := ${shell mkdir $(OBJECTDIR)}
|
||||||
|
endif
|
||||||
include $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET)
|
include $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
0
apps/rest-coap/Makefile.rest-coap
Executable file → Normal file
0
apps/rest-coap/Makefile.rest-coap
Executable file → Normal file
0
apps/rest-common/Makefile.rest-common
Executable file → Normal file
0
apps/rest-common/Makefile.rest-common
Executable file → Normal file
0
apps/rest-common/rest.c
Executable file → Normal file
0
apps/rest-common/rest.c
Executable file → Normal file
0
apps/rest-common/rest.h
Executable file → Normal file
0
apps/rest-common/rest.h
Executable file → Normal file
0
apps/rest-http/Makefile.rest-http
Executable file → Normal file
0
apps/rest-http/Makefile.rest-http
Executable file → Normal file
0
apps/rest-http/http-common.c
Executable file → Normal file
0
apps/rest-http/http-common.c
Executable file → Normal file
0
apps/rest-http/http-common.h
Executable file → Normal file
0
apps/rest-http/http-common.h
Executable file → Normal file
0
apps/rest-http/http-server.c
Executable file → Normal file
0
apps/rest-http/http-server.c
Executable file → Normal file
0
apps/rest-http/http-server.h
Executable file → Normal file
0
apps/rest-http/http-server.h
Executable file → Normal file
|
@ -146,7 +146,7 @@ print_remote_stats(struct stats *s)
|
||||||
{
|
{
|
||||||
unsigned long total_time;
|
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,
|
current_type,
|
||||||
s->sent, s->received, s->timedout,
|
s->sent, s->received, s->timedout,
|
||||||
s->end - s->start,
|
s->end - s->start,
|
||||||
|
@ -173,7 +173,7 @@ print_local_stats(struct stats *s)
|
||||||
{
|
{
|
||||||
unsigned long total_time;
|
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,
|
current_type,
|
||||||
s->sent, s->received, s->timedout,
|
s->sent, s->received, s->timedout,
|
||||||
s->end - s->start,
|
s->end - s->start,
|
||||||
|
@ -185,11 +185,11 @@ print_local_stats(struct stats *s)
|
||||||
|
|
||||||
printf("Local node statistics:\n");
|
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,
|
(s->end - s->start) / CLOCK_SECOND,
|
||||||
((10 * (s->end - s->start)) / CLOCK_SECOND) % 10,
|
((10 * (s->end - s->start)) / CLOCK_SECOND) % 10,
|
||||||
CLOCK_SECOND * s->sent / (s->end - s->start),
|
((1UL * CLOCK_SECOND * s->sent) / (s->end - s->start)),
|
||||||
(100 * CLOCK_SECOND * s->sent / (s->end - s->start)) % 100);
|
(((100UL * CLOCK_SECOND * s->sent) / (s->end - s->start)) % 100));
|
||||||
|
|
||||||
printf(" Average round-trip-time: %lu ms (%lu + %lu)\n",
|
printf(" Average round-trip-time: %lu ms (%lu + %lu)\n",
|
||||||
(1000 * (s->total_rx_latency + s->total_tx_latency) / s->received) /
|
(1000 * (s->total_rx_latency + s->total_tx_latency) / s->received) /
|
||||||
|
|
|
@ -174,6 +174,17 @@ typedef struct unit_test {
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} 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. */
|
/* The default print function. */
|
||||||
void unit_test_print_report(const unit_test_t *utp);
|
void unit_test_print_report(const unit_test_t *utp);
|
||||||
|
|
||||||
|
|
0
core/cfs/cfs-coffee.c
Executable file → Normal file
0
core/cfs/cfs-coffee.c
Executable file → Normal file
|
@ -50,7 +50,6 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
|
|
|
@ -121,7 +121,3 @@ leds_invert(unsigned char ledv) {
|
||||||
show_leds(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); }
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
|
|
|
@ -55,11 +55,18 @@ void leds_init(void);
|
||||||
*/
|
*/
|
||||||
void leds_blink(void);
|
void leds_blink(void);
|
||||||
|
|
||||||
|
#ifndef LEDS_GREEN
|
||||||
#define LEDS_GREEN 1
|
#define LEDS_GREEN 1
|
||||||
#define LEDS_YELLOW 2
|
#endif /* LEDS_GREEN */
|
||||||
#define LEDS_RED 4
|
#ifndef LEDS_YELLOW
|
||||||
#define LEDS_BLUE LEDS_YELLOW /* Tmote Sky is colorblind? */
|
#define LEDS_YELLOW 2
|
||||||
#define leds_blue leds_yellow
|
#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
|
#ifdef LEDS_CONF_ALL
|
||||||
#define LEDS_ALL 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_toggle(unsigned char leds);
|
||||||
void leds_invert(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
|
* Leds implementation
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -46,41 +46,40 @@
|
||||||
#define ETX_LIMIT 15
|
#define ETX_LIMIT 15
|
||||||
#define ETX_SCALE 100
|
#define ETX_SCALE 100
|
||||||
#define ETX_ALPHA 90
|
#define ETX_ALPHA 90
|
||||||
#define ETX_FIRST_GUESS 5
|
#define ETX_NOACK_PENALTY ETX_LIMIT
|
||||||
|
|
||||||
#define NOACK_PACKET_ETX 8
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
NEIGHBOR_ATTRIBUTE(uint8_t, etx, NULL);
|
NEIGHBOR_ATTRIBUTE(link_metric_t, etx, NULL);
|
||||||
|
|
||||||
static neighbor_info_subscriber_t subscriber_callback;
|
static neighbor_info_subscriber_t subscriber_callback;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
update_etx(const rimeaddr_t *dest, int packet_etx)
|
update_metric(const rimeaddr_t *dest, int packet_metric)
|
||||||
{
|
{
|
||||||
uint8_t *etxp;
|
link_metric_t *metricp;
|
||||||
uint8_t recorded_etx, new_etx;
|
link_metric_t recorded_metric, new_metric;
|
||||||
|
|
||||||
etxp = (uint8_t *)neighbor_attr_get_data(&etx, dest);
|
metricp = (link_metric_t *)neighbor_attr_get_data(&etx, dest);
|
||||||
if(etxp == NULL || *etxp == 0) {
|
packet_metric = NEIGHBOR_INFO_ETX2FIX(packet_metric);
|
||||||
recorded_etx = NEIGHBOR_INFO_ETX2FIX(ETX_FIRST_GUESS);
|
if(metricp == NULL || *metricp == 0) {
|
||||||
|
recorded_metric = NEIGHBOR_INFO_ETX2FIX(ETX_LIMIT);
|
||||||
|
new_metric = packet_metric;
|
||||||
} else {
|
} 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",
|
PRINTF("neighbor-info: ETX changed from %d to %d (packet ETX = %d) %d\n",
|
||||||
NEIGHBOR_INFO_FIX2ETX(recorded_etx),
|
NEIGHBOR_INFO_FIX2ETX(recorded_metric),
|
||||||
NEIGHBOR_INFO_FIX2ETX(new_etx),
|
NEIGHBOR_INFO_FIX2ETX(new_metric),
|
||||||
NEIGHBOR_INFO_FIX2ETX(packet_etx),
|
NEIGHBOR_INFO_FIX2ETX(packet_metric),
|
||||||
dest->u8[7]);
|
dest->u8[7]);
|
||||||
|
|
||||||
if(neighbor_attr_has_neighbor(dest)) {
|
if(neighbor_attr_has_neighbor(dest)) {
|
||||||
neighbor_attr_set_data(&etx, dest, &new_etx);
|
neighbor_attr_set_data(&etx, dest, &new_metric);
|
||||||
if(new_etx != recorded_etx && subscriber_callback != NULL) {
|
if(new_metric != recorded_metric && subscriber_callback != NULL) {
|
||||||
subscriber_callback(dest, 1, new_etx);
|
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");
|
PRINTF("neighbor-info: The neighbor is already known\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(subscriber_callback != NULL) {
|
|
||||||
subscriber_callback(addr, 1, NEIGHBOR_INFO_ETX2FIX(ETX_FIRST_GUESS));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +103,7 @@ void
|
||||||
neighbor_info_packet_sent(int status, int numtx)
|
neighbor_info_packet_sent(int status, int numtx)
|
||||||
{
|
{
|
||||||
const rimeaddr_t *dest;
|
const rimeaddr_t *dest;
|
||||||
uint8_t packet_etx;
|
link_metric_t packet_metric;
|
||||||
|
|
||||||
dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
|
dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
|
||||||
if(rimeaddr_cmp(dest, &rimeaddr_null)) {
|
if(rimeaddr_cmp(dest, &rimeaddr_null)) {
|
||||||
|
@ -120,25 +116,22 @@ neighbor_info_packet_sent(int status, int numtx)
|
||||||
|
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case MAC_TX_OK:
|
case MAC_TX_OK:
|
||||||
packet_etx = numtx;
|
packet_metric = numtx;
|
||||||
add_neighbor(dest);
|
add_neighbor(dest);
|
||||||
break;
|
break;
|
||||||
case MAC_TX_COLLISION:
|
case MAC_TX_COLLISION:
|
||||||
packet_etx = numtx;
|
packet_metric = numtx;
|
||||||
break;
|
break;
|
||||||
case MAC_TX_NOACK:
|
case MAC_TX_NOACK:
|
||||||
packet_etx = NOACK_PACKET_ETX;
|
packet_metric = ETX_NOACK_PENALTY;
|
||||||
/* error and collissions will not cause high hits ??? */
|
|
||||||
break;
|
break;
|
||||||
case MAC_TX_ERR:
|
|
||||||
default:
|
default:
|
||||||
packet_etx = 0;
|
/* Do not penalize the ETX when collisions or transmission
|
||||||
break;
|
errors occur. */
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(packet_etx > 0) {
|
update_metric(dest, packet_metric);
|
||||||
update_etx(dest, packet_etx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -169,12 +162,12 @@ neighbor_info_subscribe(neighbor_info_subscriber_t s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uint8_t
|
link_metric_t
|
||||||
neighbor_info_get_etx(const rimeaddr_t *addr)
|
neighbor_info_get_metric(const rimeaddr_t *addr)
|
||||||
{
|
{
|
||||||
uint8_t *etxp;
|
link_metric_t *metricp;
|
||||||
|
|
||||||
etxp = (uint8_t *)neighbor_attr_get_data(&etx, addr);
|
metricp = (link_metric_t *)neighbor_attr_get_data(&etx, addr);
|
||||||
return etxp == NULL ? 0 : *etxp;
|
return metricp == NULL ? ETX_LIMIT : *metricp;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#define NEIGHBOR_INFO_FIX2ETX(fix) ((fix) / NEIGHBOR_INFO_ETX_DIVISOR)
|
#define NEIGHBOR_INFO_FIX2ETX(fix) ((fix) / NEIGHBOR_INFO_ETX_DIVISOR)
|
||||||
|
|
||||||
typedef void (*neighbor_info_subscriber_t)(const rimeaddr_t *, int known, int etx);
|
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
|
* 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.
|
* \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 */
|
#endif /* NEIGHBOR_INFO_H */
|
||||||
|
|
|
@ -286,7 +286,7 @@ PT_THREAD(psock_readto(CC_REGISTER_ARG struct psock *psock, unsigned char c))
|
||||||
PT_END(&psock->psockpt);
|
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);
|
PT_BEGIN(&psock->psockpt);
|
||||||
|
|
||||||
|
@ -295,15 +295,17 @@ PT_THREAD(psock_readbuf(CC_REGISTER_ARG struct psock *psock))
|
||||||
/* XXX: Should add buf_checkmarker() before do{} loop, if
|
/* XXX: Should add buf_checkmarker() before do{} loop, if
|
||||||
incoming data has been handled while waiting for a write. */
|
incoming data has been handled while waiting for a write. */
|
||||||
|
|
||||||
if(psock->readlen == 0) {
|
/* read len bytes or to end of data */
|
||||||
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
|
do {
|
||||||
psock->state = STATE_READ;
|
if(psock->readlen == 0) {
|
||||||
psock->readptr = (u8_t *)uip_appdata;
|
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
|
||||||
psock->readlen = uip_datalen();
|
psock->state = STATE_READ;
|
||||||
}
|
psock->readptr = (u8_t *)uip_appdata;
|
||||||
buf_bufdata(&psock->buf, psock->bufsize,
|
psock->readlen = uip_datalen();
|
||||||
&psock->readptr,
|
}
|
||||||
&psock->readlen);
|
} while(buf_bufdata(&psock->buf, psock->bufsize,
|
||||||
|
&psock->readptr, &psock->readlen) == BUF_NOT_FULL &&
|
||||||
|
psock_datalen(psock) < len);
|
||||||
|
|
||||||
if(psock_datalen(psock) == 0) {
|
if(psock_datalen(psock) == 0) {
|
||||||
psock->state = STATE_NONE;
|
psock->state = STATE_NONE;
|
||||||
|
@ -311,6 +313,7 @@ PT_THREAD(psock_readbuf(CC_REGISTER_ARG struct psock *psock))
|
||||||
}
|
}
|
||||||
PT_END(&psock->psockpt);
|
PT_END(&psock->psockpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
psock_init(CC_REGISTER_ARG struct psock *psock,
|
psock_init(CC_REGISTER_ARG struct psock *psock,
|
||||||
|
|
|
@ -241,7 +241,7 @@ PT_THREAD(psock_generator_send(struct psock *psock,
|
||||||
*/
|
*/
|
||||||
#define PSOCK_CLOSE(psock) uip_close()
|
#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.
|
* Read data until the buffer is full.
|
||||||
*
|
*
|
||||||
|
@ -255,7 +255,24 @@ PT_THREAD(psock_readbuf(struct psock *psock));
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#define PSOCK_READBUF(psock) \
|
#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));
|
PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -94,8 +94,6 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF};
|
||||||
#define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS
|
#define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS
|
||||||
#endif /* !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. */
|
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */
|
||||||
MEMB(parent_memb, struct rpl_parent, RPL_MAX_PARENTS);
|
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));
|
memcpy(&p->addr, addr, sizeof(p->addr));
|
||||||
p->dag = dag;
|
p->dag = dag;
|
||||||
p->rank = dio->rank;
|
p->rank = dio->rank;
|
||||||
p->etx = INITIAL_ETX;
|
p->link_metric = INITIAL_LINK_METRIC;
|
||||||
p->dtsn = 0;
|
p->dtsn = 0;
|
||||||
|
|
||||||
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
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);
|
rpl_reset_dio_timer(dag, 1);
|
||||||
PRINTF("RPL: New preferred parent, rank changed from %u to %u\n",
|
PRINTF("RPL: New preferred parent, rank changed from %u to %u\n",
|
||||||
(unsigned)dag->rank, dag->of->calculate_rank(best, 0));
|
(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
|
/* 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");
|
PRINTF("succeeded\n");
|
||||||
|
|
||||||
p->etx = INITIAL_ETX; /* The lowest confidence for new parents. */
|
|
||||||
|
|
||||||
/* Determine the objective function by using the
|
/* Determine the objective function by using the
|
||||||
objective code point of the DIO. */
|
objective code point of the DIO. */
|
||||||
of = rpl_find_of(dio->ocp);
|
of = rpl_find_of(dio->ocp);
|
||||||
|
@ -743,6 +740,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
|
|
||||||
/* We have allocated a candidate parent; process the DIO further. */
|
/* We have allocated a candidate parent; process the DIO further. */
|
||||||
|
|
||||||
|
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
||||||
p->rank = dio->rank;
|
p->rank = dio->rank;
|
||||||
if(rpl_process_parent_event(dag, p) == 0) {
|
if(rpl_process_parent_event(dag, p) == 0) {
|
||||||
/* The candidate parent no longer exists. */
|
/* The candidate parent no longer exists. */
|
||||||
|
|
|
@ -250,9 +250,10 @@ dio_input(void)
|
||||||
dio.mc.aggr = buffer[i + 4] >> 4;
|
dio.mc.aggr = buffer[i + 4] >> 4;
|
||||||
dio.mc.prec = buffer[i + 4] & 0xf;
|
dio.mc.prec = buffer[i + 4] & 0xf;
|
||||||
dio.mc.length = buffer[i + 5];
|
dio.mc.length = buffer[i + 5];
|
||||||
|
|
||||||
if(dio.mc.type == RPL_DAG_MC_ETX) {
|
if(dio.mc.type == RPL_DAG_MC_ETX) {
|
||||||
dio.mc.etx.etx = buffer[i + 6] << 8;
|
dio.mc.obj.etx = buffer[i + 6] << 8;
|
||||||
dio.mc.etx.etx |= buffer[i + 7];
|
dio.mc.obj.etx |= buffer[i + 7];
|
||||||
|
|
||||||
PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n",
|
PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n",
|
||||||
(unsigned)dio.mc.type,
|
(unsigned)dio.mc.type,
|
||||||
|
@ -260,7 +261,10 @@ dio_input(void)
|
||||||
(unsigned)dio.mc.aggr,
|
(unsigned)dio.mc.aggr,
|
||||||
(unsigned)dio.mc.prec,
|
(unsigned)dio.mc.prec,
|
||||||
(unsigned)dio.mc.length,
|
(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 {
|
} else {
|
||||||
PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type);
|
PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type);
|
||||||
return;
|
return;
|
||||||
|
@ -380,8 +384,12 @@ dio_output(rpl_dag_t *dag, uip_ipaddr_t *uc_addr)
|
||||||
buffer[pos++] |= dag->mc.prec;
|
buffer[pos++] |= dag->mc.prec;
|
||||||
if(dag->mc.type == RPL_DAG_MC_ETX) {
|
if(dag->mc.type == RPL_DAG_MC_ETX) {
|
||||||
buffer[pos++] = 2;
|
buffer[pos++] = 2;
|
||||||
buffer[pos++] = dag->mc.etx.etx >> 8;
|
buffer[pos++] = dag->mc.obj.etx >> 8;
|
||||||
buffer[pos++] = dag->mc.etx.etx & 0xff;
|
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 {
|
} else {
|
||||||
PRINTF("RPL: Unable to send DIO because of unhandled DAG MC type %u\n",
|
PRINTF("RPL: Unable to send DIO because of unhandled DAG MC type %u\n",
|
||||||
(unsigned)dag->mc.type);
|
(unsigned)dag->mc.type);
|
||||||
|
@ -459,6 +467,8 @@ dao_input(void)
|
||||||
uint8_t prefixlen;
|
uint8_t prefixlen;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t subopt_type;
|
uint8_t subopt_type;
|
||||||
|
uint8_t pathcontrol;
|
||||||
|
uint8_t pathsequence;
|
||||||
uip_ipaddr_t prefix;
|
uip_ipaddr_t prefix;
|
||||||
uip_ds6_route_t *rep;
|
uip_ds6_route_t *rep;
|
||||||
uint8_t buffer_length;
|
uint8_t buffer_length;
|
||||||
|
@ -523,7 +533,9 @@ dao_input(void)
|
||||||
break;
|
break;
|
||||||
case RPL_DIO_SUBOPT_TRANSIT:
|
case RPL_DIO_SUBOPT_TRANSIT:
|
||||||
/* path sequence and control ignored */
|
/* 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 */
|
/* parent address also ignored */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -567,11 +579,11 @@ dao_input(void)
|
||||||
|
|
||||||
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
|
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
|
||||||
if(rep == NULL) {
|
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");
|
PRINTF("RPL: Could not add a route after receiving a DAO\n");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
rep->state.lifetime = lifetime;
|
rep->state.lifetime = lifetime * dag->lifetime_unit;
|
||||||
rep->state.learned_from = learned_from;
|
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);
|
memcpy(buffer + pos, &prefix, (prefixlen + 7) / CHAR_BIT);
|
||||||
pos += ((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++] = RPL_DIO_SUBOPT_TRANSIT;
|
||||||
buffer[pos++] = 6;
|
buffer[pos++] = 4;
|
||||||
buffer[pos++] = 0; /* path seq - ignored */
|
buffer[pos++] = 0; /* flags - ignored */
|
||||||
buffer[pos++] = 0; /* path control - ignored */
|
buffer[pos++] = 0; /* path control - ignored */
|
||||||
set32(buffer, pos, lifetime);
|
buffer[pos++] = 0; /* path seq - ignored */
|
||||||
pos += 4;
|
buffer[pos++] = (lifetime / dag->lifetime_unit) & 0xff;
|
||||||
|
|
||||||
if(n == NULL) {
|
if(n == NULL) {
|
||||||
uip_create_linklocal_rplnodes_mcast(&addr);
|
uip_create_linklocal_rplnodes_mcast(&addr);
|
||||||
|
|
|
@ -66,7 +66,7 @@ rpl_of_t rpl_of_etx = {
|
||||||
|
|
||||||
#define NI_ETX_TO_RPL_ETX(etx) \
|
#define NI_ETX_TO_RPL_ETX(etx) \
|
||||||
((etx) * (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR))
|
((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))
|
((etx) / (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR))
|
||||||
|
|
||||||
/* Reject parents that have a higher link metric than the following. */
|
/* 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. */
|
/* Reject parents that have a higher path cost than the following. */
|
||||||
#define MAX_PATH_COST 100
|
#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
|
* The rank must differ more than 1/PARENT_SWITCH_THRESHOLD_DIV in order
|
||||||
* to switch preferred parent.
|
* to switch preferred parent.
|
||||||
*/
|
*/
|
||||||
#define PARENT_SWITCH_THRESHOLD_DIV 2
|
#define PARENT_SWITCH_THRESHOLD_DIV 2
|
||||||
|
|
||||||
typedef uint16_t rpl_etx_t;
|
typedef uint16_t rpl_path_metric_t;
|
||||||
#define MAX_ETX 65535
|
|
||||||
|
|
||||||
static uint16_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
|
static void
|
||||||
|
@ -113,12 +112,9 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
|
||||||
if(base_rank == 0) {
|
if(base_rank == 0) {
|
||||||
return INFINITE_RANK;
|
return INFINITE_RANK;
|
||||||
}
|
}
|
||||||
rank_increase = INITIAL_LINK_METRIC * DEFAULT_MIN_HOPRANKINC;
|
rank_increase = NEIGHBOR_INFO_FIX2ETX(INITIAL_LINK_METRIC) * DEFAULT_MIN_HOPRANKINC;
|
||||||
} else {
|
} else {
|
||||||
if(p->etx == 0) {
|
rank_increase = NEIGHBOR_INFO_FIX2ETX(p->link_metric) * p->dag->min_hoprankinc;
|
||||||
p->etx = INITIAL_LINK_METRIC * NEIGHBOR_INFO_ETX_DIVISOR;
|
|
||||||
}
|
|
||||||
rank_increase = (p->etx * p->dag->min_hoprankinc) / NEIGHBOR_INFO_ETX_DIVISOR;
|
|
||||||
if(base_rank == 0) {
|
if(base_rank == 0) {
|
||||||
base_rank = p->rank;
|
base_rank = p->rank;
|
||||||
}
|
}
|
||||||
|
@ -140,46 +136,64 @@ static rpl_parent_t *
|
||||||
best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
||||||
{
|
{
|
||||||
rpl_dag_t *dag;
|
rpl_dag_t *dag;
|
||||||
rpl_etx_t min_diff;
|
rpl_path_metric_t min_diff;
|
||||||
rpl_etx_t p1_etx;
|
rpl_path_metric_t p1_metric;
|
||||||
rpl_etx_t p2_etx;
|
rpl_path_metric_t p2_metric;
|
||||||
|
|
||||||
dag = p1->dag; /* Both parents must be in the same DAG. */
|
dag = p1->dag; /* Both parents must be in the same DAG. */
|
||||||
|
|
||||||
min_diff = RPL_DAG_MC_ETX_DIVISOR /
|
min_diff = RPL_DAG_MC_ETX_DIVISOR /
|
||||||
PARENT_SWITCH_THRESHOLD_DIV;
|
PARENT_SWITCH_THRESHOLD_DIV;
|
||||||
|
|
||||||
p1_etx = calculate_etx(p1);
|
p1_metric = calculate_path_metric(p1);
|
||||||
p2_etx = calculate_etx(p2);
|
p2_metric = calculate_path_metric(p2);
|
||||||
|
|
||||||
/* Maintain stability of the preferred parent in case of similar ranks. */
|
/* Maintain stability of the preferred parent in case of similar ranks. */
|
||||||
if(p1_etx < p2_etx + min_diff &&
|
if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
|
||||||
p1_etx > p2_etx - min_diff) {
|
if(p1_metric < p2_metric + min_diff &&
|
||||||
PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
|
p1_metric > p2_metric - min_diff) {
|
||||||
p2_etx - min_diff,
|
PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
|
||||||
p1_etx,
|
p2_metric - min_diff,
|
||||||
p2_etx + min_diff);
|
p1_metric,
|
||||||
return dag->preferred_parent;
|
p2_metric + min_diff);
|
||||||
|
return dag->preferred_parent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p1_etx < p2_etx ? p1 : p2;
|
return p1_metric < p2_metric ? p1 : p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_metric_container(rpl_dag_t *dag)
|
update_metric_container(rpl_dag_t *dag)
|
||||||
{
|
{
|
||||||
|
#if RPL_DAG_MC == RPL_DAG_MC_ETX
|
||||||
dag->mc.type = RPL_DAG_MC_ETX;
|
dag->mc.type = RPL_DAG_MC_ETX;
|
||||||
dag->mc.flags = RPL_DAG_MC_FLAG_P;
|
dag->mc.flags = RPL_DAG_MC_FLAG_P;
|
||||||
dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
|
dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
|
||||||
dag->mc.prec = 0;
|
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)) {
|
if(dag->rank == ROOT_RANK(dag)) {
|
||||||
dag->mc.etx.etx = 0;
|
dag->mc.obj.etx = 0;
|
||||||
} else {
|
} 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",
|
PRINTF("RPL: My path ETX to the root is %u.%u\n",
|
||||||
dag->mc.etx.etx / RPL_DAG_MC_ETX_DIVISOR,
|
dag->mc.obj.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 * 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 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,8 @@
|
||||||
|
|
||||||
#define INFINITE_RANK 0xffff
|
#define INFINITE_RANK 0xffff
|
||||||
|
|
||||||
|
#define INITIAL_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(5)
|
||||||
|
|
||||||
/* Represents 2^n ms. */
|
/* Represents 2^n ms. */
|
||||||
/* Default value according to the specification is 3 which
|
/* Default value according to the specification is 3 which
|
||||||
means 8 milliseconds, but that is an unreasonable value if
|
means 8 milliseconds, but that is an unreasonable value if
|
||||||
|
@ -218,6 +220,7 @@ struct rpl_stats {
|
||||||
uint16_t global_repairs;
|
uint16_t global_repairs;
|
||||||
uint16_t malformed_msgs;
|
uint16_t malformed_msgs;
|
||||||
uint16_t resets;
|
uint16_t resets;
|
||||||
|
uint16_t parent_switch;
|
||||||
};
|
};
|
||||||
typedef struct rpl_stats rpl_stats_t;
|
typedef struct rpl_stats rpl_stats_t;
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ new_dio_interval(rpl_dag_t *dag)
|
||||||
dag->version,
|
dag->version,
|
||||||
dag->dio_totint, dag->dio_totsend,
|
dag->dio_totint, dag->dio_totsend,
|
||||||
dag->dio_totrecv,dag->dio_intcurrent,
|
dag->dio_totrecv,dag->dio_intcurrent,
|
||||||
dag->rank == ROOT_RANK ? "BLUE" : "ORANGE");
|
dag->rank == ROOT_RANK(dag) ? "BLUE" : "ORANGE");
|
||||||
#endif /* RPL_CONF_STATS */
|
#endif /* RPL_CONF_STATS */
|
||||||
|
|
||||||
/* reset the redundancy counter */
|
/* reset the redundancy counter */
|
||||||
|
@ -205,7 +205,8 @@ handle_dao_timer(void *ptr)
|
||||||
fan-out as being under investigation. */
|
fan-out as being under investigation. */
|
||||||
if(dag->preferred_parent != NULL) {
|
if(dag->preferred_parent != NULL) {
|
||||||
PRINTF("RPL: handle_dao_timer - sending DAO\n");
|
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 {
|
} else {
|
||||||
PRINTF("RPL: Could not find a parent to send a DAO to \n");
|
PRINTF("RPL: Could not find a parent to send a DAO to \n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,11 +148,10 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(etx != parent->etx) {
|
/* Trigger DAG rank recalculation. */
|
||||||
/* Trigger DAG rank recalculation. */
|
parent->updated = 1;
|
||||||
parent->updated = 1;
|
|
||||||
}
|
parent->link_metric = etx;
|
||||||
parent->etx = etx;
|
|
||||||
|
|
||||||
if(dag->of->parent_state_callback != NULL) {
|
if(dag->of->parent_state_callback != NULL) {
|
||||||
dag->of->parent_state_callback(parent, known, etx);
|
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);
|
PRINT6ADDR(&parent->addr);
|
||||||
PRINTF(" because of bad connectivity (ETX %d)\n", etx);
|
PRINTF(" because of bad connectivity (ETX %d)\n", etx);
|
||||||
parent->rank = INFINITE_RANK;
|
parent->rank = INFINITE_RANK;
|
||||||
parent->updated = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
|
@ -49,6 +49,17 @@
|
||||||
#define RPL_CONF_STATS 0
|
#define RPL_CONF_STATS 0
|
||||||
#endif /* RPL_CONF_STATS */
|
#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
|
* The objective function used by RPL is configurable through the
|
||||||
* RPL_CONF_OF parameter. This should be defined to be the name of an
|
* 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. */
|
/* 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_NONE 0 /* Local identifier for empty MC */
|
||||||
#define RPL_DAG_MC_NSA 1 /* Node State and Attributes */
|
#define RPL_DAG_MC_NSA 1 /* Node State and Attributes */
|
||||||
#define RPL_DAG_MC_NE 2 /* Node Energy */
|
#define RPL_DAG_MC_ENERGY 2 /* Node Energy */
|
||||||
#define RPL_DAG_MC_HC 3 /* Hop Count */
|
#define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */
|
||||||
#define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */
|
#define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */
|
||||||
#define RPL_DAG_MC_LATENCY 5 /* Latency */
|
#define RPL_DAG_MC_LATENCY 5 /* Latency */
|
||||||
#define RPL_DAG_MC_LQL 6 /* Link Quality Level */
|
#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_MINIMUM 2
|
||||||
#define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
|
#define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
|
||||||
|
|
||||||
/* Logical representation of an ETX object in a DAG Metric Container. */
|
/* The bit index within the flags field of
|
||||||
struct rpl_metric_object_etx {
|
the rpl_metric_object_energy structure. */
|
||||||
uint16_t etx;
|
#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. */
|
/* Logical representation of a DAG Metric Container. */
|
||||||
|
@ -111,9 +132,10 @@ struct rpl_metric_container {
|
||||||
uint8_t aggr;
|
uint8_t aggr;
|
||||||
uint8_t prec;
|
uint8_t prec;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
/* Once we support more objects, the etx field will be replaced by a
|
union metric_object {
|
||||||
union of those. */
|
struct rpl_metric_object_energy energy;
|
||||||
struct rpl_metric_object_etx etx;
|
uint16_t etx;
|
||||||
|
} obj;
|
||||||
};
|
};
|
||||||
typedef struct rpl_metric_container rpl_metric_container_t;
|
typedef struct rpl_metric_container rpl_metric_container_t;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -125,7 +147,7 @@ struct rpl_parent {
|
||||||
rpl_metric_container_t mc;
|
rpl_metric_container_t mc;
|
||||||
uip_ipaddr_t addr;
|
uip_ipaddr_t addr;
|
||||||
rpl_rank_t rank;
|
rpl_rank_t rank;
|
||||||
uint8_t etx;
|
uint8_t link_metric;
|
||||||
uint8_t dtsn;
|
uint8_t dtsn;
|
||||||
uint8_t updated;
|
uint8_t updated;
|
||||||
};
|
};
|
||||||
|
|
|
@ -268,7 +268,7 @@ static uint8_t *hc06_ptr;
|
||||||
/* Uncompression of linklocal */
|
/* Uncompression of linklocal */
|
||||||
/* 0 -> 16 bytes from packet */
|
/* 0 -> 16 bytes from packet */
|
||||||
/* 1 -> 2 bytes from prefix - bunch of zeroes and 8 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 */
|
/* 3 -> 2 bytes from prefix - infer 8 bytes from lladdr */
|
||||||
/* NOTE: => the uncompress function does change 0xf to 0x10 */
|
/* NOTE: => the uncompress function does change 0xf to 0x10 */
|
||||||
/* NOTE: 0x00 => no-autoconfig => unspecified */
|
/* NOTE: 0x00 => no-autoconfig => unspecified */
|
||||||
|
@ -277,7 +277,7 @@ const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
|
||||||
/* Uncompression of ctx-based */
|
/* Uncompression of ctx-based */
|
||||||
/* 0 -> 0 bits from packet [unspecified / reserved] */
|
/* 0 -> 0 bits from packet [unspecified / reserved] */
|
||||||
/* 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet */
|
/* 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 */
|
/* 3 -> 8 bytes from prefix - infer 8 bytes from lladdr */
|
||||||
const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
|
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)) {
|
if(uip_is_addr_mac_addr_based(ipaddr, lladdr)) {
|
||||||
return 3 << bitpos; /* 0-bits */
|
return 3 << bitpos; /* 0-bits */
|
||||||
} else if(sicslowpan_is_iid_16_bit_compressable(ipaddr)) {
|
} 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);
|
memcpy(hc06_ptr, &ipaddr->u16[7], 2);
|
||||||
hc06_ptr += 2;
|
hc06_ptr += 2;
|
||||||
return 2 << bitpos; /* 16-bits */
|
return 2 << bitpos; /* 16-bits */
|
||||||
|
@ -377,6 +377,11 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
|
||||||
}
|
}
|
||||||
if(postcount > 0) {
|
if(postcount > 0) {
|
||||||
memcpy(&ipaddr->u8[16 - postcount], hc06_ptr, postcount);
|
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;
|
hc06_ptr += postcount;
|
||||||
} else if (prefcount > 0) {
|
} else if (prefcount > 0) {
|
||||||
/* no IID based configuration if no prefix and no data => unspec */
|
/* no IID based configuration if no prefix and no data => unspec */
|
||||||
|
|
|
@ -233,13 +233,15 @@ struct sicslowpan_addr_context {
|
||||||
* \brief check whether we can compress the IID in
|
* \brief check whether we can compress the IID in
|
||||||
* address 'a' to 16 bits.
|
* address 'a' to 16 bits.
|
||||||
* This is used for unicast addresses only, and is true
|
* 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) \
|
#define sicslowpan_is_iid_16_bit_compressable(a) \
|
||||||
((((a)->u16[4]) == 0) && \
|
((((a)->u16[4]) == 0) && \
|
||||||
(((a)->u16[5]) == 0) && \
|
(((a)->u8[10]) == 0)&& \
|
||||||
(((a)->u16[6]) == 0) && \
|
(((a)->u8[11]) == 0xff)&& \
|
||||||
((((a)->u8[14]) & 0x80) == 0))
|
(((a)->u8[12]) == 0xfe)&& \
|
||||||
|
(((a)->u8[13]) == 0))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief check whether the 9-bit group-id of the
|
* \brief check whether the 9-bit group-id of the
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* 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 "net/uip-debug.h"
|
||||||
#include <stdio.h>
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
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];
|
a = (addr->u8[i] << 8) + addr->u8[i + 1];
|
||||||
if(a == 0 && f >= 0) {
|
if(a == 0 && f >= 0) {
|
||||||
if(f++ == 0) {
|
if(f++ == 0) {
|
||||||
printf("::");
|
PRINTA("::");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(f > 0) {
|
if(f > 0) {
|
||||||
f = -1;
|
f = -1;
|
||||||
} else if(i > 0) {
|
} else if(i > 0) {
|
||||||
printf(":");
|
PRINTA(":");
|
||||||
}
|
}
|
||||||
printf("%x", a);
|
PRINTA("%x", a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* UIP_CONF_IPV6 */
|
#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 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -74,9 +73,9 @@ uip_debug_lladdr_print(const uip_lladdr_t *addr)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for(i = 0; i < sizeof(uip_lladdr_t); i++) {
|
for(i = 0; i < sizeof(uip_lladdr_t); i++) {
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
printf(":");
|
PRINTA(":");
|
||||||
}
|
}
|
||||||
printf("%02x", addr->addr[i]);
|
PRINTA("%02x", addr->addr[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#define UIP_DEBUG_H
|
#define UIP_DEBUG_H
|
||||||
|
|
||||||
#include "net/uip.h"
|
#include "net/uip.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
void uip_debug_ipaddr_print(const uip_ipaddr_t *addr);
|
void uip_debug_ipaddr_print(const uip_ipaddr_t *addr);
|
||||||
void uip_debug_lladdr_print(const uip_lladdr_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_ANNOTATE 2
|
||||||
#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT
|
#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
|
#if (DEBUG) & DEBUG_ANNOTATE
|
||||||
#include <stdio.h>
|
#ifdef __AVR__
|
||||||
|
#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
|
||||||
|
#else
|
||||||
#define ANNOTATE(...) printf(__VA_ARGS__)
|
#define ANNOTATE(...) printf(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define ANNOTATE(...)
|
#define ANNOTATE(...)
|
||||||
#endif /* (DEBUG) & DEBUG_ANNOTATE */
|
#endif /* (DEBUG) & DEBUG_ANNOTATE */
|
||||||
|
|
||||||
#if (DEBUG) & DEBUG_PRINT
|
#if (DEBUG) & DEBUG_PRINT
|
||||||
#include <stdio.h>
|
#ifdef __AVR__
|
||||||
|
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
|
||||||
|
#else
|
||||||
#define PRINTF(...) printf(__VA_ARGS__)
|
#define PRINTF(...) printf(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
#define PRINT6ADDR(addr) uip_debug_ipaddr_print(addr)
|
#define PRINT6ADDR(addr) uip_debug_ipaddr_print(addr)
|
||||||
#define PRINTLLADDR(lladdr) uip_debug_lladdr_print(lladdr)
|
#define PRINTLLADDR(lladdr) uip_debug_lladdr_print(lladdr)
|
||||||
#else
|
#else
|
||||||
|
|
203
core/net/uip-ds6.c
Executable file → Normal file
203
core/net/uip-ds6.c
Executable file → Normal file
|
@ -174,60 +174,60 @@ uip_ds6_periodic(void)
|
||||||
#if !UIP_CONF_ROUTER
|
#if !UIP_CONF_ROUTER
|
||||||
/* Periodic processing on prefixes */
|
/* Periodic processing on prefixes */
|
||||||
for(locprefix = uip_ds6_prefix_list;
|
for(locprefix = uip_ds6_prefix_list;
|
||||||
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
|
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB;
|
||||||
if((locprefix->isused) && (!locprefix->isinfinite)
|
locprefix++) {
|
||||||
&& (stimer_expired(&(locprefix->vlifetime)))) {
|
if(locprefix->isused && !locprefix->isinfinite
|
||||||
|
&& stimer_expired(&(locprefix->vlifetime))) {
|
||||||
uip_ds6_prefix_rm(locprefix);
|
uip_ds6_prefix_rm(locprefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !UIP_CONF_ROUTER */
|
#endif /* !UIP_CONF_ROUTER */
|
||||||
|
|
||||||
/* Periodic processing on neighbors */
|
/* 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++) {
|
locnbr++) {
|
||||||
if(locnbr->isused) {
|
if(locnbr->isused) {
|
||||||
switch (locnbr->state) {
|
switch(locnbr->state) {
|
||||||
case NBR_INCOMPLETE:
|
case NBR_INCOMPLETE:
|
||||||
if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
|
if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
|
||||||
uip_ds6_nbr_rm(locnbr);
|
uip_ds6_nbr_rm(locnbr);
|
||||||
} else if(stimer_expired(&(locnbr->sendns))) {
|
} else if(stimer_expired(&locnbr->sendns)) {
|
||||||
locnbr->nscount++;
|
locnbr->nscount++;
|
||||||
PRINTF("NBR_INCOMPLETE: NS %u\n", locnbr->nscount);
|
PRINTF("NBR_INCOMPLETE: NS %u\n", locnbr->nscount);
|
||||||
uip_nd6_ns_output(NULL, NULL, &locnbr->ipaddr);
|
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;
|
break;
|
||||||
case NBR_REACHABLE:
|
case NBR_REACHABLE:
|
||||||
if(stimer_expired(&(locnbr->reachable))) {
|
if(stimer_expired(&locnbr->reachable)) {
|
||||||
PRINTF("REACHABLE: moving to STALE (");
|
PRINTF("REACHABLE: moving to STALE (");
|
||||||
PRINT6ADDR(&locnbr->ipaddr);
|
PRINT6ADDR(&locnbr->ipaddr);
|
||||||
PRINTF(")\n");
|
PRINTF(")\n");
|
||||||
locnbr->state = NBR_STALE;
|
locnbr->state = NBR_STALE;
|
||||||
/* NEIGHBOR_STATE_CHANGED(locnbr); */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NBR_DELAY:
|
case NBR_DELAY:
|
||||||
if(stimer_expired(&(locnbr->reachable))) {
|
if(stimer_expired(&locnbr->reachable)) {
|
||||||
locnbr->state = NBR_PROBE;
|
locnbr->state = NBR_PROBE;
|
||||||
locnbr->nscount = 1;
|
locnbr->nscount = 1;
|
||||||
/* NEIGHBOR_STATE_CHANGED(locnbr); */
|
|
||||||
PRINTF("DELAY: moving to PROBE + NS %u\n", locnbr->nscount);
|
PRINTF("DELAY: moving to PROBE + NS %u\n", locnbr->nscount);
|
||||||
uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr);
|
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;
|
break;
|
||||||
case NBR_PROBE:
|
case NBR_PROBE:
|
||||||
if(locnbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
|
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) {
|
if((locdefrt = uip_ds6_defrt_lookup(&locnbr->ipaddr)) != NULL) {
|
||||||
uip_ds6_defrt_rm(locdefrt);
|
uip_ds6_defrt_rm(locdefrt);
|
||||||
}
|
}
|
||||||
uip_ds6_nbr_rm(locnbr);
|
uip_ds6_nbr_rm(locnbr);
|
||||||
} else if(stimer_expired(&(locnbr->sendns))) {
|
} else if(stimer_expired(&locnbr->sendns)) {
|
||||||
locnbr->nscount++;
|
locnbr->nscount++;
|
||||||
PRINTF("PROBE: NS %u\n", locnbr->nscount);
|
PRINTF("PROBE: NS %u\n", locnbr->nscount);
|
||||||
uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -248,9 +248,9 @@ uip_ds6_periodic(void)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uint8_t
|
uint8_t
|
||||||
uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size,
|
uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
|
||||||
uint16_t elementsize, uip_ipaddr_t * ipaddr,
|
uint16_t elementsize, uip_ipaddr_t *ipaddr,
|
||||||
uint8_t ipaddrlen, uip_ds6_element_t ** out_element)
|
uint8_t ipaddrlen, uip_ds6_element_t **out_element)
|
||||||
{
|
{
|
||||||
uip_ds6_element_t *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;
|
for(element = list;
|
||||||
element <
|
element <
|
||||||
(uip_ds6_element_t *) ((uint8_t *) list + (size * elementsize));
|
(uip_ds6_element_t *)((uint8_t *)list + (size * elementsize));
|
||||||
element = (uip_ds6_element_t *) ((uint8_t *) element + elementsize)) {
|
element = (uip_ds6_element_t *)((uint8_t *)element + elementsize)) {
|
||||||
// printf("+ %p %d\n", &element->isused, element->isused);
|
|
||||||
if(element->isused) {
|
if(element->isused) {
|
||||||
if(uip_ipaddr_prefixcmp(&(element->ipaddr), ipaddr, ipaddrlen)) {
|
if(uip_ipaddr_prefixcmp(&element->ipaddr, ipaddr, ipaddrlen)) {
|
||||||
*out_element = element;
|
*out_element = element;
|
||||||
return FOUND;
|
return FOUND;
|
||||||
}
|
}
|
||||||
|
@ -271,33 +270,28 @@ uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*out_element != NULL) {
|
return *out_element != NULL ? FREESPACE : NOSPACE;
|
||||||
return FREESPACE;
|
|
||||||
} else {
|
|
||||||
return NOSPACE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_nbr_t *
|
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)
|
uint8_t isrouter, uint8_t state)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = uip_ds6_list_loop
|
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,
|
sizeof(uip_ds6_nbr_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) &locnbr);
|
(uip_ds6_element_t **)&locnbr);
|
||||||
// printf("r %d\n", r);
|
|
||||||
|
|
||||||
if(r == FREESPACE) {
|
if(r == FREESPACE) {
|
||||||
locnbr->isused = 1;
|
locnbr->isused = 1;
|
||||||
uip_ipaddr_copy(&(locnbr->ipaddr), ipaddr);
|
uip_ipaddr_copy(&locnbr->ipaddr, ipaddr);
|
||||||
if(lladdr != NULL) {
|
if(lladdr != NULL) {
|
||||||
memcpy(&(locnbr->lladdr), lladdr, UIP_LLADDR_LEN);
|
memcpy(&locnbr->lladdr, lladdr, UIP_LLADDR_LEN);
|
||||||
} else {
|
} else {
|
||||||
memset(&(locnbr->lladdr), 0, UIP_LLADDR_LEN);
|
memset(&locnbr->lladdr, 0, UIP_LLADDR_LEN);
|
||||||
}
|
}
|
||||||
locnbr->isrouter = isrouter;
|
locnbr->isrouter = isrouter;
|
||||||
locnbr->state = state;
|
locnbr->state = state;
|
||||||
|
@ -305,18 +299,17 @@ uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr,
|
||||||
uip_packetqueue_new(&locnbr->packethandle);
|
uip_packetqueue_new(&locnbr->packethandle);
|
||||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||||
/* timers are set separately, for now we put them in expired state */
|
/* timers are set separately, for now we put them in expired state */
|
||||||
stimer_set(&(locnbr->reachable), 0);
|
stimer_set(&locnbr->reachable, 0);
|
||||||
stimer_set(&(locnbr->sendns), 0);
|
stimer_set(&locnbr->sendns, 0);
|
||||||
locnbr->nscount = 0;
|
locnbr->nscount = 0;
|
||||||
PRINTF("Adding neighbor with ip addr");
|
PRINTF("Adding neighbor with ip addr ");
|
||||||
PRINT6ADDR(ipaddr);
|
PRINT6ADDR(ipaddr);
|
||||||
PRINTF("link addr");
|
PRINTF("link addr ");
|
||||||
PRINTLLADDR((&(locnbr->lladdr)));
|
PRINTLLADDR((&(locnbr->lladdr)));
|
||||||
PRINTF("state %u\n", state);
|
PRINTF("state %u\n", state);
|
||||||
NEIGHBOR_STATE_CHANGED(locnbr);
|
NEIGHBOR_STATE_CHANGED(locnbr);
|
||||||
|
|
||||||
locnbr->last_lookup = clock_time();
|
locnbr->last_lookup = clock_time();
|
||||||
// printf("add %p\n", locnbr);
|
|
||||||
return locnbr;
|
return locnbr;
|
||||||
} else if(r == NOSPACE) {
|
} else if(r == NOSPACE) {
|
||||||
/* We did not find any empty slot on the neighbor list, so we need
|
/* 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) {
|
if(oldest != NULL) {
|
||||||
// printf("rm3\n");
|
|
||||||
uip_ds6_nbr_rm(oldest);
|
uip_ds6_nbr_rm(oldest);
|
||||||
return uip_ds6_nbr_add(ipaddr, lladdr, isrouter, state);
|
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) {
|
if(nbr != NULL) {
|
||||||
nbr->isused = 0;
|
nbr->isused = 0;
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
// printf("rm %p\n", &nbr->isused);
|
|
||||||
uip_packetqueue_free(&nbr->packethandle);
|
uip_packetqueue_free(&nbr->packethandle);
|
||||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||||
NEIGHBOR_STATE_CHANGED(nbr);
|
NEIGHBOR_STATE_CHANGED(nbr);
|
||||||
|
@ -367,9 +358,9 @@ uip_ds6_nbr_t *
|
||||||
uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr)
|
uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr)
|
||||||
{
|
{
|
||||||
if(uip_ds6_list_loop
|
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,
|
sizeof(uip_ds6_nbr_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) & locnbr) == FOUND) {
|
(uip_ds6_element_t **)&locnbr) == FOUND) {
|
||||||
return locnbr;
|
return locnbr;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -380,19 +371,19 @@ uip_ds6_defrt_t *
|
||||||
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
|
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
|
||||||
{
|
{
|
||||||
if(uip_ds6_list_loop
|
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,
|
sizeof(uip_ds6_defrt_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) & locdefrt) == FREESPACE) {
|
(uip_ds6_element_t **)&locdefrt) == FREESPACE) {
|
||||||
locdefrt->isused = 1;
|
locdefrt->isused = 1;
|
||||||
uip_ipaddr_copy(&(locdefrt->ipaddr), ipaddr);
|
uip_ipaddr_copy(&locdefrt->ipaddr, ipaddr);
|
||||||
if(interval != 0) {
|
if(interval != 0) {
|
||||||
stimer_set(&(locdefrt->lifetime), interval);
|
stimer_set(&locdefrt->lifetime, interval);
|
||||||
locdefrt->isinfinite = 0;
|
locdefrt->isinfinite = 0;
|
||||||
} else {
|
} else {
|
||||||
locdefrt->isinfinite = 1;
|
locdefrt->isinfinite = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINTF("Adding defrouter with ip addr");
|
PRINTF("Adding defrouter with ip addr ");
|
||||||
PRINT6ADDR(&locdefrt->ipaddr);
|
PRINT6ADDR(&locdefrt->ipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
|
||||||
|
@ -405,7 +396,7 @@ uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_ds6_defrt_rm(uip_ds6_defrt_t * defrt)
|
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
|
||||||
{
|
{
|
||||||
if(defrt != NULL) {
|
if(defrt != NULL) {
|
||||||
defrt->isused = 0;
|
defrt->isused = 0;
|
||||||
|
@ -416,11 +407,11 @@ uip_ds6_defrt_rm(uip_ds6_defrt_t * defrt)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_defrt_t *
|
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_DEFRT_NB, sizeof(uip_ds6_defrt_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) & locdefrt) == FOUND) {
|
(uip_ds6_element_t **)&locdefrt) == FOUND) {
|
||||||
return locdefrt;
|
return locdefrt;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -440,7 +431,7 @@ uip_ds6_defrt_choose(void)
|
||||||
PRINT6ADDR(&locdefrt->ipaddr);
|
PRINT6ADDR(&locdefrt->ipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
bestnbr = uip_ds6_nbr_lookup(&locdefrt->ipaddr);
|
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 ");
|
PRINTF("Defrt found, IP address ");
|
||||||
PRINT6ADDR(&locdefrt->ipaddr);
|
PRINT6ADDR(&locdefrt->ipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
@ -459,16 +450,16 @@ uip_ds6_defrt_choose(void)
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_prefix_t *
|
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,
|
uint8_t advertise, uint8_t flags, unsigned long vtime,
|
||||||
unsigned long ptime)
|
unsigned long ptime)
|
||||||
{
|
{
|
||||||
if(uip_ds6_list_loop
|
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,
|
sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen,
|
||||||
(uip_ds6_element_t **) & locprefix) == FREESPACE) {
|
(uip_ds6_element_t **)&locprefix) == FREESPACE) {
|
||||||
locprefix->isused = 1;
|
locprefix->isused = 1;
|
||||||
uip_ipaddr_copy(&(locprefix->ipaddr), ipaddr);
|
uip_ipaddr_copy(&locprefix->ipaddr, ipaddr);
|
||||||
locprefix->length = ipaddrlen;
|
locprefix->length = ipaddrlen;
|
||||||
locprefix->advertise = advertise;
|
locprefix->advertise = advertise;
|
||||||
locprefix->l_a_reserved = flags;
|
locprefix->l_a_reserved = flags;
|
||||||
|
@ -488,15 +479,15 @@ uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen,
|
||||||
|
|
||||||
#else /* UIP_CONF_ROUTER */
|
#else /* UIP_CONF_ROUTER */
|
||||||
uip_ds6_prefix_t *
|
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)
|
unsigned long interval)
|
||||||
{
|
{
|
||||||
if(uip_ds6_list_loop
|
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,
|
sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen,
|
||||||
(uip_ds6_element_t **) & locprefix) == FREESPACE) {
|
(uip_ds6_element_t **)&locprefix) == FREESPACE) {
|
||||||
locprefix->isused = 1;
|
locprefix->isused = 1;
|
||||||
uip_ipaddr_copy(&(locprefix->ipaddr), ipaddr);
|
uip_ipaddr_copy(&locprefix->ipaddr, ipaddr);
|
||||||
locprefix->length = ipaddrlen;
|
locprefix->length = ipaddrlen;
|
||||||
if(interval != 0) {
|
if(interval != 0) {
|
||||||
stimer_set(&(locprefix->vlifetime), interval);
|
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_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,
|
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_prefix_list,
|
||||||
UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix_t),
|
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
|
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;
|
for(locprefix = uip_ds6_prefix_list;
|
||||||
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
|
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_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
|
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,
|
sizeof(uip_ds6_addr_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) & locaddr) == FREESPACE) {
|
(uip_ds6_element_t **)&locaddr) == FREESPACE) {
|
||||||
locaddr->isused = 1;
|
locaddr->isused = 1;
|
||||||
uip_ipaddr_copy(&locaddr->ipaddr, ipaddr);
|
uip_ipaddr_copy(&locaddr->ipaddr, ipaddr);
|
||||||
locaddr->state = ADDR_TENTATIVE;
|
locaddr->state = ADDR_TENTATIVE;
|
||||||
|
@ -579,7 +570,7 @@ uip_ds6_addr_add(uip_ipaddr_t * ipaddr, unsigned long vlifetime, uint8_t type)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_ds6_addr_rm(uip_ds6_addr_t * addr)
|
uip_ds6_addr_rm(uip_ds6_addr_t *addr)
|
||||||
{
|
{
|
||||||
if(addr != NULL) {
|
if(addr != NULL) {
|
||||||
uip_create_solicited_node(&addr->ipaddr, &loc_fipaddr);
|
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_t *
|
||||||
uip_ds6_addr_lookup(uip_ipaddr_t * ipaddr)
|
uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr)
|
||||||
{
|
{
|
||||||
if(uip_ds6_list_loop
|
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,
|
sizeof(uip_ds6_addr_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) & locaddr) == FOUND) {
|
(uip_ds6_element_t **)&locaddr) == FOUND) {
|
||||||
return locaddr;
|
return locaddr;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -615,7 +606,7 @@ uip_ds6_get_link_local(int8_t state)
|
||||||
{
|
{
|
||||||
for(locaddr = uip_ds6_if.addr_list;
|
for(locaddr = uip_ds6_if.addr_list;
|
||||||
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
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))) {
|
&& (uip_is_addr_link_local(&locaddr->ipaddr))) {
|
||||||
return locaddr;
|
return locaddr;
|
||||||
}
|
}
|
||||||
|
@ -634,7 +625,7 @@ uip_ds6_get_global(int8_t state)
|
||||||
{
|
{
|
||||||
for(locaddr = uip_ds6_if.addr_list;
|
for(locaddr = uip_ds6_if.addr_list;
|
||||||
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
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))) {
|
&& !(uip_is_addr_link_local(&locaddr->ipaddr))) {
|
||||||
return locaddr;
|
return locaddr;
|
||||||
}
|
}
|
||||||
|
@ -644,12 +635,12 @@ uip_ds6_get_global(int8_t state)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_maddr_t *
|
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
|
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,
|
sizeof(uip_ds6_maddr_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) & locmaddr) == FREESPACE) {
|
(uip_ds6_element_t **)&locmaddr) == FREESPACE) {
|
||||||
locmaddr->isused = 1;
|
locmaddr->isused = 1;
|
||||||
uip_ipaddr_copy(&locmaddr->ipaddr, ipaddr);
|
uip_ipaddr_copy(&locmaddr->ipaddr, ipaddr);
|
||||||
return locmaddr;
|
return locmaddr;
|
||||||
|
@ -669,12 +660,12 @@ uip_ds6_maddr_rm(uip_ds6_maddr_t * maddr)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_maddr_t *
|
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
|
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,
|
sizeof(uip_ds6_maddr_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) & locmaddr) == FOUND) {
|
(uip_ds6_element_t **)&locmaddr) == FOUND) {
|
||||||
return locmaddr;
|
return locmaddr;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -683,12 +674,12 @@ uip_ds6_maddr_lookup(uip_ipaddr_t * ipaddr)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_aaddr_t *
|
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
|
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,
|
sizeof(uip_ds6_aaddr_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **) & locaaddr) == FREESPACE) {
|
(uip_ds6_element_t **)&locaaddr) == FREESPACE) {
|
||||||
locaaddr->isused = 1;
|
locaaddr->isused = 1;
|
||||||
uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr);
|
uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr);
|
||||||
return locaaddr;
|
return locaaddr;
|
||||||
|
@ -708,9 +699,9 @@ uip_ds6_aaddr_rm(uip_ds6_aaddr_t * aaddr)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_aaddr_t *
|
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_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128,
|
||||||
(uip_ds6_element_t **)&locaaddr) == FOUND) {
|
(uip_ds6_element_t **)&locaaddr) == FOUND) {
|
||||||
return locaaddr;
|
return locaaddr;
|
||||||
|
@ -720,12 +711,12 @@ uip_ds6_aaddr_lookup(uip_ipaddr_t * ipaddr)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_route_t *
|
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;
|
uip_ds6_route_t *locrt = NULL;
|
||||||
uint8_t longestmatch = 0;
|
uint8_t longestmatch = 0;
|
||||||
|
|
||||||
PRINTF("DS6: Looking up route for");
|
PRINTF("DS6: Looking up route for ");
|
||||||
PRINT6ADDR(destipaddr);
|
PRINT6ADDR(destipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
|
||||||
|
@ -747,7 +738,7 @@ uip_ds6_route_lookup(uip_ipaddr_t * destipaddr)
|
||||||
PRINT6ADDR(&locrt->nexthop);
|
PRINT6ADDR(&locrt->nexthop);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
} else {
|
} else {
|
||||||
PRINTF("DS6: No route found ...\n");
|
PRINTF("DS6: No route found\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return locrt;
|
return locrt;
|
||||||
|
@ -755,27 +746,25 @@ uip_ds6_route_lookup(uip_ipaddr_t * destipaddr)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_route_t *
|
uip_ds6_route_t *
|
||||||
uip_ds6_route_add(uip_ipaddr_t * ipaddr, u8_t length, uip_ipaddr_t * nexthop,
|
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop,
|
||||||
u8_t metric)
|
uint8_t metric)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(uip_ds6_list_loop
|
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,
|
sizeof(uip_ds6_route_t), ipaddr, length,
|
||||||
(uip_ds6_element_t **) & locroute) == FREESPACE) {
|
(uip_ds6_element_t **)&locroute) == FREESPACE) {
|
||||||
locroute->isused = 1;
|
locroute->isused = 1;
|
||||||
uip_ipaddr_copy(&(locroute->ipaddr), ipaddr);
|
uip_ipaddr_copy(&(locroute->ipaddr), ipaddr);
|
||||||
locroute->length = length;
|
locroute->length = length;
|
||||||
uip_ipaddr_copy(&(locroute->nexthop), nexthop);
|
uip_ipaddr_copy(&(locroute->nexthop), nexthop);
|
||||||
locroute->metric = metric;
|
locroute->metric = metric;
|
||||||
|
|
||||||
PRINTF("DS6: adding route:");
|
PRINTF("DS6: adding route: ");
|
||||||
PRINT6ADDR(ipaddr);
|
PRINT6ADDR(ipaddr);
|
||||||
PRINTF(" via ");
|
PRINTF(" via ");
|
||||||
PRINT6ADDR(nexthop);
|
PRINT6ADDR(nexthop);
|
||||||
PRINTF("\n");
|
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;
|
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" */
|
/* we need to check if this was the last route towards "nexthop" */
|
||||||
/* if so - remove that link (annotation) */
|
/* if so - remove that link (annotation) */
|
||||||
for(locroute = uip_ds6_routing_table;
|
for(locroute = uip_ds6_routing_table;
|
||||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
|
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
|
||||||
if((locroute->isused) && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
|
locroute++) {
|
||||||
/* we did find another link using the specific nexthop, so keep the #L */
|
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
|
||||||
|
/* we found another link using the specific nexthop, so keep the #L */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,8 +794,9 @@ void
|
||||||
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
|
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
|
||||||
{
|
{
|
||||||
for(locroute = uip_ds6_routing_table;
|
for(locroute = uip_ds6_routing_table;
|
||||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
|
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
|
||||||
if((locroute->isused) && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
|
locroute++) {
|
||||||
|
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
|
||||||
locroute->isused = 0;
|
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;
|
for(locaddr = uip_ds6_if.addr_list;
|
||||||
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
||||||
/* Only preferred global (not link-local) addresses */
|
/* Only preferred global (not link-local) addresses */
|
||||||
if((locaddr->isused) && (locaddr->state == ADDR_PREFERRED) &&
|
if(locaddr->isused && locaddr->state == ADDR_PREFERRED &&
|
||||||
(!uip_is_addr_link_local(&locaddr->ipaddr))) {
|
!uip_is_addr_link_local(&locaddr->ipaddr)) {
|
||||||
n = get_match_length(dst, &(locaddr->ipaddr));
|
n = get_match_length(dst, &locaddr->ipaddr);
|
||||||
if(n >= best) {
|
if(n >= best) {
|
||||||
best = n;
|
best = n;
|
||||||
matchaddr = locaddr;
|
matchaddr = locaddr;
|
||||||
|
@ -848,7 +839,7 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
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
|
/* We consider only links with IEEE EUI-64 identifier or
|
||||||
* IEEE 48-bit MAC addresses */
|
* 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);
|
memcpy(ipaddr->u8 + 8, lladdr, 3);
|
||||||
ipaddr->u8[11] = 0xff;
|
ipaddr->u8[11] = 0xff;
|
||||||
ipaddr->u8[12] = 0xfe;
|
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;
|
ipaddr->u8[8] ^= 0x02;
|
||||||
#else
|
#else
|
||||||
#error uip-ds6.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
|
#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
|
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 j, k, x_or;
|
||||||
uint8_t len = 0;
|
uint8_t len = 0;
|
||||||
|
@ -894,7 +885,7 @@ get_match_length(uip_ipaddr_t * src, uip_ipaddr_t * dst)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_ds6_dad(uip_ds6_addr_t * addr)
|
uip_ds6_dad(uip_ds6_addr_t *addr)
|
||||||
{
|
{
|
||||||
/* send maxdadns NS for DAD */
|
/* send maxdadns NS for DAD */
|
||||||
if(addr->dadnscount < uip_ds6_if.maxdadns) {
|
if(addr->dadnscount < uip_ds6_if.maxdadns) {
|
||||||
|
|
2
core/net/uip-ds6.h
Executable file → Normal file
2
core/net/uip-ds6.h
Executable file → Normal 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_lookup(uip_ipaddr_t *destipaddr);
|
||||||
uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
|
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(uip_ds6_route_t *route);
|
||||||
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
|
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
|
||||||
|
|
||||||
|
|
|
@ -53,15 +53,17 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
||||||
|
|
||||||
value = 0;
|
value = 0;
|
||||||
zero = -1;
|
zero = -1;
|
||||||
|
if(*addrstr == '[') addrstr++;
|
||||||
|
|
||||||
for(len = 0; len < sizeof(uip_ipaddr_t) - 1; addrstr++) {
|
for(len = 0; len < sizeof(uip_ipaddr_t) - 1; addrstr++) {
|
||||||
c = *addrstr;
|
c = *addrstr;
|
||||||
if(c == ':' || c == '\0') {
|
if(c == ':' || c == '\0' || c == ']') {
|
||||||
ipaddr->u8[len] = (value >> 8) & 0xff;
|
ipaddr->u8[len] = (value >> 8) & 0xff;
|
||||||
ipaddr->u8[len + 1] = value & 0xff;
|
ipaddr->u8[len + 1] = value & 0xff;
|
||||||
len += 2;
|
len += 2;
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|
||||||
if(c == '\0') {
|
if(c == '\0' || c == ']') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +88,7 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
||||||
value = (value << 4) + (tmp & 0xf);
|
value = (value << 4) + (tmp & 0xf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c != '\0') {
|
if(c != '\0' && c != ']') {
|
||||||
PRINTF("uiplib: too large address\n");
|
PRINTF("uiplib: too large address\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ ifndef NOAVRSIZE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
%.hex: %.out
|
%.hex: %.out
|
||||||
$(OBJCOPY) $^ -O ihex $@
|
$(OBJCOPY) $^ -j .text -j .data -O ihex $@
|
||||||
|
|
||||||
%.ihex: %.out
|
%.ihex: %.out
|
||||||
$(OBJCOPY) $^ -O ihex $@
|
$(OBJCOPY) $^ -O ihex $@
|
||||||
|
|
|
@ -15,12 +15,23 @@ long sleepseconds;
|
||||||
#if RF230BB && WEBSERVER
|
#if RF230BB && WEBSERVER
|
||||||
#define RADIOSTATS 1
|
#define RADIOSTATS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RADIOSTATS
|
#if RADIOSTATS
|
||||||
static volatile uint8_t rcount;
|
static volatile uint8_t rcount;
|
||||||
volatile unsigned long radioontime;
|
volatile unsigned long radioontime;
|
||||||
extern uint8_t RF230_receive_on;
|
extern uint8_t RF230_receive_on;
|
||||||
#endif
|
#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.
|
CLOCK_SECOND is the number of ticks per second.
|
||||||
It is defined through CONF_CLOCK_SECOND in the contiki-conf.h for each platform.
|
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
|
#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)
|
//SIGNAL(SIG_OUTPUT_COMPARE0)
|
||||||
ISR(AVR_OUTPUT_COMPARE_INT)
|
ISR(AVR_OUTPUT_COMPARE_INT)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if(++scount == CLOCK_SECOND) {
|
if(++scount == CLOCK_SECOND) {
|
||||||
scount = 0;
|
scount = 0;
|
||||||
increment_seconds();
|
seconds++;
|
||||||
// seconds++;
|
|
||||||
}
|
}
|
||||||
|
#if RADIOCALIBRATE
|
||||||
|
if (++calibrate_interval==0) {
|
||||||
|
rf230_calibrate=1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if RADIOSTATS
|
#if RADIOSTATS
|
||||||
if (RF230_receive_on) {
|
if (RF230_receive_on) {
|
||||||
if (++rcount == CLOCK_SECOND) {
|
if (++rcount == CLOCK_SECOND) {
|
||||||
rcount=0;
|
rcount=0;
|
||||||
increment_radioontime();
|
radioontime++;
|
||||||
// radioontime++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* gcc will save all registers on the stack if an external routine is called */
|
||||||
if(etimer_pending()) {
|
if(etimer_pending()) {
|
||||||
etimer_request_poll();
|
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);
|
} while(tmp != seconds);
|
||||||
return tmp;
|
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
31
cpu/avr/dev/uart1.h
Normal 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
|
|
@ -73,6 +73,12 @@
|
||||||
#define RG_CSMA_BE CSMA_BE
|
#define RG_CSMA_BE CSMA_BE
|
||||||
#define RG_CSMA_SEED_0 CSMA_SEED_0
|
#define RG_CSMA_SEED_0 CSMA_SEED_0
|
||||||
#define RG_PHY_RSSI PHY_RSSI
|
#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 */
|
/* RF230 register assignments, for reference */
|
||||||
|
|
|
@ -148,9 +148,12 @@ struct timestamp {
|
||||||
#if RADIOSTATS
|
#if RADIOSTATS
|
||||||
uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
|
uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if RADIOCALIBRATE
|
||||||
/* Set in clock.c every 256 seconds */
|
/* Set in clock.c every 256 seconds */
|
||||||
uint8_t rf230_calibrate;
|
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 */
|
/* Track flow through driver, see contiki-raven-main.c for example of use */
|
||||||
//#define DEBUGFLOWSIZE 64
|
//#define DEBUGFLOWSIZE 64
|
||||||
|
@ -206,8 +209,7 @@ static int rf230_receiving_packet(void);
|
||||||
static int pending_packet(void);
|
static int pending_packet(void);
|
||||||
static int rf230_cca(void);
|
static int rf230_cca(void);
|
||||||
|
|
||||||
signed char rf230_last_rssi;
|
uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
|
||||||
uint8_t rf230_last_correlation;
|
|
||||||
|
|
||||||
const struct radio_driver rf230_driver =
|
const struct radio_driver rf230_driver =
|
||||||
{
|
{
|
||||||
|
@ -700,6 +702,27 @@ rf230_init(void)
|
||||||
PRINTF("rf230: Unsupported manufacturer ID %u\n",tmanu);
|
PRINTF("rf230: Unsupported manufacturer ID %u\n",tmanu);
|
||||||
|
|
||||||
PRINTF("rf230: Version %u, ID %u\n",tvers,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);
|
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 */
|
/* 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(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 );
|
// 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 */
|
/* Use automatic CRC unless manual is specified */
|
||||||
#if RF230_CONF_CHECKSUM
|
#if RF230_CONF_CHECKSUM
|
||||||
hal_subregister_write(SR_TX_AUTO_CRC_ON, 0);
|
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);
|
hal_subregister_write(SR_TX_AUTO_CRC_ON, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Start the packet receive process */
|
|
||||||
process_start(&rf230_process, NULL);
|
|
||||||
|
|
||||||
/* Limit tx power for testing miniature Raven mesh */
|
/* Limit tx power for testing miniature Raven mesh */
|
||||||
#ifdef RF230_MAX_TX_POWER
|
#ifdef RF230_MAX_TX_POWER
|
||||||
set_txpower(RF230_MAX_TX_POWER); //0=3dbm 15=-17.2dbm
|
set_txpower(RF230_MAX_TX_POWER); //0=3dbm 15=-17.2dbm
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Leave radio in on state (?)*/
|
|
||||||
on();
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH+AUX_LEN];
|
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);
|
// delay_us(TIME_SLEEP_TO_TRX_OFF);
|
||||||
RF230_sleeping=0;
|
RF230_sleeping=0;
|
||||||
} else {
|
} else {
|
||||||
|
#if RADIOCALIBRATE
|
||||||
/* If on, do periodic calibration. See clock.c */
|
/* If on, do periodic calibration. See clock.c */
|
||||||
if (rf230_calibrate) {
|
if (rf230_calibrate) {
|
||||||
hal_subregister_write(SR_PLL_CF_START,1); //takes 80us max
|
hal_subregister_write(SR_PLL_CF_START,1); //takes 80us max
|
||||||
|
@ -766,6 +799,7 @@ rf230_transmit(unsigned short payload_len)
|
||||||
rf230_calibrated=1;
|
rf230_calibrated=1;
|
||||||
delay_us(80); //?
|
delay_us(80); //?
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for any previous operation or state transition to finish */
|
/* Wait for any previous operation or state transition to finish */
|
||||||
|
@ -878,7 +912,6 @@ rf230_transmit(unsigned short payload_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
RELEASE_LOCK();
|
RELEASE_LOCK();
|
||||||
|
|
||||||
if (tx_result==1) { //success, data pending from adressee
|
if (tx_result==1) { //success, data pending from adressee
|
||||||
tx_result=0; //Just show success?
|
tx_result=0; //Just show success?
|
||||||
} else if (tx_result==3) { //CSMA channel access failure
|
} else if (tx_result==3) { //CSMA channel access failure
|
||||||
|
@ -1327,6 +1360,10 @@ if (RF230_receive_on) {
|
||||||
#endif
|
#endif
|
||||||
#endif /* speed vs. generality */
|
#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;
|
// rf230_last_correlation = rxframe[rxframe_head].lqi;
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf230_last_rssi);
|
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf230_last_rssi);
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf230_last_correlation);
|
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf230_last_correlation);
|
||||||
|
@ -1446,9 +1483,17 @@ rf230_cca(void)
|
||||||
rf230_on();
|
rf230_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
// cca = CCA_IS_1;
|
|
||||||
DEBUGFLOW('c');
|
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) {
|
if(radio_was_off) {
|
||||||
rf230_off();
|
rf230_off();
|
||||||
|
@ -1476,4 +1521,46 @@ pending_packet(void)
|
||||||
return pending;
|
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
|
|
@ -202,6 +202,8 @@ typedef void (*radio_rx_callback) (uint16_t data);
|
||||||
const struct radio_driver rf230_driver;
|
const struct radio_driver rf230_driver;
|
||||||
|
|
||||||
int rf230_init(void);
|
int rf230_init(void);
|
||||||
|
void rf230_warm_reset(void);
|
||||||
|
void rf230_start_sneeze(void);
|
||||||
//int rf230_on(void);
|
//int rf230_on(void);
|
||||||
//int rf230_off(void);
|
//int rf230_off(void);
|
||||||
void rf230_set_channel(uint8_t channel);
|
void rf230_set_channel(uint8_t channel);
|
||||||
|
@ -214,8 +216,7 @@ uint8_t rf230_get_txpower(void);
|
||||||
void rf230_set_promiscuous_mode(bool isPromiscuous);
|
void rf230_set_promiscuous_mode(bool isPromiscuous);
|
||||||
bool rf230_is_ready_to_send();
|
bool rf230_is_ready_to_send();
|
||||||
|
|
||||||
extern signed char rf230_last_rssi;
|
extern uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
|
||||||
extern uint8_t rf230_last_correlation;
|
|
||||||
|
|
||||||
uint8_t rf230_get_raw_rssi(void);
|
uint8_t rf230_get_raw_rssi(void);
|
||||||
|
|
||||||
|
|
|
@ -28,45 +28,92 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* 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 "dev/watchdog.h"
|
||||||
#include <avr/wdt.h>
|
#include <avr/wdt.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#if WATCHDOG_CONF_BALANCE && WATCHDOG_CONF_TIMEOUT >= 0
|
||||||
static int stopped = 0;
|
static int stopped = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_init(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);
|
MCUSR&=~(1<<WDRF);
|
||||||
stopped = 0;
|
wdt_disable();
|
||||||
watchdog_stop();
|
#if WATCHDOG_CONF_BALANCE && WATCHDOG_CONF_TIMEOUT >= 0
|
||||||
|
stopped = 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_start(void)
|
watchdog_start(void)
|
||||||
{
|
{
|
||||||
|
#if WATCHDOG_CONF_TIMEOUT >= 0
|
||||||
|
#if WATCHDOG_CONF_BALANCE
|
||||||
stopped--;
|
stopped--;
|
||||||
// if(!stopped)
|
if(!stopped)
|
||||||
wdt_enable(WDTO_2S);
|
#endif
|
||||||
|
wdt_enable(WATCHDOG_CONF_TIMEOUT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_periodic(void)
|
watchdog_periodic(void)
|
||||||
{
|
{
|
||||||
// if(!stopped)
|
#if WATCHDOG_CONF_TIMEOUT >= 0
|
||||||
|
#if WATCHDOG_CONF_BALANCE
|
||||||
|
if(!stopped)
|
||||||
|
#endif
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_stop(void)
|
watchdog_stop(void)
|
||||||
{
|
{
|
||||||
// stopped++;
|
#if WATCHDOG_CONF_TIMEOUT >= 0
|
||||||
|
#if WATCHDOG_CONF_BALANCE
|
||||||
|
stopped++;
|
||||||
|
#endif
|
||||||
wdt_disable();
|
wdt_disable();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -77,3 +124,9 @@ watchdog_reboot(void)
|
||||||
while(1); //loop
|
while(1); //loop
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if 0
|
||||||
|
/* Not all AVRs implement the wdt interrupt */
|
||||||
|
ISR(WDT_vect)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -72,7 +72,12 @@ CUSTOM_RULE_C_TO_O=yes
|
||||||
CFLAGS += -I$(OBJECTDIR) -I$(CONTIKI_CPU)/board -DBOARD=$(TARGET)
|
CFLAGS += -I$(OBJECTDIR) -I$(CONTIKI_CPU)/board -DBOARD=$(TARGET)
|
||||||
|
|
||||||
$(OBJECTDIR)/board.h: $(OBJECTDIR)
|
$(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
|
ln -sf ../$(CONTIKI_CPU)/board/$(TARGET).h $(OBJECTDIR)/board.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
$(OBJECTDIR)/isr.o: $(CONTIKI_CPU)/src/isr.c
|
$(OBJECTDIR)/isr.o: $(CONTIKI_CPU)/src/isr.c
|
||||||
|
@ -85,8 +90,6 @@ $(OBJECTDIR)/%.o: %.c
|
||||||
$(CC) $(CFLAGS) $(THUMB_FLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) $(THUMB_FLAGS) -c $< -o $@
|
||||||
|
|
||||||
CUSTOM_RULE_S_TO_OBJECTDIR_O = yes
|
CUSTOM_RULE_S_TO_OBJECTDIR_O = yes
|
||||||
%.o: %.S
|
|
||||||
$(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c
|
|
||||||
|
|
||||||
$(OBJECTDIR)/%.o: %.S
|
$(OBJECTDIR)/%.o: %.S
|
||||||
$(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c -o $@
|
$(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c -o $@
|
||||||
|
|
138
cpu/mc1322x/lib/adc.c
Normal file
138
cpu/mc1322x/lib/adc.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
cpu/mc1322x/lib/gpio-util.c
Normal file
63
cpu/mc1322x/lib/gpio-util.c
Normal 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;
|
||||||
|
}
|
164
cpu/mc1322x/lib/include/adc.h
Normal file
164
cpu/mc1322x/lib/include/adc.h
Normal 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
|
116
cpu/mc1322x/lib/include/asm.h
Normal file
116
cpu/mc1322x/lib/include/asm.h
Normal 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
|
|
@ -220,6 +220,11 @@ struct CRM_struct {
|
||||||
|
|
||||||
static volatile struct CRM_struct * const CRM = (void *) (CRM_BASE);
|
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 */
|
/* Old register definitions, for compatibility */
|
||||||
#ifndef REG_NO_COMPAT
|
#ifndef REG_NO_COMPAT
|
||||||
|
|
28
cpu/mc1322x/lib/include/gpio-util.h
Normal file
28
cpu/mc1322x/lib/include/gpio-util.h
Normal 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
|
|
@ -166,5 +166,7 @@ extern void uart1_isr(void) __attribute__((weak));
|
||||||
|
|
||||||
extern void maca_isr(void) __attribute__((weak));
|
extern void maca_isr(void) __attribute__((weak));
|
||||||
|
|
||||||
|
extern void asm_isr(void) __attribute__((weak));
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -121,8 +121,8 @@ enum {
|
||||||
#define LFSR 6 /* 1 use polynomial for Turbolink */
|
#define LFSR 6 /* 1 use polynomial for Turbolink */
|
||||||
#define TM 5
|
#define TM 5
|
||||||
|
|
||||||
#define MODE 3
|
#define MACA_MODE 3
|
||||||
#define MODE_MASK bit_mask(2,MODE)
|
#define MODE_MASK bit_mask(2,MACA_MODE)
|
||||||
#define NO_CCA 0
|
#define NO_CCA 0
|
||||||
#define NO_SLOT_CCA 1
|
#define NO_SLOT_CCA 1
|
||||||
#define SLOT_CCA 2
|
#define SLOT_CCA 2
|
||||||
|
|
|
@ -46,5 +46,6 @@
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "uart1.h"
|
#include "uart1.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "asm.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
67
cpu/mc1322x/lib/include/pwm.h
Normal file
67
cpu/mc1322x/lib/include/pwm.h
Normal 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
|
57
cpu/mc1322x/lib/include/rtc.h
Normal file
57
cpu/mc1322x/lib/include/rtc.h
Normal 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
|
|
@ -184,7 +184,7 @@ void maca_init(void) {
|
||||||
/* nop, promiscuous, no cca */
|
/* nop, promiscuous, no cca */
|
||||||
*MACA_CONTROL =
|
*MACA_CONTROL =
|
||||||
(prm_mode << PRM) |
|
(prm_mode << PRM) |
|
||||||
(NO_CCA << MODE);
|
(NO_CCA << MACA_MODE);
|
||||||
|
|
||||||
enable_irq(MACA);
|
enable_irq(MACA);
|
||||||
*INTFRC = (1 << INT_NUM_MACA);
|
*INTFRC = (1 << INT_NUM_MACA);
|
||||||
|
@ -368,7 +368,9 @@ void post_receive(void) {
|
||||||
( 4 << PRECOUNT) |
|
( 4 << PRECOUNT) |
|
||||||
( fcs_mode << NOFC ) |
|
( fcs_mode << NOFC ) |
|
||||||
( prm_mode << PRM) |
|
( 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) |
|
(1 << maca_ctrl_auto) |
|
||||||
|
#endif
|
||||||
(maca_ctrl_seq_rx));
|
(maca_ctrl_seq_rx));
|
||||||
/* status bit 10 is set immediately */
|
/* status bit 10 is set immediately */
|
||||||
/* then 11, 10, and 9 get set */
|
/* then 11, 10, and 9 get set */
|
||||||
|
|
254
cpu/mc1322x/lib/pwm.c
Normal file
254
cpu/mc1322x/lib/pwm.c
Normal 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
202
cpu/mc1322x/lib/rtc.c
Normal 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;
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ FIQ_STACK_SIZE = 256;
|
||||||
SVC_STACK_SIZE = 256;
|
SVC_STACK_SIZE = 256;
|
||||||
ABT_STACK_SIZE = 16;
|
ABT_STACK_SIZE = 16;
|
||||||
UND_STACK_SIZE = 16;
|
UND_STACK_SIZE = 16;
|
||||||
HEAP_SIZE = 1024;
|
HEAP_SIZE = 4096;
|
||||||
|
|
||||||
/* Read-only sections, merged into text segment: */
|
/* Read-only sections, merged into text segment: */
|
||||||
PROVIDE (__executable_start = 0x00400000); . = 0x00400000;
|
PROVIDE (__executable_start = 0x00400000); . = 0x00400000;
|
||||||
|
|
|
@ -87,6 +87,9 @@ void irq(void)
|
||||||
cal_isr();
|
cal_isr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(bit_is_set(pending, INT_NUM_ASM)) {
|
||||||
|
if(asm_isr != 0) { asm_isr(); }
|
||||||
|
}
|
||||||
|
|
||||||
*INTFRC = 0; /* stop forcing interrupts */
|
*INTFRC = 0; /* stop forcing interrupts */
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,11 @@ TARGETS := blink-red blink-green blink-blue blink-white blink-allio \
|
||||||
uart1-loopback \
|
uart1-loopback \
|
||||||
tmr tmr-ints \
|
tmr tmr-ints \
|
||||||
sleep \
|
sleep \
|
||||||
printf
|
printf \
|
||||||
|
asm \
|
||||||
|
adc \
|
||||||
|
pwm \
|
||||||
|
wdt
|
||||||
|
|
||||||
# these targets are built with space reserved for variables needed by ROM services
|
# 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
|
# this space is initialized with a rom call to rom_data_init
|
||||||
|
|
63
cpu/mc1322x/tests/adc.c
Normal file
63
cpu/mc1322x/tests/adc.c
Normal 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
209
cpu/mc1322x/tests/asm.c
Normal 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
85
cpu/mc1322x/tests/pwm.c
Normal 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
76
cpu/mc1322x/tests/wdt.c
Normal 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
82
cpu/mc1322x/tools/bin2macbin.pl
Executable 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
65
cpu/mc1322x/tools/burn-mac.pl
Executable 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);
|
||||||
|
|
|
@ -24,7 +24,7 @@ GetOptions ('file=s' => \$filename,
|
||||||
'zerolen' => \$zerolen,
|
'zerolen' => \$zerolen,
|
||||||
'terminal=s' => \$term,
|
'terminal=s' => \$term,
|
||||||
'verbose' => \$verbose,
|
'verbose' => \$verbose,
|
||||||
'baud=s' => \$baud,
|
'u|baud=s' => \$baud,
|
||||||
'rts=s' => \$rts,
|
'rts=s' => \$rts,
|
||||||
'command=s' => \$command,
|
'command=s' => \$command,
|
||||||
'a=s' => \$first_delay,
|
'a=s' => \$first_delay,
|
||||||
|
@ -41,8 +41,8 @@ if($filename eq '') {
|
||||||
print " -f required: binary file to load\n";
|
print " -f required: binary file to load\n";
|
||||||
print " -s optional: secondary binary file to send\n";
|
print " -s optional: secondary binary file to send\n";
|
||||||
print " -z optional: send a zero length file as secondary\n";
|
print " -z optional: send a zero length file as secondary\n";
|
||||||
print " -t terminal default: /dev/ttyUSB0\n";
|
print " -t, terminal default: /dev/ttyUSB0\n";
|
||||||
print " -b baud rate default: 115200\n";
|
print " -u, --baud baud rate default: 115200\n";
|
||||||
print " -r [none|rts] flow control default: rts\n";
|
print " -r [none|rts] flow control default: rts\n";
|
||||||
print " -c command to run for autoreset: \n";
|
print " -c command to run for autoreset: \n";
|
||||||
print " e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n";
|
print " e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n";
|
||||||
|
|
|
@ -5,11 +5,14 @@ my $bin = shift;
|
||||||
my $terms = shift;
|
my $terms = shift;
|
||||||
|
|
||||||
my $addr = "0x1e000";
|
my $addr = "0x1e000";
|
||||||
my $company_id;
|
my $iab = 0xa8c; # Redwire, LLC's IAB
|
||||||
my $iab = 0xabc; # Redwire, LLC's IAB
|
|
||||||
|
my $mac_h;
|
||||||
|
my $mac_l;
|
||||||
|
|
||||||
if(defined($iab)) {
|
if(defined($iab)) {
|
||||||
$company_id = (0x0050C2 << 12) | $iab;
|
$mac_h = 0x0050C200 | ($iab >> 4);
|
||||||
|
$mac_l = ($iab & 0xf) << 28;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $terms) {
|
if (! $terms) {
|
||||||
|
@ -19,15 +22,17 @@ if (! $terms) {
|
||||||
|
|
||||||
for (my $t=0; $t<$terms; $t++) {
|
for (my $t=0; $t<$terms; $t++) {
|
||||||
my $dev_num = 2 * $t + 1;
|
my $dev_num = 2 * $t + 1;
|
||||||
|
$mac_l |= $dev_num;
|
||||||
|
#stupid 32-bit thing...
|
||||||
my $mac;
|
my $mac;
|
||||||
if(defined($iab)) {
|
printf("mac_h %x\n", $mac_h);
|
||||||
$mac = ($company_id << 28) | $dev_num;
|
printf("mac_l %x\n", $mac_l);
|
||||||
} else {
|
|
||||||
$mac = ($company_id << 40) | $dev_num;
|
|
||||||
}
|
|
||||||
my @words;
|
my @words;
|
||||||
for(my $i=0; $i<8; $i++) {
|
for(my $i=0; $i<4; $i++) {
|
||||||
push @words, ($mac >> ($i * 8)) & 0xff;
|
push @words, ($mac_h >> ($i * 8)) & 0xff;
|
||||||
|
}
|
||||||
|
for(my $i=0; $i<4; $i++) {
|
||||||
|
push @words, ($mac_l >> ($i * 8)) & 0xff;
|
||||||
}
|
}
|
||||||
reverse @words;
|
reverse @words;
|
||||||
foreach my $byte (@words) {
|
foreach my $byte (@words) {
|
||||||
|
|
|
@ -111,7 +111,7 @@ loader_arch_load(unsigned short startaddr)
|
||||||
/* If the checksum was wrong, we beep. The number of beeps indicate
|
/* If the checksum was wrong, we beep. The number of beeps indicate
|
||||||
the numerival value of the calculated checksum. */
|
the numerival value of the calculated checksum. */
|
||||||
if(sum != 0xff) {
|
if(sum != 0xff) {
|
||||||
leds_red(LEDS_ON);
|
leds_on(LEDS_RED);
|
||||||
|
|
||||||
for(i = 0; i < (sum >> 4); ++i) {
|
for(i = 0; i < (sum >> 4); ++i) {
|
||||||
beep_beep(200);
|
beep_beep(200);
|
||||||
|
@ -131,23 +131,23 @@ loader_arch_load(unsigned short startaddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leds_red(LEDS_OFF);
|
leds_off(LEDS_RED);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
leds_green(LEDS_ON);
|
leds_on(LEDS_GREEN);
|
||||||
for(i = 0; i < 4; ++i) {
|
for(i = 0; i < 4; ++i) {
|
||||||
beep_beep(200);
|
beep_beep(200);
|
||||||
for(j = 0; j < 2; ++j) {
|
for(j = 0; j < 2; ++j) {
|
||||||
clock_delay(60000);
|
clock_delay(60000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leds_green(LEDS_OFF);
|
leds_off(LEDS_GREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
leds_yellow(LEDS_ON);
|
leds_on(LEDS_YELLOW);
|
||||||
startaddr += 2;
|
startaddr += 2;
|
||||||
|
|
||||||
/* Read the size of the code segment from the next two bytes in EEPROM. */
|
/* 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();
|
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. */
|
/* Read the size of the code segment from the first two bytes in EEPROM. */
|
||||||
eeprom_read(startaddr + 2 + codelen, (char *)&datalen, 2);
|
eeprom_read(startaddr + 2 + codelen, (char *)&datalen, 2);
|
||||||
|
@ -205,7 +205,7 @@ loader_arch_load(unsigned short startaddr)
|
||||||
clock_delay(20000);
|
clock_delay(20000);
|
||||||
}
|
}
|
||||||
|
|
||||||
leds_green(LEDS_OFF);
|
leds_off(LEDS_GREEN);
|
||||||
|
|
||||||
/* Execute the loaded program. */
|
/* Execute the loaded program. */
|
||||||
init = ((void (*)(void *))FLASHADDR);
|
init = ((void (*)(void *))FLASHADDR);
|
||||||
|
|
|
@ -45,9 +45,9 @@ ifdef IAR
|
||||||
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library.a
|
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library.a
|
||||||
else
|
else
|
||||||
ifdef PRINTF_FLOAT
|
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
|
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
|
||||||
endif
|
endif
|
||||||
# `$(CC) -print-file-name=thumb2/libc.a` `$(CC) -print-file-name=thumb2/libgcc.a`
|
# `$(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)
|
ASFLAGS = -s+ -w+ --cpu Cortex-M3 -L$(OBJECTDIR)
|
||||||
LDFLAGS += --redirect _Printf=_PrintfSmall --redirect _Scanf=_ScanfSmall --map=contiki-$(TARGET).map
|
LDFLAGS += --redirect _Printf=_PrintfSmall --redirect _Scanf=_ScanfSmall --map=contiki-$(TARGET).map
|
||||||
ifndef COFFEE
|
ifndef COFFEE
|
||||||
LDFLAGS+= --config $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/iar-cfg.icf
|
LDFLAGS+= --config $(CONTIKI_CPU)/iar-cfg.icf
|
||||||
endif
|
endif
|
||||||
OBJOPTS = --bin
|
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
|
-mlittle-endian -fshort-enums -x assembler-with-cpp -Wa,-EL
|
||||||
LDFLAGS += -mcpu=cortex-m3 \
|
LDFLAGS += -mcpu=cortex-m3 \
|
||||||
-mthumb \
|
-mthumb \
|
||||||
-Wl,-T -Xlinker $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/gnu.ld \
|
-Wl,-T -Xlinker $(CONTIKI_CPU)/gnu.ld \
|
||||||
-Wl,-static \
|
-Wl,-static \
|
||||||
-u Default_Handler \
|
-u Default_Handler \
|
||||||
-nostartfiles \
|
-nostartfiles \
|
||||||
|
@ -118,8 +118,6 @@ OBJOPTS = -O binary
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifndef IAR
|
|
||||||
|
|
||||||
ifdef COFFEE_ADDRESS
|
ifdef COFFEE_ADDRESS
|
||||||
COFFEE = 1
|
COFFEE = 1
|
||||||
endif
|
endif
|
||||||
|
@ -147,15 +145,18 @@ ifeq ($(COFFEE),1)
|
||||||
|
|
||||||
else
|
else
|
||||||
# Coffee starts at the end of the flash, before NVM section.
|
# Coffee starts at the end of the flash, before NVM section.
|
||||||
COFFEE_ADDRESS = 0x801F400
|
COFFEE_ADDRESS = 0x801F800
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ifndef IAR
|
||||||
|
|
||||||
LDFLAGS+= -Wl,--section-start=.coffee=$(COFFEE_ADDRESS)
|
LDFLAGS+= -Wl,--section-start=.coffee=$(COFFEE_ADDRESS)
|
||||||
|
|
||||||
else #IAR
|
else #IAR
|
||||||
|
|
||||||
ifeq ($(COFFEE),1)
|
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
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
/* If using IAR, COFFEE_ADDRESS reflects the static value in the linker script
|
/* 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.*/
|
iar-cfg-coffee.icf, so it can't be passed as a parameter for Make.*/
|
||||||
#ifdef __ICCARM__
|
#ifdef __ICCARM__
|
||||||
#define COFFEE_ADDRESS 0x8010000
|
#define COFFEE_ADDRESS 0x8010c00
|
||||||
#endif
|
#endif
|
||||||
#if (COFFEE_ADDRESS & 0x3FF) !=0
|
#if (COFFEE_ADDRESS & 0x3FF) !=0
|
||||||
#error "COFFEE_ADDRESS not aligned to a 1024-bytes page boundary."
|
#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.
|
#define COFFEE_LOG_SIZE 128 // COFFEE_MICRO_LOGS is 0.
|
||||||
|
|
||||||
|
|
||||||
#if COFFEE_PAGES <= 0x100
|
#if COFFEE_PAGES <= 127
|
||||||
#define coffee_page_t uint8_t
|
#define coffee_page_t int8_t
|
||||||
#elif COFFEE_PAGES <= 0x10000
|
#elif COFFEE_PAGES <= 0x7FFF
|
||||||
|
#define coffee_page_t int16_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
||||||
* File Name : stm32f10x_conf.h
|
* File Name : stm32w_conf.h
|
||||||
* Author : MCD Application Team
|
* Author : MCD Application Team
|
||||||
* Version : V2.0.3
|
* Version : V2.0.3
|
||||||
* Date : 09/22/2008
|
* Date : 09/22/2008
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
#define __STM32F10x_CONF_H
|
#define __STM32F10x_CONF_H
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "stm32w_type.h"
|
#include "stm32w108_type.h"
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
/* Exported constants --------------------------------------------------------*/
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
||||||
* File Name : stm32f10x_systick.c
|
* File Name : stm32w108_systick.c
|
||||||
* Author : MCD Application Team
|
* Author : MCD Application Team
|
||||||
* Version : V2.0.3
|
* Version : V2.0.3
|
||||||
* Date : 09/22/2008
|
* Date : 09/22/2008
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#ifndef __STM32W_SYSTICK_H
|
#ifndef __STM32W_SYSTICK_H
|
||||||
#define __STM32W_SYSTICK_H
|
#define __STM32W_SYSTICK_H
|
||||||
|
|
||||||
#include "stm32w_type.h"
|
#include "stm32w108_type.h"
|
||||||
#include "stm32w_conf.h"
|
#include "stm32w_conf.h"
|
||||||
|
|
||||||
#ifndef EXT
|
#ifndef EXT
|
||||||
|
|
|
@ -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****/
|
|
53
cpu/stm32w108/dev/uart1.h.bak
Normal file
53
cpu/stm32w108/dev/uart1.h.bak
Normal 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
Loading…
Reference in a new issue