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
241 changed files with 6193 additions and 3413 deletions
25
.gitignore
vendored
25
.gitignore
vendored
|
@ -1,16 +1,13 @@
|
|||
*~
|
||||
*.swp
|
||||
.a
|
||||
*.bin
|
||||
*.map
|
||||
*.png
|
||||
*.log
|
||||
*.elf
|
||||
*.ihex
|
||||
obj_*
|
||||
*.z1
|
||||
!Makefile.z1
|
||||
*.sky
|
||||
*.map
|
||||
*.a
|
||||
*pyc
|
||||
*.pyc
|
||||
symbols.c
|
||||
symbols.h
|
||||
*_del*
|
||||
tools/
|
||||
*.class
|
||||
symbols.*
|
||||
Makefile.target
|
||||
doc/html
|
||||
patches-*
|
||||
tools/tunslip6
|
||||
|
|
|
@ -36,9 +36,6 @@ savedefines:
|
|||
@echo >Makefile.$(TARGET).defines "DEFINES = $(DEFINES)"
|
||||
|
||||
OBJECTDIR = obj_$(TARGET)
|
||||
ifeq (${wildcard $(OBJECTDIR)},)
|
||||
DUMMY := ${shell mkdir $(OBJECTDIR)}
|
||||
endif
|
||||
|
||||
LOWERCASE = -abcdefghijklmnopqrstuvwxyz
|
||||
UPPERCASE = _ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
|
@ -109,10 +106,13 @@ endif
|
|||
|
||||
target_makefile := $(wildcard $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET))
|
||||
|
||||
# Check if the target makefile exists
|
||||
# Check if the target makefile exists, and create the object directory if necessary.
|
||||
ifeq ($(strip $(target_makefile)),)
|
||||
${error The target platform "$(TARGET)" does not exist (maybe it was misspelled?)}
|
||||
else
|
||||
ifeq (${wildcard $(OBJECTDIR)},)
|
||||
DUMMY := ${shell mkdir $(OBJECTDIR)}
|
||||
endif
|
||||
include $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET)
|
||||
endif
|
||||
|
||||
|
|
0
apps/rest-coap/Makefile.rest-coap
Executable file → Normal file
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;
|
||||
|
||||
printf("%d 1 %d %d %d %u %lu %lu %lu %lu %lu %lu # for automatic processing\n",
|
||||
printf("%d 1 %d %d %d %lu %lu %lu %lu %lu %lu %lu # for automatic processing\n",
|
||||
current_type,
|
||||
s->sent, s->received, s->timedout,
|
||||
s->end - s->start,
|
||||
|
@ -173,7 +173,7 @@ print_local_stats(struct stats *s)
|
|||
{
|
||||
unsigned long total_time;
|
||||
|
||||
printf("%d 0 %d %d %d %u %lu %lu %lu %lu %lu %lu # for automatic processing\n",
|
||||
printf("%d 0 %d %d %d %lu %lu %lu %lu %lu %lu %lu # for automatic processing\n",
|
||||
current_type,
|
||||
s->sent, s->received, s->timedout,
|
||||
s->end - s->start,
|
||||
|
@ -185,12 +185,12 @@ print_local_stats(struct stats *s)
|
|||
|
||||
printf("Local node statistics:\n");
|
||||
|
||||
printf(" Total transfer time: %d.%d seconds, %d.%02d packets/second\n",
|
||||
printf(" Total transfer time: %lu.%02lu seconds, %lu.%02lu packets/second\n",
|
||||
(s->end - s->start) / CLOCK_SECOND,
|
||||
((10 * (s->end - s->start)) / CLOCK_SECOND) % 10,
|
||||
CLOCK_SECOND * s->sent / (s->end - s->start),
|
||||
(100 * CLOCK_SECOND * s->sent / (s->end - s->start)) % 100);
|
||||
|
||||
((1UL * CLOCK_SECOND * s->sent) / (s->end - s->start)),
|
||||
(((100UL * CLOCK_SECOND * s->sent) / (s->end - s->start)) % 100));
|
||||
|
||||
printf(" Average round-trip-time: %lu ms (%lu + %lu)\n",
|
||||
(1000 * (s->total_rx_latency + s->total_tx_latency) / s->received) /
|
||||
RTIMER_ARCH_SECOND,
|
||||
|
|
|
@ -174,6 +174,17 @@ typedef struct unit_test {
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Obtain the result of a certain unit test.
|
||||
*
|
||||
* If the unit test has not yet been executed, this macro returns
|
||||
* unit_test_failed. Otherwise it returns the result of the last
|
||||
* execution of the unit test.
|
||||
*
|
||||
* \param name The name of the unit test.
|
||||
*/
|
||||
#define UNIT_TEST_RESULT(name) (unit_test_##name.result)
|
||||
|
||||
/* The default print function. */
|
||||
void unit_test_print_report(const unit_test_t *utp);
|
||||
|
||||
|
|
0
core/cfs/cfs-coffee.c
Executable file → Normal file
0
core/cfs/cfs-coffee.c
Executable file → Normal file
|
@ -50,7 +50,6 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <io.h>
|
||||
|
||||
#include "contiki.h"
|
||||
|
|
|
@ -121,7 +121,3 @@ leds_invert(unsigned char ledv) {
|
|||
show_leds(ledv);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void leds_green(int o) { o?leds_on(LEDS_GREEN):leds_off(LEDS_GREEN); }
|
||||
void leds_yellow(int o) { o?leds_on(LEDS_YELLOW):leds_off(LEDS_YELLOW); }
|
||||
void leds_red(int o) { o?leds_on(LEDS_RED):leds_off(LEDS_RED); }
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -55,11 +55,18 @@ void leds_init(void);
|
|||
*/
|
||||
void leds_blink(void);
|
||||
|
||||
#ifndef LEDS_GREEN
|
||||
#define LEDS_GREEN 1
|
||||
#define LEDS_YELLOW 2
|
||||
#define LEDS_RED 4
|
||||
#define LEDS_BLUE LEDS_YELLOW /* Tmote Sky is colorblind? */
|
||||
#define leds_blue leds_yellow
|
||||
#endif /* LEDS_GREEN */
|
||||
#ifndef LEDS_YELLOW
|
||||
#define LEDS_YELLOW 2
|
||||
#endif /* LEDS_YELLOW */
|
||||
#ifndef LEDS_RED
|
||||
#define LEDS_RED 4
|
||||
#endif /* LEDS_RED */
|
||||
#ifndef LEDS_BLUE
|
||||
#define LEDS_BLUE LEDS_YELLOW
|
||||
#endif /* LEDS_BLUE */
|
||||
|
||||
#ifdef LEDS_CONF_ALL
|
||||
#define LEDS_ALL LEDS_CONF_ALL
|
||||
|
@ -76,18 +83,6 @@ void leds_off(unsigned char leds);
|
|||
void leds_toggle(unsigned char leds);
|
||||
void leds_invert(unsigned char leds);
|
||||
|
||||
|
||||
|
||||
|
||||
void leds_green(int onoroff);
|
||||
void leds_red(int onoroff);
|
||||
void leds_yellow(int onoroff);
|
||||
#define LEDS_ON 1
|
||||
#define LEDS_OFF 0
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Leds implementation
|
||||
*/
|
||||
|
|
|
@ -46,41 +46,40 @@
|
|||
#define ETX_LIMIT 15
|
||||
#define ETX_SCALE 100
|
||||
#define ETX_ALPHA 90
|
||||
#define ETX_FIRST_GUESS 5
|
||||
|
||||
#define NOACK_PACKET_ETX 8
|
||||
#define ETX_NOACK_PENALTY ETX_LIMIT
|
||||
/*---------------------------------------------------------------------------*/
|
||||
NEIGHBOR_ATTRIBUTE(uint8_t, etx, NULL);
|
||||
NEIGHBOR_ATTRIBUTE(link_metric_t, etx, NULL);
|
||||
|
||||
static neighbor_info_subscriber_t subscriber_callback;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
update_etx(const rimeaddr_t *dest, int packet_etx)
|
||||
update_metric(const rimeaddr_t *dest, int packet_metric)
|
||||
{
|
||||
uint8_t *etxp;
|
||||
uint8_t recorded_etx, new_etx;
|
||||
link_metric_t *metricp;
|
||||
link_metric_t recorded_metric, new_metric;
|
||||
|
||||
etxp = (uint8_t *)neighbor_attr_get_data(&etx, dest);
|
||||
if(etxp == NULL || *etxp == 0) {
|
||||
recorded_etx = NEIGHBOR_INFO_ETX2FIX(ETX_FIRST_GUESS);
|
||||
metricp = (link_metric_t *)neighbor_attr_get_data(&etx, dest);
|
||||
packet_metric = NEIGHBOR_INFO_ETX2FIX(packet_metric);
|
||||
if(metricp == NULL || *metricp == 0) {
|
||||
recorded_metric = NEIGHBOR_INFO_ETX2FIX(ETX_LIMIT);
|
||||
new_metric = packet_metric;
|
||||
} else {
|
||||
recorded_etx = *etxp;
|
||||
recorded_metric = *metricp;
|
||||
/* Update the EWMA of the ETX for the neighbor. */
|
||||
new_metric = ((uint16_t)recorded_metric * ETX_ALPHA +
|
||||
(uint16_t)packet_metric * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
|
||||
}
|
||||
|
||||
/* Update the EWMA of the ETX for the neighbor. */
|
||||
packet_etx = NEIGHBOR_INFO_ETX2FIX(packet_etx);
|
||||
new_etx = ((uint16_t)recorded_etx * ETX_ALPHA +
|
||||
(uint16_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
|
||||
PRINTF("neighbor-info: ETX changed from %d to %d (packet ETX = %d) %d\n",
|
||||
NEIGHBOR_INFO_FIX2ETX(recorded_etx),
|
||||
NEIGHBOR_INFO_FIX2ETX(new_etx),
|
||||
NEIGHBOR_INFO_FIX2ETX(packet_etx),
|
||||
NEIGHBOR_INFO_FIX2ETX(recorded_metric),
|
||||
NEIGHBOR_INFO_FIX2ETX(new_metric),
|
||||
NEIGHBOR_INFO_FIX2ETX(packet_metric),
|
||||
dest->u8[7]);
|
||||
|
||||
if(neighbor_attr_has_neighbor(dest)) {
|
||||
neighbor_attr_set_data(&etx, dest, &new_etx);
|
||||
if(new_etx != recorded_etx && subscriber_callback != NULL) {
|
||||
subscriber_callback(dest, 1, new_etx);
|
||||
neighbor_attr_set_data(&etx, dest, &new_metric);
|
||||
if(new_metric != recorded_metric && subscriber_callback != NULL) {
|
||||
subscriber_callback(dest, 1, new_metric);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,9 +95,6 @@ add_neighbor(const rimeaddr_t *addr)
|
|||
PRINTF("neighbor-info: The neighbor is already known\n");
|
||||
break;
|
||||
default:
|
||||
if(subscriber_callback != NULL) {
|
||||
subscriber_callback(addr, 1, NEIGHBOR_INFO_ETX2FIX(ETX_FIRST_GUESS));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +103,7 @@ void
|
|||
neighbor_info_packet_sent(int status, int numtx)
|
||||
{
|
||||
const rimeaddr_t *dest;
|
||||
uint8_t packet_etx;
|
||||
link_metric_t packet_metric;
|
||||
|
||||
dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
|
||||
if(rimeaddr_cmp(dest, &rimeaddr_null)) {
|
||||
|
@ -120,25 +116,22 @@ neighbor_info_packet_sent(int status, int numtx)
|
|||
|
||||
switch(status) {
|
||||
case MAC_TX_OK:
|
||||
packet_etx = numtx;
|
||||
packet_metric = numtx;
|
||||
add_neighbor(dest);
|
||||
break;
|
||||
case MAC_TX_COLLISION:
|
||||
packet_etx = numtx;
|
||||
packet_metric = numtx;
|
||||
break;
|
||||
case MAC_TX_NOACK:
|
||||
packet_etx = NOACK_PACKET_ETX;
|
||||
/* error and collissions will not cause high hits ??? */
|
||||
packet_metric = ETX_NOACK_PENALTY;
|
||||
break;
|
||||
case MAC_TX_ERR:
|
||||
default:
|
||||
packet_etx = 0;
|
||||
break;
|
||||
/* Do not penalize the ETX when collisions or transmission
|
||||
errors occur. */
|
||||
return;
|
||||
}
|
||||
|
||||
if(packet_etx > 0) {
|
||||
update_etx(dest, packet_etx);
|
||||
}
|
||||
update_metric(dest, packet_metric);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -169,12 +162,12 @@ neighbor_info_subscribe(neighbor_info_subscriber_t s)
|
|||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
neighbor_info_get_etx(const rimeaddr_t *addr)
|
||||
link_metric_t
|
||||
neighbor_info_get_metric(const rimeaddr_t *addr)
|
||||
{
|
||||
uint8_t *etxp;
|
||||
link_metric_t *metricp;
|
||||
|
||||
etxp = (uint8_t *)neighbor_attr_get_data(&etx, addr);
|
||||
return etxp == NULL ? 0 : *etxp;
|
||||
metricp = (link_metric_t *)neighbor_attr_get_data(&etx, addr);
|
||||
return metricp == NULL ? ETX_LIMIT : *metricp;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#define NEIGHBOR_INFO_FIX2ETX(fix) ((fix) / NEIGHBOR_INFO_ETX_DIVISOR)
|
||||
|
||||
typedef void (*neighbor_info_subscriber_t)(const rimeaddr_t *, int known, int etx);
|
||||
typedef uint8_t link_metric_t;
|
||||
|
||||
/**
|
||||
* Notify the neighbor information module about the status of
|
||||
|
@ -85,6 +86,6 @@ int neighbor_info_subscribe(neighbor_info_subscriber_t);
|
|||
*
|
||||
* \return Returns ETX if the neighbor exists, and 0 if not.
|
||||
*/
|
||||
uint8_t neighbor_info_get_etx(const rimeaddr_t *addr);
|
||||
link_metric_t neighbor_info_get_etx(const rimeaddr_t *addr);
|
||||
|
||||
#endif /* NEIGHBOR_INFO_H */
|
||||
|
|
|
@ -286,31 +286,34 @@ PT_THREAD(psock_readto(CC_REGISTER_ARG struct psock *psock, unsigned char c))
|
|||
PT_END(&psock->psockpt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PT_THREAD(psock_readbuf(CC_REGISTER_ARG struct psock *psock))
|
||||
PT_THREAD(psock_readbuf_len(CC_REGISTER_ARG struct psock *psock, uint16_t len))
|
||||
{
|
||||
PT_BEGIN(&psock->psockpt);
|
||||
|
||||
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
|
||||
|
||||
|
||||
/* XXX: Should add buf_checkmarker() before do{} loop, if
|
||||
incoming data has been handled while waiting for a write. */
|
||||
|
||||
if(psock->readlen == 0) {
|
||||
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
|
||||
psock->state = STATE_READ;
|
||||
psock->readptr = (u8_t *)uip_appdata;
|
||||
psock->readlen = uip_datalen();
|
||||
}
|
||||
buf_bufdata(&psock->buf, psock->bufsize,
|
||||
&psock->readptr,
|
||||
&psock->readlen);
|
||||
|
||||
|
||||
/* read len bytes or to end of data */
|
||||
do {
|
||||
if(psock->readlen == 0) {
|
||||
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
|
||||
psock->state = STATE_READ;
|
||||
psock->readptr = (u8_t *)uip_appdata;
|
||||
psock->readlen = uip_datalen();
|
||||
}
|
||||
} while(buf_bufdata(&psock->buf, psock->bufsize,
|
||||
&psock->readptr, &psock->readlen) == BUF_NOT_FULL &&
|
||||
psock_datalen(psock) < len);
|
||||
|
||||
if(psock_datalen(psock) == 0) {
|
||||
psock->state = STATE_NONE;
|
||||
PT_RESTART(&psock->psockpt);
|
||||
}
|
||||
PT_END(&psock->psockpt);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
psock_init(CC_REGISTER_ARG struct psock *psock,
|
||||
|
|
|
@ -241,7 +241,7 @@ PT_THREAD(psock_generator_send(struct psock *psock,
|
|||
*/
|
||||
#define PSOCK_CLOSE(psock) uip_close()
|
||||
|
||||
PT_THREAD(psock_readbuf(struct psock *psock));
|
||||
PT_THREAD(psock_readbuf_len(struct psock *psock, uint16_t len));
|
||||
/**
|
||||
* Read data until the buffer is full.
|
||||
*
|
||||
|
@ -255,7 +255,24 @@ PT_THREAD(psock_readbuf(struct psock *psock));
|
|||
* \hideinitializer
|
||||
*/
|
||||
#define PSOCK_READBUF(psock) \
|
||||
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
|
||||
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, 1))
|
||||
|
||||
|
||||
/**
|
||||
* Read data until at least len bytes have been read.
|
||||
*
|
||||
* This macro will block waiting for data and read the data into the
|
||||
* input buffer specified with the call to PSOCK_INIT(). Data is read
|
||||
* until the buffer is full or len bytes have been read.
|
||||
*
|
||||
* \param psock (struct psock *) A pointer to the protosocket from which
|
||||
* data should be read.
|
||||
* \param len (uint16_t) The minimum number of bytes to read.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define PSOCK_READBUF_LEN(psock, len) \
|
||||
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, len))
|
||||
|
||||
PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
|
||||
/**
|
||||
|
|
|
@ -94,8 +94,6 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF};
|
|||
#define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS
|
||||
#endif /* !RPL_CONF_DIO_INTERVAL_DOUBLINGS */
|
||||
|
||||
#define INITIAL_ETX NEIGHBOR_INFO_ETX_DIVISOR * 5
|
||||
|
||||
/************************************************************************/
|
||||
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */
|
||||
MEMB(parent_memb, struct rpl_parent, RPL_MAX_PARENTS);
|
||||
|
@ -309,7 +307,7 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
|||
memcpy(&p->addr, addr, sizeof(p->addr));
|
||||
p->dag = dag;
|
||||
p->rank = dio->rank;
|
||||
p->etx = INITIAL_ETX;
|
||||
p->link_metric = INITIAL_LINK_METRIC;
|
||||
p->dtsn = 0;
|
||||
|
||||
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
||||
|
@ -358,6 +356,7 @@ rpl_select_parent(rpl_dag_t *dag)
|
|||
rpl_reset_dio_timer(dag, 1);
|
||||
PRINTF("RPL: New preferred parent, rank changed from %u to %u\n",
|
||||
(unsigned)dag->rank, dag->of->calculate_rank(best, 0));
|
||||
RPL_STAT(rpl_stats.parent_switch++);
|
||||
}
|
||||
|
||||
/* Update the DAG rank, since link-layer information may have changed
|
||||
|
@ -458,8 +457,6 @@ join_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
}
|
||||
PRINTF("succeeded\n");
|
||||
|
||||
p->etx = INITIAL_ETX; /* The lowest confidence for new parents. */
|
||||
|
||||
/* Determine the objective function by using the
|
||||
objective code point of the DIO. */
|
||||
of = rpl_find_of(dio->ocp);
|
||||
|
@ -732,7 +729,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
PRINTF(")\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PRINTF("RPL: New candidate parent with rank %u: ", (unsigned)p->rank);
|
||||
PRINT6ADDR(from);
|
||||
PRINTF("\n");
|
||||
|
@ -742,7 +739,8 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
}
|
||||
|
||||
/* We have allocated a candidate parent; process the DIO further. */
|
||||
|
||||
|
||||
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
||||
p->rank = dio->rank;
|
||||
if(rpl_process_parent_event(dag, p) == 0) {
|
||||
/* The candidate parent no longer exists. */
|
||||
|
|
|
@ -250,9 +250,10 @@ dio_input(void)
|
|||
dio.mc.aggr = buffer[i + 4] >> 4;
|
||||
dio.mc.prec = buffer[i + 4] & 0xf;
|
||||
dio.mc.length = buffer[i + 5];
|
||||
|
||||
if(dio.mc.type == RPL_DAG_MC_ETX) {
|
||||
dio.mc.etx.etx = buffer[i + 6] << 8;
|
||||
dio.mc.etx.etx |= buffer[i + 7];
|
||||
dio.mc.obj.etx = buffer[i + 6] << 8;
|
||||
dio.mc.obj.etx |= buffer[i + 7];
|
||||
|
||||
PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n",
|
||||
(unsigned)dio.mc.type,
|
||||
|
@ -260,7 +261,10 @@ dio_input(void)
|
|||
(unsigned)dio.mc.aggr,
|
||||
(unsigned)dio.mc.prec,
|
||||
(unsigned)dio.mc.length,
|
||||
(unsigned)dio.mc.etx.etx);
|
||||
(unsigned)dio.mc.obj.etx);
|
||||
} else if(dio.mc.type == RPL_DAG_MC_ENERGY) {
|
||||
dio.mc.obj.energy.flags = buffer[i + 6];
|
||||
dio.mc.obj.energy.energy_est = buffer[i + 7];
|
||||
} else {
|
||||
PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type);
|
||||
return;
|
||||
|
@ -380,8 +384,12 @@ dio_output(rpl_dag_t *dag, uip_ipaddr_t *uc_addr)
|
|||
buffer[pos++] |= dag->mc.prec;
|
||||
if(dag->mc.type == RPL_DAG_MC_ETX) {
|
||||
buffer[pos++] = 2;
|
||||
buffer[pos++] = dag->mc.etx.etx >> 8;
|
||||
buffer[pos++] = dag->mc.etx.etx & 0xff;
|
||||
buffer[pos++] = dag->mc.obj.etx >> 8;
|
||||
buffer[pos++] = dag->mc.obj.etx & 0xff;
|
||||
} else if(dag->mc.type == RPL_DAG_MC_ENERGY) {
|
||||
buffer[pos++] = 2;
|
||||
buffer[pos++] = dag->mc.obj.energy.flags;
|
||||
buffer[pos++] = dag->mc.obj.energy.energy_est;
|
||||
} else {
|
||||
PRINTF("RPL: Unable to send DIO because of unhandled DAG MC type %u\n",
|
||||
(unsigned)dag->mc.type);
|
||||
|
@ -459,6 +467,8 @@ dao_input(void)
|
|||
uint8_t prefixlen;
|
||||
uint8_t flags;
|
||||
uint8_t subopt_type;
|
||||
uint8_t pathcontrol;
|
||||
uint8_t pathsequence;
|
||||
uip_ipaddr_t prefix;
|
||||
uip_ds6_route_t *rep;
|
||||
uint8_t buffer_length;
|
||||
|
@ -523,7 +533,9 @@ dao_input(void)
|
|||
break;
|
||||
case RPL_DIO_SUBOPT_TRANSIT:
|
||||
/* path sequence and control ignored */
|
||||
lifetime = get32(buffer, i + 4);
|
||||
pathcontrol = buffer[i + 3];
|
||||
pathsequence = buffer[i + 4];
|
||||
lifetime = buffer[i + 5];
|
||||
/* parent address also ignored */
|
||||
break;
|
||||
}
|
||||
|
@ -567,11 +579,11 @@ dao_input(void)
|
|||
|
||||
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
|
||||
if(rep == NULL) {
|
||||
RPL_STAT(rpl_stats.memory_overflows++);
|
||||
RPL_STAT(rpl_stats.mem_overflows++);
|
||||
PRINTF("RPL: Could not add a route after receiving a DAO\n");
|
||||
return;
|
||||
} else {
|
||||
rep->state.lifetime = lifetime;
|
||||
rep->state.lifetime = lifetime * dag->lifetime_unit;
|
||||
rep->state.learned_from = learned_from;
|
||||
}
|
||||
|
||||
|
@ -637,13 +649,13 @@ dao_output(rpl_parent_t *n, uint32_t lifetime)
|
|||
memcpy(buffer + pos, &prefix, (prefixlen + 7) / CHAR_BIT);
|
||||
pos += ((prefixlen + 7) / CHAR_BIT);
|
||||
|
||||
/* create a transit information subopt */
|
||||
/* create a transit information subopt (RPL-18)*/
|
||||
buffer[pos++] = RPL_DIO_SUBOPT_TRANSIT;
|
||||
buffer[pos++] = 6;
|
||||
buffer[pos++] = 0; /* path seq - ignored */
|
||||
buffer[pos++] = 4;
|
||||
buffer[pos++] = 0; /* flags - ignored */
|
||||
buffer[pos++] = 0; /* path control - ignored */
|
||||
set32(buffer, pos, lifetime);
|
||||
pos += 4;
|
||||
buffer[pos++] = 0; /* path seq - ignored */
|
||||
buffer[pos++] = (lifetime / dag->lifetime_unit) & 0xff;
|
||||
|
||||
if(n == NULL) {
|
||||
uip_create_linklocal_rplnodes_mcast(&addr);
|
||||
|
|
|
@ -66,7 +66,7 @@ rpl_of_t rpl_of_etx = {
|
|||
|
||||
#define NI_ETX_TO_RPL_ETX(etx) \
|
||||
((etx) * (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR))
|
||||
#define RPL_ETX_TO_NI_ETX(etx) \
|
||||
#define RPL_ETX_TO_NI_ETX(etx) \
|
||||
((etx) / (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR))
|
||||
|
||||
/* Reject parents that have a higher link metric than the following. */
|
||||
|
@ -75,22 +75,21 @@ rpl_of_t rpl_of_etx = {
|
|||
/* Reject parents that have a higher path cost than the following. */
|
||||
#define MAX_PATH_COST 100
|
||||
|
||||
/* An initial guess of the link metric. */
|
||||
#define INITIAL_LINK_METRIC 3
|
||||
|
||||
/*
|
||||
* The rank must differ more than 1/PARENT_SWITCH_THRESHOLD_DIV in order
|
||||
* to switch preferred parent.
|
||||
*/
|
||||
#define PARENT_SWITCH_THRESHOLD_DIV 2
|
||||
|
||||
typedef uint16_t rpl_etx_t;
|
||||
#define MAX_ETX 65535
|
||||
typedef uint16_t rpl_path_metric_t;
|
||||
|
||||
static uint16_t
|
||||
calculate_etx(rpl_parent_t *p)
|
||||
calculate_path_metric(rpl_parent_t *p)
|
||||
{
|
||||
return p->mc.etx.etx + NI_ETX_TO_RPL_ETX(p->etx);
|
||||
if(p->mc.obj.etx == 0 && p->rank > ROOT_RANK(p->dag)) {
|
||||
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
|
||||
}
|
||||
return p->mc.obj.etx + NI_ETX_TO_RPL_ETX(p->link_metric);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -113,12 +112,9 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
|
|||
if(base_rank == 0) {
|
||||
return INFINITE_RANK;
|
||||
}
|
||||
rank_increase = INITIAL_LINK_METRIC * DEFAULT_MIN_HOPRANKINC;
|
||||
rank_increase = NEIGHBOR_INFO_FIX2ETX(INITIAL_LINK_METRIC) * DEFAULT_MIN_HOPRANKINC;
|
||||
} else {
|
||||
if(p->etx == 0) {
|
||||
p->etx = INITIAL_LINK_METRIC * NEIGHBOR_INFO_ETX_DIVISOR;
|
||||
}
|
||||
rank_increase = (p->etx * p->dag->min_hoprankinc) / NEIGHBOR_INFO_ETX_DIVISOR;
|
||||
rank_increase = NEIGHBOR_INFO_FIX2ETX(p->link_metric) * p->dag->min_hoprankinc;
|
||||
if(base_rank == 0) {
|
||||
base_rank = p->rank;
|
||||
}
|
||||
|
@ -140,46 +136,64 @@ static rpl_parent_t *
|
|||
best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
||||
{
|
||||
rpl_dag_t *dag;
|
||||
rpl_etx_t min_diff;
|
||||
rpl_etx_t p1_etx;
|
||||
rpl_etx_t p2_etx;
|
||||
rpl_path_metric_t min_diff;
|
||||
rpl_path_metric_t p1_metric;
|
||||
rpl_path_metric_t p2_metric;
|
||||
|
||||
dag = p1->dag; /* Both parents must be in the same DAG. */
|
||||
|
||||
min_diff = RPL_DAG_MC_ETX_DIVISOR /
|
||||
PARENT_SWITCH_THRESHOLD_DIV;
|
||||
|
||||
p1_etx = calculate_etx(p1);
|
||||
p2_etx = calculate_etx(p2);
|
||||
p1_metric = calculate_path_metric(p1);
|
||||
p2_metric = calculate_path_metric(p2);
|
||||
|
||||
/* Maintain stability of the preferred parent in case of similar ranks. */
|
||||
if(p1_etx < p2_etx + min_diff &&
|
||||
p1_etx > p2_etx - min_diff) {
|
||||
PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
|
||||
p2_etx - min_diff,
|
||||
p1_etx,
|
||||
p2_etx + min_diff);
|
||||
return dag->preferred_parent;
|
||||
if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
|
||||
if(p1_metric < p2_metric + min_diff &&
|
||||
p1_metric > p2_metric - min_diff) {
|
||||
PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
|
||||
p2_metric - min_diff,
|
||||
p1_metric,
|
||||
p2_metric + min_diff);
|
||||
return dag->preferred_parent;
|
||||
}
|
||||
}
|
||||
|
||||
return p1_etx < p2_etx ? p1 : p2;
|
||||
return p1_metric < p2_metric ? p1 : p2;
|
||||
}
|
||||
|
||||
static void
|
||||
update_metric_container(rpl_dag_t *dag)
|
||||
{
|
||||
#if RPL_DAG_MC == RPL_DAG_MC_ETX
|
||||
dag->mc.type = RPL_DAG_MC_ETX;
|
||||
dag->mc.flags = RPL_DAG_MC_FLAG_P;
|
||||
dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
|
||||
dag->mc.prec = 0;
|
||||
dag->mc.length = sizeof(dag->mc.etx.etx);
|
||||
dag->mc.length = sizeof(dag->mc.obj.etx);
|
||||
if(dag->rank == ROOT_RANK(dag)) {
|
||||
dag->mc.etx.etx = 0;
|
||||
dag->mc.obj.etx = 0;
|
||||
} else {
|
||||
dag->mc.etx.etx = calculate_etx(dag->preferred_parent);
|
||||
dag->mc.obj.etx = calculate_path_metric(dag->preferred_parent);
|
||||
}
|
||||
|
||||
PRINTF("RPL: My path ETX to the root is %u.%u\n",
|
||||
dag->mc.etx.etx / RPL_DAG_MC_ETX_DIVISOR,
|
||||
(dag->mc.etx.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR);
|
||||
dag->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR,
|
||||
(dag->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR);
|
||||
#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
|
||||
dag->mc.type = RPL_DAG_MC_ENERGY;
|
||||
dag->mc.flags = RPL_DAG_MC_FLAG_P;
|
||||
dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
|
||||
dag->mc.prec = 0;
|
||||
dag->mc.length = sizeof(dag->mc.obj.energy);
|
||||
if(dag->rank == ROOT_RANK(dag)) {
|
||||
dag->mc.obj.energy.flags = RPL_DAG_MC_ENERGY_TYPE_MAINS << RPL_DAG_MC_ENERGY_TYPE;
|
||||
} else {
|
||||
dag->mc.obj.energy.flags = RPL_DAG_MC_ENERGY_TYPE_BATTERY << RPL_DAG_MC_ENERGY_TYPE;
|
||||
}
|
||||
dag->mc.obj.energy.energy_est = calculate_path_metric(dag->preferred_parent);
|
||||
#else
|
||||
#error "Unsupported RPL_DAG_MC configured. See rpl.h."
|
||||
#endif /* RPL_DAG_MC */
|
||||
}
|
||||
|
|
|
@ -127,6 +127,8 @@
|
|||
|
||||
#define INFINITE_RANK 0xffff
|
||||
|
||||
#define INITIAL_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(5)
|
||||
|
||||
/* Represents 2^n ms. */
|
||||
/* Default value according to the specification is 3 which
|
||||
means 8 milliseconds, but that is an unreasonable value if
|
||||
|
@ -218,6 +220,7 @@ struct rpl_stats {
|
|||
uint16_t global_repairs;
|
||||
uint16_t malformed_msgs;
|
||||
uint16_t resets;
|
||||
uint16_t parent_switch;
|
||||
};
|
||||
typedef struct rpl_stats rpl_stats_t;
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ new_dio_interval(rpl_dag_t *dag)
|
|||
dag->version,
|
||||
dag->dio_totint, dag->dio_totsend,
|
||||
dag->dio_totrecv,dag->dio_intcurrent,
|
||||
dag->rank == ROOT_RANK ? "BLUE" : "ORANGE");
|
||||
dag->rank == ROOT_RANK(dag) ? "BLUE" : "ORANGE");
|
||||
#endif /* RPL_CONF_STATS */
|
||||
|
||||
/* reset the redundancy counter */
|
||||
|
@ -205,7 +205,8 @@ handle_dao_timer(void *ptr)
|
|||
fan-out as being under investigation. */
|
||||
if(dag->preferred_parent != NULL) {
|
||||
PRINTF("RPL: handle_dao_timer - sending DAO\n");
|
||||
dao_output(dag->preferred_parent, DEFAULT_ROUTE_LIFETIME);
|
||||
/* set time to maxtime */
|
||||
dao_output(dag->preferred_parent, dag->lifetime_unit * 0xffUL);
|
||||
} else {
|
||||
PRINTF("RPL: Could not find a parent to send a DAO to \n");
|
||||
}
|
||||
|
|
|
@ -148,11 +148,10 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
|||
return;
|
||||
}
|
||||
|
||||
if(etx != parent->etx) {
|
||||
/* Trigger DAG rank recalculation. */
|
||||
parent->updated = 1;
|
||||
}
|
||||
parent->etx = etx;
|
||||
/* Trigger DAG rank recalculation. */
|
||||
parent->updated = 1;
|
||||
|
||||
parent->link_metric = etx;
|
||||
|
||||
if(dag->of->parent_state_callback != NULL) {
|
||||
dag->of->parent_state_callback(parent, known, etx);
|
||||
|
@ -163,7 +162,6 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
|||
PRINT6ADDR(&parent->addr);
|
||||
PRINTF(" because of bad connectivity (ETX %d)\n", etx);
|
||||
parent->rank = INFINITE_RANK;
|
||||
parent->updated = 1;
|
||||
}
|
||||
}
|
||||
/************************************************************************/
|
||||
|
|
|
@ -49,6 +49,17 @@
|
|||
#define RPL_CONF_STATS 0
|
||||
#endif /* RPL_CONF_STATS */
|
||||
|
||||
/*
|
||||
* Select routing metric supported at runtime. This must be a valid
|
||||
* DAG Metric Container Object Type (see below). Currently, we only
|
||||
* support RPL_DAG_MC_ETX and RPL_DAG_MC_ENERGY.
|
||||
*/
|
||||
#ifdef RPL_CONF_DAG_MC
|
||||
#define RPL_DAG_MC RPL_CONF_DAG_MC
|
||||
#else
|
||||
#define RPL_DAG_MC RPL_DAG_MC_ETX
|
||||
#endif /* RPL_CONF_DAG_MC */
|
||||
|
||||
/*
|
||||
* The objective function used by RPL is configurable through the
|
||||
* RPL_CONF_OF parameter. This should be defined to be the name of an
|
||||
|
@ -78,8 +89,8 @@ typedef uint16_t rpl_ocp_t;
|
|||
/* DAG Metric Container Object Types, to be confirmed by IANA. */
|
||||
#define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */
|
||||
#define RPL_DAG_MC_NSA 1 /* Node State and Attributes */
|
||||
#define RPL_DAG_MC_NE 2 /* Node Energy */
|
||||
#define RPL_DAG_MC_HC 3 /* Hop Count */
|
||||
#define RPL_DAG_MC_ENERGY 2 /* Node Energy */
|
||||
#define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */
|
||||
#define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */
|
||||
#define RPL_DAG_MC_LATENCY 5 /* Latency */
|
||||
#define RPL_DAG_MC_LQL 6 /* Link Quality Level */
|
||||
|
@ -99,9 +110,19 @@ typedef uint16_t rpl_ocp_t;
|
|||
#define RPL_DAG_MC_AGGR_MINIMUM 2
|
||||
#define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
|
||||
|
||||
/* Logical representation of an ETX object in a DAG Metric Container. */
|
||||
struct rpl_metric_object_etx {
|
||||
uint16_t etx;
|
||||
/* The bit index within the flags field of
|
||||
the rpl_metric_object_energy structure. */
|
||||
#define RPL_DAG_MC_ENERGY_INCLUDED 3
|
||||
#define RPL_DAG_MC_ENERGY_TYPE 1
|
||||
#define RPL_DAG_MC_ENERGY_ESTIMATION 0
|
||||
|
||||
#define RPL_DAG_MC_ENERGY_TYPE_MAINS 0
|
||||
#define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1
|
||||
#define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2
|
||||
|
||||
struct rpl_metric_object_energy {
|
||||
uint8_t flags;
|
||||
uint8_t energy_est;
|
||||
};
|
||||
|
||||
/* Logical representation of a DAG Metric Container. */
|
||||
|
@ -111,9 +132,10 @@ struct rpl_metric_container {
|
|||
uint8_t aggr;
|
||||
uint8_t prec;
|
||||
uint8_t length;
|
||||
/* Once we support more objects, the etx field will be replaced by a
|
||||
union of those. */
|
||||
struct rpl_metric_object_etx etx;
|
||||
union metric_object {
|
||||
struct rpl_metric_object_energy energy;
|
||||
uint16_t etx;
|
||||
} obj;
|
||||
};
|
||||
typedef struct rpl_metric_container rpl_metric_container_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -125,7 +147,7 @@ struct rpl_parent {
|
|||
rpl_metric_container_t mc;
|
||||
uip_ipaddr_t addr;
|
||||
rpl_rank_t rank;
|
||||
uint8_t etx;
|
||||
uint8_t link_metric;
|
||||
uint8_t dtsn;
|
||||
uint8_t updated;
|
||||
};
|
||||
|
|
|
@ -268,7 +268,7 @@ static uint8_t *hc06_ptr;
|
|||
/* Uncompression of linklocal */
|
||||
/* 0 -> 16 bytes from packet */
|
||||
/* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet */
|
||||
/* 2 -> 2 bytes from prefix - zeroes + 2 from packet */
|
||||
/* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet */
|
||||
/* 3 -> 2 bytes from prefix - infer 8 bytes from lladdr */
|
||||
/* NOTE: => the uncompress function does change 0xf to 0x10 */
|
||||
/* NOTE: 0x00 => no-autoconfig => unspecified */
|
||||
|
@ -277,7 +277,7 @@ const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
|
|||
/* Uncompression of ctx-based */
|
||||
/* 0 -> 0 bits from packet [unspecified / reserved] */
|
||||
/* 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet */
|
||||
/* 2 -> 8 bytes from prefix - zeroes + 2 from packet */
|
||||
/* 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX + 2 from packet */
|
||||
/* 3 -> 8 bytes from prefix - infer 8 bytes from lladdr */
|
||||
const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
|
||||
|
||||
|
@ -338,7 +338,7 @@ compress_addr_64(uint8_t bitpos, uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
|
|||
if(uip_is_addr_mac_addr_based(ipaddr, lladdr)) {
|
||||
return 3 << bitpos; /* 0-bits */
|
||||
} else if(sicslowpan_is_iid_16_bit_compressable(ipaddr)) {
|
||||
/* compress IID to 16 bits xxxx::XXXX */
|
||||
/* compress IID to 16 bits xxxx::0000:00ff:fe00:XXXX */
|
||||
memcpy(hc06_ptr, &ipaddr->u16[7], 2);
|
||||
hc06_ptr += 2;
|
||||
return 2 << bitpos; /* 16-bits */
|
||||
|
@ -377,6 +377,11 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
|
|||
}
|
||||
if(postcount > 0) {
|
||||
memcpy(&ipaddr->u8[16 - postcount], hc06_ptr, postcount);
|
||||
if(postcount == 2 && prefcount < 11) {
|
||||
/* 16 bits uncompression => 0000:00ff:fe00:XXXX */
|
||||
ipaddr->u8[11] = 0xff;
|
||||
ipaddr->u8[12] = 0xfe;
|
||||
}
|
||||
hc06_ptr += postcount;
|
||||
} else if (prefcount > 0) {
|
||||
/* no IID based configuration if no prefix and no data => unspec */
|
||||
|
|
|
@ -233,13 +233,15 @@ struct sicslowpan_addr_context {
|
|||
* \brief check whether we can compress the IID in
|
||||
* address 'a' to 16 bits.
|
||||
* This is used for unicast addresses only, and is true
|
||||
* if first 49 bits of IID are 0
|
||||
* if the address is on the format <PREFIX>::0000:00ff:fe00:XXXX
|
||||
* NOTE: we currently assume 64-bits prefixes
|
||||
*/
|
||||
#define sicslowpan_is_iid_16_bit_compressable(a) \
|
||||
((((a)->u16[4]) == 0) && \
|
||||
(((a)->u16[5]) == 0) && \
|
||||
(((a)->u16[6]) == 0) && \
|
||||
((((a)->u8[14]) & 0x80) == 0))
|
||||
(((a)->u8[10]) == 0)&& \
|
||||
(((a)->u8[11]) == 0xff)&& \
|
||||
(((a)->u8[12]) == 0xfe)&& \
|
||||
(((a)->u8[13]) == 0))
|
||||
|
||||
/**
|
||||
* \brief check whether the 9-bit group-id of the
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: uip-debug.c,v 1.1 2010/04/30 13:20:57 joxe Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -39,7 +38,7 @@
|
|||
*/
|
||||
|
||||
#include "net/uip-debug.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
||||
|
@ -52,19 +51,19 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
|||
a = (addr->u8[i] << 8) + addr->u8[i + 1];
|
||||
if(a == 0 && f >= 0) {
|
||||
if(f++ == 0) {
|
||||
printf("::");
|
||||
PRINTA("::");
|
||||
}
|
||||
} else {
|
||||
if(f > 0) {
|
||||
f = -1;
|
||||
} else if(i > 0) {
|
||||
printf(":");
|
||||
PRINTA(":");
|
||||
}
|
||||
printf("%x", a);
|
||||
PRINTA("%x", a);
|
||||
}
|
||||
}
|
||||
#else /* UIP_CONF_IPV6 */
|
||||
printf("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);
|
||||
PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -74,9 +73,9 @@ uip_debug_lladdr_print(const uip_lladdr_t *addr)
|
|||
unsigned int i;
|
||||
for(i = 0; i < sizeof(uip_lladdr_t); i++) {
|
||||
if(i > 0) {
|
||||
printf(":");
|
||||
PRINTA(":");
|
||||
}
|
||||
printf("%02x", addr->addr[i]);
|
||||
PRINTA("%02x", addr->addr[i]);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#define UIP_DEBUG_H
|
||||
|
||||
#include "net/uip.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void uip_debug_ipaddr_print(const uip_ipaddr_t *addr);
|
||||
void uip_debug_lladdr_print(const uip_lladdr_t *addr);
|
||||
|
@ -52,16 +53,30 @@ void uip_debug_lladdr_print(const uip_lladdr_t *addr);
|
|||
#define DEBUG_ANNOTATE 2
|
||||
#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT
|
||||
|
||||
/* PRINTA will always print if the debug routines are called directly */
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
|
||||
#else
|
||||
#define PRINTA(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if (DEBUG) & DEBUG_ANNOTATE
|
||||
#include <stdio.h>
|
||||
#ifdef __AVR__
|
||||
#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
|
||||
#else
|
||||
#define ANNOTATE(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
#else
|
||||
#define ANNOTATE(...)
|
||||
#endif /* (DEBUG) & DEBUG_ANNOTATE */
|
||||
|
||||
#if (DEBUG) & DEBUG_PRINT
|
||||
#include <stdio.h>
|
||||
#ifdef __AVR__
|
||||
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
|
||||
#else
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
#define PRINT6ADDR(addr) uip_debug_ipaddr_print(addr)
|
||||
#define PRINTLLADDR(lladdr) uip_debug_lladdr_print(lladdr)
|
||||
#else
|
||||
|
|
203
core/net/uip-ds6.c
Executable file → Normal file
203
core/net/uip-ds6.c
Executable file → Normal file
|
@ -174,60 +174,60 @@ uip_ds6_periodic(void)
|
|||
#if !UIP_CONF_ROUTER
|
||||
/* Periodic processing on prefixes */
|
||||
for(locprefix = uip_ds6_prefix_list;
|
||||
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
|
||||
if((locprefix->isused) && (!locprefix->isinfinite)
|
||||
&& (stimer_expired(&(locprefix->vlifetime)))) {
|
||||
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB;
|
||||
locprefix++) {
|
||||
if(locprefix->isused && !locprefix->isinfinite
|
||||
&& stimer_expired(&(locprefix->vlifetime))) {
|
||||
uip_ds6_prefix_rm(locprefix);
|
||||
}
|
||||
}
|
||||
#endif /* !UIP_CONF_ROUTER */
|
||||
|
||||
/* Periodic processing on neighbors */
|
||||
for(locnbr = uip_ds6_nbr_cache; locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB;
|
||||
for(locnbr = uip_ds6_nbr_cache;
|
||||
locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB;
|
||||
locnbr++) {
|
||||
if(locnbr->isused) {
|
||||
switch (locnbr->state) {
|
||||
switch(locnbr->state) {
|
||||
case NBR_INCOMPLETE:
|
||||
if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
|
||||
uip_ds6_nbr_rm(locnbr);
|
||||
} else if(stimer_expired(&(locnbr->sendns))) {
|
||||
} else if(stimer_expired(&locnbr->sendns)) {
|
||||
locnbr->nscount++;
|
||||
PRINTF("NBR_INCOMPLETE: NS %u\n", locnbr->nscount);
|
||||
uip_nd6_ns_output(NULL, NULL, &locnbr->ipaddr);
|
||||
stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000);
|
||||
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
|
||||
}
|
||||
break;
|
||||
case NBR_REACHABLE:
|
||||
if(stimer_expired(&(locnbr->reachable))) {
|
||||
if(stimer_expired(&locnbr->reachable)) {
|
||||
PRINTF("REACHABLE: moving to STALE (");
|
||||
PRINT6ADDR(&locnbr->ipaddr);
|
||||
PRINTF(")\n");
|
||||
locnbr->state = NBR_STALE;
|
||||
/* NEIGHBOR_STATE_CHANGED(locnbr); */
|
||||
}
|
||||
break;
|
||||
case NBR_DELAY:
|
||||
if(stimer_expired(&(locnbr->reachable))) {
|
||||
if(stimer_expired(&locnbr->reachable)) {
|
||||
locnbr->state = NBR_PROBE;
|
||||
locnbr->nscount = 1;
|
||||
/* NEIGHBOR_STATE_CHANGED(locnbr); */
|
||||
PRINTF("DELAY: moving to PROBE + NS %u\n", locnbr->nscount);
|
||||
uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr);
|
||||
stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000);
|
||||
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
|
||||
}
|
||||
break;
|
||||
case NBR_PROBE:
|
||||
if(locnbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
|
||||
PRINTF("PROBE END \n");
|
||||
PRINTF("PROBE END\n");
|
||||
if((locdefrt = uip_ds6_defrt_lookup(&locnbr->ipaddr)) != NULL) {
|
||||
uip_ds6_defrt_rm(locdefrt);
|
||||
}
|
||||
uip_ds6_nbr_rm(locnbr);
|
||||
} else if(stimer_expired(&(locnbr->sendns))) {
|
||||
} else if(stimer_expired(&locnbr->sendns)) {
|
||||
locnbr->nscount++;
|
||||
PRINTF("PROBE: NS %u\n", locnbr->nscount);
|
||||
uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr);
|
||||
stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000);
|
||||
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -248,9 +248,9 @@ uip_ds6_periodic(void)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size,
|
||||
uint16_t elementsize, uip_ipaddr_t * ipaddr,
|
||||
uint8_t ipaddrlen, uip_ds6_element_t ** out_element)
|
||||
uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
|
||||
uint16_t elementsize, uip_ipaddr_t *ipaddr,
|
||||
uint8_t ipaddrlen, uip_ds6_element_t **out_element)
|
||||
{
|
||||
uip_ds6_element_t *element;
|
||||
|
||||
|
@ -258,11 +258,10 @@ uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size,
|
|||
|
||||
for(element = list;
|
||||
element <
|
||||
(uip_ds6_element_t *) ((uint8_t *) list + (size * elementsize));
|
||||
element = (uip_ds6_element_t *) ((uint8_t *) element + elementsize)) {
|
||||
// printf("+ %p %d\n", &element->isused, element->isused);
|
||||
(uip_ds6_element_t *)((uint8_t *)list + (size * elementsize));
|
||||
element = (uip_ds6_element_t *)((uint8_t *)element + elementsize)) {
|
||||
if(element->isused) {
|
||||
if(uip_ipaddr_prefixcmp(&(element->ipaddr), ipaddr, ipaddrlen)) {
|
||||
if(uip_ipaddr_prefixcmp(&element->ipaddr, ipaddr, ipaddrlen)) {
|
||||
*out_element = element;
|
||||
return FOUND;
|
||||
}
|
||||
|
@ -271,33 +270,28 @@ uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size,
|
|||
}
|
||||
}
|
||||
|
||||
if(*out_element != NULL) {
|
||||
return FREESPACE;
|
||||
} else {
|
||||
return NOSPACE;
|
||||
}
|
||||
return *out_element != NULL ? FREESPACE : NOSPACE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr,
|
||||
uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t * lladdr,
|
||||
uint8_t isrouter, uint8_t state)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
|
||||
sizeof(uip_ds6_nbr_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) &locnbr);
|
||||
// printf("r %d\n", r);
|
||||
(uip_ds6_element_t **)&locnbr);
|
||||
|
||||
if(r == FREESPACE) {
|
||||
locnbr->isused = 1;
|
||||
uip_ipaddr_copy(&(locnbr->ipaddr), ipaddr);
|
||||
uip_ipaddr_copy(&locnbr->ipaddr, ipaddr);
|
||||
if(lladdr != NULL) {
|
||||
memcpy(&(locnbr->lladdr), lladdr, UIP_LLADDR_LEN);
|
||||
memcpy(&locnbr->lladdr, lladdr, UIP_LLADDR_LEN);
|
||||
} else {
|
||||
memset(&(locnbr->lladdr), 0, UIP_LLADDR_LEN);
|
||||
memset(&locnbr->lladdr, 0, UIP_LLADDR_LEN);
|
||||
}
|
||||
locnbr->isrouter = isrouter;
|
||||
locnbr->state = state;
|
||||
|
@ -305,18 +299,17 @@ uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr,
|
|||
uip_packetqueue_new(&locnbr->packethandle);
|
||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||
/* timers are set separately, for now we put them in expired state */
|
||||
stimer_set(&(locnbr->reachable), 0);
|
||||
stimer_set(&(locnbr->sendns), 0);
|
||||
stimer_set(&locnbr->reachable, 0);
|
||||
stimer_set(&locnbr->sendns, 0);
|
||||
locnbr->nscount = 0;
|
||||
PRINTF("Adding neighbor with ip addr");
|
||||
PRINTF("Adding neighbor with ip addr ");
|
||||
PRINT6ADDR(ipaddr);
|
||||
PRINTF("link addr");
|
||||
PRINTF("link addr ");
|
||||
PRINTLLADDR((&(locnbr->lladdr)));
|
||||
PRINTF("state %u\n", state);
|
||||
NEIGHBOR_STATE_CHANGED(locnbr);
|
||||
|
||||
locnbr->last_lookup = clock_time();
|
||||
// printf("add %p\n", locnbr);
|
||||
return locnbr;
|
||||
} else if(r == NOSPACE) {
|
||||
/* We did not find any empty slot on the neighbor list, so we need
|
||||
|
@ -338,7 +331,6 @@ uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr,
|
|||
}
|
||||
}
|
||||
if(oldest != NULL) {
|
||||
// printf("rm3\n");
|
||||
uip_ds6_nbr_rm(oldest);
|
||||
return uip_ds6_nbr_add(ipaddr, lladdr, isrouter, state);
|
||||
}
|
||||
|
@ -354,7 +346,6 @@ uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
|
|||
if(nbr != NULL) {
|
||||
nbr->isused = 0;
|
||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||
// printf("rm %p\n", &nbr->isused);
|
||||
uip_packetqueue_free(&nbr->packethandle);
|
||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||
NEIGHBOR_STATE_CHANGED(nbr);
|
||||
|
@ -367,9 +358,9 @@ uip_ds6_nbr_t *
|
|||
uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
|
||||
sizeof(uip_ds6_nbr_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) & locnbr) == FOUND) {
|
||||
(uip_ds6_element_t **)&locnbr) == FOUND) {
|
||||
return locnbr;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -380,19 +371,19 @@ uip_ds6_defrt_t *
|
|||
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_defrt_list, UIP_DS6_DEFRT_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_defrt_list, UIP_DS6_DEFRT_NB,
|
||||
sizeof(uip_ds6_defrt_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) & locdefrt) == FREESPACE) {
|
||||
(uip_ds6_element_t **)&locdefrt) == FREESPACE) {
|
||||
locdefrt->isused = 1;
|
||||
uip_ipaddr_copy(&(locdefrt->ipaddr), ipaddr);
|
||||
uip_ipaddr_copy(&locdefrt->ipaddr, ipaddr);
|
||||
if(interval != 0) {
|
||||
stimer_set(&(locdefrt->lifetime), interval);
|
||||
stimer_set(&locdefrt->lifetime, interval);
|
||||
locdefrt->isinfinite = 0;
|
||||
} else {
|
||||
locdefrt->isinfinite = 1;
|
||||
}
|
||||
|
||||
PRINTF("Adding defrouter with ip addr");
|
||||
PRINTF("Adding defrouter with ip addr ");
|
||||
PRINT6ADDR(&locdefrt->ipaddr);
|
||||
PRINTF("\n");
|
||||
|
||||
|
@ -405,7 +396,7 @@ uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_defrt_rm(uip_ds6_defrt_t * defrt)
|
||||
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
|
||||
{
|
||||
if(defrt != NULL) {
|
||||
defrt->isused = 0;
|
||||
|
@ -416,11 +407,11 @@ uip_ds6_defrt_rm(uip_ds6_defrt_t * defrt)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_defrt_t *
|
||||
uip_ds6_defrt_lookup(uip_ipaddr_t * ipaddr)
|
||||
uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
if(uip_ds6_list_loop((uip_ds6_element_t *) uip_ds6_defrt_list,
|
||||
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_defrt_list,
|
||||
UIP_DS6_DEFRT_NB, sizeof(uip_ds6_defrt_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) & locdefrt) == FOUND) {
|
||||
(uip_ds6_element_t **)&locdefrt) == FOUND) {
|
||||
return locdefrt;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -440,7 +431,7 @@ uip_ds6_defrt_choose(void)
|
|||
PRINT6ADDR(&locdefrt->ipaddr);
|
||||
PRINTF("\n");
|
||||
bestnbr = uip_ds6_nbr_lookup(&locdefrt->ipaddr);
|
||||
if((bestnbr != NULL) && (bestnbr->state != NBR_INCOMPLETE)) {
|
||||
if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) {
|
||||
PRINTF("Defrt found, IP address ");
|
||||
PRINT6ADDR(&locdefrt->ipaddr);
|
||||
PRINTF("\n");
|
||||
|
@ -459,16 +450,16 @@ uip_ds6_defrt_choose(void)
|
|||
#if UIP_CONF_ROUTER
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_prefix_t *
|
||||
uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen,
|
||||
uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
|
||||
uint8_t advertise, uint8_t flags, unsigned long vtime,
|
||||
unsigned long ptime)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
|
||||
sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen,
|
||||
(uip_ds6_element_t **) & locprefix) == FREESPACE) {
|
||||
(uip_ds6_element_t **)&locprefix) == FREESPACE) {
|
||||
locprefix->isused = 1;
|
||||
uip_ipaddr_copy(&(locprefix->ipaddr), ipaddr);
|
||||
uip_ipaddr_copy(&locprefix->ipaddr, ipaddr);
|
||||
locprefix->length = ipaddrlen;
|
||||
locprefix->advertise = advertise;
|
||||
locprefix->l_a_reserved = flags;
|
||||
|
@ -488,15 +479,15 @@ uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen,
|
|||
|
||||
#else /* UIP_CONF_ROUTER */
|
||||
uip_ds6_prefix_t *
|
||||
uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen,
|
||||
uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
|
||||
unsigned long interval)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
|
||||
sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen,
|
||||
(uip_ds6_element_t **) & locprefix) == FREESPACE) {
|
||||
(uip_ds6_element_t **)&locprefix) == FREESPACE) {
|
||||
locprefix->isused = 1;
|
||||
uip_ipaddr_copy(&(locprefix->ipaddr), ipaddr);
|
||||
uip_ipaddr_copy(&locprefix->ipaddr, ipaddr);
|
||||
locprefix->length = ipaddrlen;
|
||||
if(interval != 0) {
|
||||
stimer_set(&(locprefix->vlifetime), interval);
|
||||
|
@ -523,7 +514,7 @@ uip_ds6_prefix_rm(uip_ds6_prefix_t * prefix)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_prefix_t *
|
||||
uip_ds6_prefix_lookup(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen)
|
||||
uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen)
|
||||
{
|
||||
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_prefix_list,
|
||||
UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix_t),
|
||||
|
@ -536,7 +527,7 @@ uip_ds6_prefix_lookup(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
uip_ds6_is_addr_onlink(uip_ipaddr_t * ipaddr)
|
||||
uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
for(locprefix = uip_ds6_prefix_list;
|
||||
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
|
||||
|
@ -550,12 +541,12 @@ uip_ds6_is_addr_onlink(uip_ipaddr_t * ipaddr)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_addr_t *
|
||||
uip_ds6_addr_add(uip_ipaddr_t * ipaddr, unsigned long vlifetime, uint8_t type)
|
||||
uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
|
||||
sizeof(uip_ds6_addr_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) & locaddr) == FREESPACE) {
|
||||
(uip_ds6_element_t **)&locaddr) == FREESPACE) {
|
||||
locaddr->isused = 1;
|
||||
uip_ipaddr_copy(&locaddr->ipaddr, ipaddr);
|
||||
locaddr->state = ADDR_TENTATIVE;
|
||||
|
@ -579,7 +570,7 @@ uip_ds6_addr_add(uip_ipaddr_t * ipaddr, unsigned long vlifetime, uint8_t type)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_addr_rm(uip_ds6_addr_t * addr)
|
||||
uip_ds6_addr_rm(uip_ds6_addr_t *addr)
|
||||
{
|
||||
if(addr != NULL) {
|
||||
uip_create_solicited_node(&addr->ipaddr, &loc_fipaddr);
|
||||
|
@ -593,12 +584,12 @@ uip_ds6_addr_rm(uip_ds6_addr_t * addr)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_addr_t *
|
||||
uip_ds6_addr_lookup(uip_ipaddr_t * ipaddr)
|
||||
uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
|
||||
sizeof(uip_ds6_addr_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) & locaddr) == FOUND) {
|
||||
(uip_ds6_element_t **)&locaddr) == FOUND) {
|
||||
return locaddr;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -615,7 +606,7 @@ uip_ds6_get_link_local(int8_t state)
|
|||
{
|
||||
for(locaddr = uip_ds6_if.addr_list;
|
||||
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
||||
if((locaddr->isused) && (state == -1 || locaddr->state == state)
|
||||
if(locaddr->isused && (state == -1 || locaddr->state == state)
|
||||
&& (uip_is_addr_link_local(&locaddr->ipaddr))) {
|
||||
return locaddr;
|
||||
}
|
||||
|
@ -634,7 +625,7 @@ uip_ds6_get_global(int8_t state)
|
|||
{
|
||||
for(locaddr = uip_ds6_if.addr_list;
|
||||
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
||||
if((locaddr->isused) && (state == -1 || locaddr->state == state)
|
||||
if(locaddr->isused && (state == -1 || locaddr->state == state)
|
||||
&& !(uip_is_addr_link_local(&locaddr->ipaddr))) {
|
||||
return locaddr;
|
||||
}
|
||||
|
@ -644,12 +635,12 @@ uip_ds6_get_global(int8_t state)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_maddr_t *
|
||||
uip_ds6_maddr_add(uip_ipaddr_t * ipaddr)
|
||||
uip_ds6_maddr_add(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
|
||||
sizeof(uip_ds6_maddr_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) & locmaddr) == FREESPACE) {
|
||||
(uip_ds6_element_t **)&locmaddr) == FREESPACE) {
|
||||
locmaddr->isused = 1;
|
||||
uip_ipaddr_copy(&locmaddr->ipaddr, ipaddr);
|
||||
return locmaddr;
|
||||
|
@ -669,12 +660,12 @@ uip_ds6_maddr_rm(uip_ds6_maddr_t * maddr)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_maddr_t *
|
||||
uip_ds6_maddr_lookup(uip_ipaddr_t * ipaddr)
|
||||
uip_ds6_maddr_lookup(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
|
||||
sizeof(uip_ds6_maddr_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) & locmaddr) == FOUND) {
|
||||
(uip_ds6_element_t **)&locmaddr) == FOUND) {
|
||||
return locmaddr;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -683,12 +674,12 @@ uip_ds6_maddr_lookup(uip_ipaddr_t * ipaddr)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_aaddr_t *
|
||||
uip_ds6_aaddr_add(uip_ipaddr_t * ipaddr)
|
||||
uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB,
|
||||
sizeof(uip_ds6_aaddr_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **) & locaaddr) == FREESPACE) {
|
||||
(uip_ds6_element_t **)&locaaddr) == FREESPACE) {
|
||||
locaaddr->isused = 1;
|
||||
uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr);
|
||||
return locaaddr;
|
||||
|
@ -708,9 +699,9 @@ uip_ds6_aaddr_rm(uip_ds6_aaddr_t * aaddr)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_aaddr_t *
|
||||
uip_ds6_aaddr_lookup(uip_ipaddr_t * ipaddr)
|
||||
uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
if(uip_ds6_list_loop((uip_ds6_element_t *) uip_ds6_if.aaddr_list,
|
||||
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_if.aaddr_list,
|
||||
UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128,
|
||||
(uip_ds6_element_t **)&locaaddr) == FOUND) {
|
||||
return locaaddr;
|
||||
|
@ -720,12 +711,12 @@ uip_ds6_aaddr_lookup(uip_ipaddr_t * ipaddr)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_route_t *
|
||||
uip_ds6_route_lookup(uip_ipaddr_t * destipaddr)
|
||||
uip_ds6_route_lookup(uip_ipaddr_t *destipaddr)
|
||||
{
|
||||
uip_ds6_route_t *locrt = NULL;
|
||||
uint8_t longestmatch = 0;
|
||||
|
||||
PRINTF("DS6: Looking up route for");
|
||||
PRINTF("DS6: Looking up route for ");
|
||||
PRINT6ADDR(destipaddr);
|
||||
PRINTF("\n");
|
||||
|
||||
|
@ -747,7 +738,7 @@ uip_ds6_route_lookup(uip_ipaddr_t * destipaddr)
|
|||
PRINT6ADDR(&locrt->nexthop);
|
||||
PRINTF("\n");
|
||||
} else {
|
||||
PRINTF("DS6: No route found ...\n");
|
||||
PRINTF("DS6: No route found\n");
|
||||
}
|
||||
|
||||
return locrt;
|
||||
|
@ -755,27 +746,25 @@ uip_ds6_route_lookup(uip_ipaddr_t * destipaddr)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_route_t *
|
||||
uip_ds6_route_add(uip_ipaddr_t * ipaddr, u8_t length, uip_ipaddr_t * nexthop,
|
||||
u8_t metric)
|
||||
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop,
|
||||
uint8_t metric)
|
||||
{
|
||||
|
||||
if(uip_ds6_list_loop
|
||||
((uip_ds6_element_t *) uip_ds6_routing_table, UIP_DS6_ROUTE_NB,
|
||||
((uip_ds6_element_t *)uip_ds6_routing_table, UIP_DS6_ROUTE_NB,
|
||||
sizeof(uip_ds6_route_t), ipaddr, length,
|
||||
(uip_ds6_element_t **) & locroute) == FREESPACE) {
|
||||
(uip_ds6_element_t **)&locroute) == FREESPACE) {
|
||||
locroute->isused = 1;
|
||||
uip_ipaddr_copy(&(locroute->ipaddr), ipaddr);
|
||||
locroute->length = length;
|
||||
uip_ipaddr_copy(&(locroute->nexthop), nexthop);
|
||||
locroute->metric = metric;
|
||||
|
||||
PRINTF("DS6: adding route:");
|
||||
PRINTF("DS6: adding route: ");
|
||||
PRINT6ADDR(ipaddr);
|
||||
PRINTF(" via ");
|
||||
PRINT6ADDR(nexthop);
|
||||
PRINTF("\n");
|
||||
ANNOTATE("#L %u 1;blue\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||
|
||||
ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||
}
|
||||
|
||||
return locroute;
|
||||
|
@ -790,9 +779,10 @@ uip_ds6_route_rm(uip_ds6_route_t *route)
|
|||
/* we need to check if this was the last route towards "nexthop" */
|
||||
/* if so - remove that link (annotation) */
|
||||
for(locroute = uip_ds6_routing_table;
|
||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
|
||||
if((locroute->isused) && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
|
||||
/* we did find another link using the specific nexthop, so keep the #L */
|
||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
|
||||
locroute++) {
|
||||
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
|
||||
/* we found another link using the specific nexthop, so keep the #L */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -804,8 +794,9 @@ void
|
|||
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
|
||||
{
|
||||
for(locroute = uip_ds6_routing_table;
|
||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
|
||||
if((locroute->isused) && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
|
||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
|
||||
locroute++) {
|
||||
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
|
||||
locroute->isused = 0;
|
||||
}
|
||||
}
|
||||
|
@ -825,9 +816,9 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
|||
for(locaddr = uip_ds6_if.addr_list;
|
||||
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
||||
/* Only preferred global (not link-local) addresses */
|
||||
if((locaddr->isused) && (locaddr->state == ADDR_PREFERRED) &&
|
||||
(!uip_is_addr_link_local(&locaddr->ipaddr))) {
|
||||
n = get_match_length(dst, &(locaddr->ipaddr));
|
||||
if(locaddr->isused && locaddr->state == ADDR_PREFERRED &&
|
||||
!uip_is_addr_link_local(&locaddr->ipaddr)) {
|
||||
n = get_match_length(dst, &locaddr->ipaddr);
|
||||
if(n >= best) {
|
||||
best = n;
|
||||
matchaddr = locaddr;
|
||||
|
@ -848,7 +839,7 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr)
|
||||
uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t * lladdr)
|
||||
{
|
||||
/* We consider only links with IEEE EUI-64 identifier or
|
||||
* IEEE 48-bit MAC addresses */
|
||||
|
@ -859,7 +850,7 @@ uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr)
|
|||
memcpy(ipaddr->u8 + 8, lladdr, 3);
|
||||
ipaddr->u8[11] = 0xff;
|
||||
ipaddr->u8[12] = 0xfe;
|
||||
memcpy(ipaddr->u8 + 13, (uint8_t *) lladdr + 3, 3);
|
||||
memcpy(ipaddr->u8 + 13, (uint8_t *)lladdr + 3, 3);
|
||||
ipaddr->u8[8] ^= 0x02;
|
||||
#else
|
||||
#error uip-ds6.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
|
||||
|
@ -868,7 +859,7 @@ uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
get_match_length(uip_ipaddr_t * src, uip_ipaddr_t * dst)
|
||||
get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
||||
{
|
||||
uint8_t j, k, x_or;
|
||||
uint8_t len = 0;
|
||||
|
@ -894,7 +885,7 @@ get_match_length(uip_ipaddr_t * src, uip_ipaddr_t * dst)
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_dad(uip_ds6_addr_t * addr)
|
||||
uip_ds6_dad(uip_ds6_addr_t *addr)
|
||||
{
|
||||
/* send maxdadns NS for DAD */
|
||||
if(addr->dadnscount < uip_ds6_if.maxdadns) {
|
||||
|
|
2
core/net/uip-ds6.h
Executable file → Normal file
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_add(uip_ipaddr_t *ipaddr, uint8_t length,
|
||||
uip_ipaddr_t *next_hop, u8_t metric);
|
||||
uip_ipaddr_t *next_hop, uint8_t metric);
|
||||
void uip_ds6_route_rm(uip_ds6_route_t *route);
|
||||
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
|
||||
|
||||
|
|
|
@ -53,15 +53,17 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
|||
|
||||
value = 0;
|
||||
zero = -1;
|
||||
if(*addrstr == '[') addrstr++;
|
||||
|
||||
for(len = 0; len < sizeof(uip_ipaddr_t) - 1; addrstr++) {
|
||||
c = *addrstr;
|
||||
if(c == ':' || c == '\0') {
|
||||
if(c == ':' || c == '\0' || c == ']') {
|
||||
ipaddr->u8[len] = (value >> 8) & 0xff;
|
||||
ipaddr->u8[len + 1] = value & 0xff;
|
||||
len += 2;
|
||||
value = 0;
|
||||
|
||||
if(c == '\0') {
|
||||
if(c == '\0' || c == ']') {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -86,7 +88,7 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
|||
value = (value << 4) + (tmp & 0xf);
|
||||
}
|
||||
}
|
||||
if(c != '\0') {
|
||||
if(c != '\0' && c != ']') {
|
||||
PRINTF("uiplib: too large address\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ ifndef NOAVRSIZE
|
|||
endif
|
||||
|
||||
%.hex: %.out
|
||||
$(OBJCOPY) $^ -O ihex $@
|
||||
$(OBJCOPY) $^ -j .text -j .data -O ihex $@
|
||||
|
||||
%.ihex: %.out
|
||||
$(OBJCOPY) $^ -O ihex $@
|
||||
|
|
|
@ -15,12 +15,23 @@ long sleepseconds;
|
|||
#if RF230BB && WEBSERVER
|
||||
#define RADIOSTATS 1
|
||||
#endif
|
||||
|
||||
#if RADIOSTATS
|
||||
static volatile uint8_t rcount;
|
||||
volatile unsigned long radioontime;
|
||||
extern uint8_t RF230_receive_on;
|
||||
#endif
|
||||
|
||||
/* Set RADIOCALIBRATE for periodic calibration of the PLL during extended radio on time.
|
||||
* The data sheet suggests every 5 minutes if the temperature is fluctuating.
|
||||
* Using an eight bit counter gives 256 second calibrations.
|
||||
* Actual calibration is done by the driver on the next transmit request.
|
||||
*/
|
||||
#if RADIOCALIBRATE
|
||||
extern volatile uint8_t rf230_calibrate;
|
||||
static uint8_t calibrate_interval;
|
||||
#endif
|
||||
|
||||
/*
|
||||
CLOCK_SECOND is the number of ticks per second.
|
||||
It is defined through CONF_CLOCK_SECOND in the contiki-conf.h for each platform.
|
||||
|
@ -46,48 +57,50 @@ void clock_adjust_seconds(uint8_t howmany) {
|
|||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* These routines increment the second counters.
|
||||
* Calling these avoids the interrupt overhead of pushing many registers on the stack.
|
||||
*/
|
||||
static void increment_seconds(void) __attribute__ ((noinline));
|
||||
static void increment_seconds(void)
|
||||
{
|
||||
seconds++;
|
||||
}
|
||||
#if RADIOSTATS
|
||||
extern volatile uint8_t rf230_calibrate;
|
||||
static void increment_radioontime(void) __attribute__ ((noinline));
|
||||
static void increment_radioontime(void)
|
||||
{
|
||||
static uint8_t calibrate_interval;
|
||||
radioontime++;
|
||||
if (++calibrate_interval==0) {
|
||||
rf230_calibrate=1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
//SIGNAL(SIG_OUTPUT_COMPARE0)
|
||||
ISR(AVR_OUTPUT_COMPARE_INT)
|
||||
{
|
||||
count++;
|
||||
if(++scount == CLOCK_SECOND) {
|
||||
scount = 0;
|
||||
increment_seconds();
|
||||
// seconds++;
|
||||
seconds++;
|
||||
}
|
||||
#if RADIOCALIBRATE
|
||||
if (++calibrate_interval==0) {
|
||||
rf230_calibrate=1;
|
||||
}
|
||||
#endif
|
||||
#if RADIOSTATS
|
||||
if (RF230_receive_on) {
|
||||
if (++rcount == CLOCK_SECOND) {
|
||||
rcount=0;
|
||||
increment_radioontime();
|
||||
// radioontime++;
|
||||
radioontime++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
/* gcc will save all registers on the stack if an external routine is called */
|
||||
if(etimer_pending()) {
|
||||
etimer_request_poll();
|
||||
}
|
||||
#else
|
||||
/* doing this locally saves 9 pushes and 9 pops, but these etimer.c and process.c variables have to lose the static qualifier */
|
||||
extern struct etimer *timerlist;
|
||||
extern volatile unsigned char poll_requested;
|
||||
|
||||
#define PROCESS_STATE_NONE 0
|
||||
#define PROCESS_STATE_RUNNING 1
|
||||
#define PROCESS_STATE_CALLED 2
|
||||
|
||||
if (timerlist) {
|
||||
if(etimer_process.state == PROCESS_STATE_RUNNING ||
|
||||
etimer_process.state == PROCESS_STATE_CALLED) {
|
||||
etimer_process.needspoll = 1;
|
||||
poll_requested = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -153,3 +166,91 @@ clock_seconds(void)
|
|||
} while(tmp != seconds);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#ifdef HANG_ON_UNKNOWN_INTERRUPT
|
||||
/* Useful for diagnosing unknown interrupts that reset the mcu.
|
||||
* Currently set up for 12mega128rfa1.
|
||||
* For other mcus, enable all and then disable the conflicts.
|
||||
*/
|
||||
static volatile uint8_t x;
|
||||
ISR( _VECTOR(0)) {while (1) x++;}
|
||||
ISR( _VECTOR(1)) {while (1) x++;}
|
||||
ISR( _VECTOR(2)) {while (1) x++;}
|
||||
ISR( _VECTOR(3)) {while (1) x++;}
|
||||
ISR( _VECTOR(4)) {while (1) x++;}
|
||||
ISR( _VECTOR(5)) {while (1) x++;}
|
||||
ISR( _VECTOR(6)) {while (1) x++;}
|
||||
ISR( _VECTOR(7)) {while (1) x++;}
|
||||
ISR( _VECTOR(8)) {while (1) x++;}
|
||||
ISR( _VECTOR(9)) {while (1) x++;}
|
||||
ISR( _VECTOR(10)) {while (1) x++;}
|
||||
ISR( _VECTOR(11)) {while (1) x++;}
|
||||
ISR( _VECTOR(12)) {while (1) x++;}
|
||||
ISR( _VECTOR(13)) {while (1) x++;}
|
||||
ISR( _VECTOR(14)) {while (1) x++;}
|
||||
ISR( _VECTOR(15)) {while (1) x++;}
|
||||
ISR( _VECTOR(16)) {while (1) x++;}
|
||||
ISR( _VECTOR(17)) {while (1) x++;}
|
||||
ISR( _VECTOR(18)) {while (1) x++;}
|
||||
ISR( _VECTOR(19)) {while (1) x++;}
|
||||
//ISR( _VECTOR(20)) {while (1) x++;}
|
||||
//ISR( _VECTOR(21)) {while (1) x++;}
|
||||
ISR( _VECTOR(22)) {while (1) x++;}
|
||||
ISR( _VECTOR(23)) {while (1) x++;}
|
||||
ISR( _VECTOR(24)) {while (1) x++;}
|
||||
//ISR( _VECTOR(25)) {while (1) x++;}
|
||||
ISR( _VECTOR(26)) {while (1) x++;}
|
||||
//ISR( _VECTOR(27)) {while (1) x++;}
|
||||
ISR( _VECTOR(28)) {while (1) x++;}
|
||||
ISR( _VECTOR(29)) {while (1) x++;}
|
||||
ISR( _VECTOR(30)) {while (1) x++;}
|
||||
ISR( _VECTOR(31)) {while (1) x++;}
|
||||
//ISR( _VECTOR(32)) {while (1) x++;}
|
||||
ISR( _VECTOR(33)) {while (1) x++;}
|
||||
ISR( _VECTOR(34)) {while (1) x++;}
|
||||
ISR( _VECTOR(35)) {while (1) x++;}
|
||||
//ISR( _VECTOR(36)) {while (1) x++;}
|
||||
ISR( _VECTOR(37)) {while (1) x++;}
|
||||
//ISR( _VECTOR(38)) {while (1) x++;}
|
||||
ISR( _VECTOR(39)) {while (1) x++;}
|
||||
ISR( _VECTOR(40)) {while (1) x++;}
|
||||
ISR( _VECTOR(41)) {while (1) x++;}
|
||||
ISR( _VECTOR(42)) {while (1) x++;}
|
||||
ISR( _VECTOR(43)) {while (1) x++;}
|
||||
ISR( _VECTOR(44)) {while (1) x++;}
|
||||
ISR( _VECTOR(45)) {while (1) x++;}
|
||||
ISR( _VECTOR(46)) {while (1) x++;}
|
||||
ISR( _VECTOR(47)) {while (1) x++;}
|
||||
ISR( _VECTOR(48)) {while (1) x++;}
|
||||
ISR( _VECTOR(49)) {while (1) x++;}
|
||||
ISR( _VECTOR(50)) {while (1) x++;}
|
||||
ISR( _VECTOR(51)) {while (1) x++;}
|
||||
ISR( _VECTOR(52)) {while (1) x++;}
|
||||
ISR( _VECTOR(53)) {while (1) x++;}
|
||||
ISR( _VECTOR(54)) {while (1) x++;}
|
||||
ISR( _VECTOR(55)) {while (1) x++;}
|
||||
ISR( _VECTOR(56)) {while (1) x++;}
|
||||
//ISR( _VECTOR(57)) {while (1) x++;}
|
||||
//ISR( _VECTOR(58)) {while (1) x++;}
|
||||
//ISR( _VECTOR(59)) {while (1) x++;}
|
||||
//ISR( _VECTOR(60)) {while (1) x++;}
|
||||
ISR( _VECTOR(61)) {while (1) x++;}
|
||||
ISR( _VECTOR(62)) {while (1) x++;}
|
||||
ISR( _VECTOR(63)) {while (1) x++;}
|
||||
ISR( _VECTOR(64)) {while (1) x++;}
|
||||
ISR( _VECTOR(65)) {while (1) x++;}
|
||||
ISR( _VECTOR(66)) {while (1) x++;}
|
||||
ISR( _VECTOR(67)) {while (1) x++;}
|
||||
ISR( _VECTOR(68)) {while (1) x++;}
|
||||
ISR( _VECTOR(69)) {while (1) x++;}
|
||||
ISR( _VECTOR(70)) {while (1) x++;}
|
||||
ISR( _VECTOR(71)) {while (1) x++;}
|
||||
ISR( _VECTOR(72)) {while (1) x++;}
|
||||
ISR( _VECTOR(73)) {while (1) x++;}
|
||||
ISR( _VECTOR(74)) {while (1) x++;}
|
||||
ISR( _VECTOR(75)) {while (1) x++;}
|
||||
ISR( _VECTOR(76)) {while (1) x++;}
|
||||
ISR( _VECTOR(77)) {while (1) x++;}
|
||||
ISR( _VECTOR(78)) {while (1) x++;}
|
||||
ISR( _VECTOR(79)) {while (1) x++;}
|
||||
#endif
|
31
cpu/avr/dev/uart1.h
Normal file
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_SEED_0 CSMA_SEED_0
|
||||
#define RG_PHY_RSSI PHY_RSSI
|
||||
#define SR_CCA_MODE 0x08, 0x60, 5
|
||||
//#define SR_CCA_CS_THRES 0x09, 0xf0, 4
|
||||
#define SR_CCA_ED_THRES 0x09, 0x0f, 0
|
||||
#define SR_CCA_REQUEST 0x08, 0x80, 7
|
||||
#define SR_CCA_DONE 0x01, 0x80, 7
|
||||
#define SR_CCA_STATUS 0x01, 0x40, 6
|
||||
|
||||
|
||||
/* RF230 register assignments, for reference */
|
||||
|
|
|
@ -148,9 +148,12 @@ struct timestamp {
|
|||
#if RADIOSTATS
|
||||
uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
|
||||
#endif
|
||||
|
||||
#if RADIOCALIBRATE
|
||||
/* Set in clock.c every 256 seconds */
|
||||
uint8_t rf230_calibrate;
|
||||
uint8_t rf230_calibrated; //debugging
|
||||
uint8_t rf230_calibrated; //for debugging, prints from main loop when calibration occurs
|
||||
#endif
|
||||
|
||||
/* Track flow through driver, see contiki-raven-main.c for example of use */
|
||||
//#define DEBUGFLOWSIZE 64
|
||||
|
@ -206,8 +209,7 @@ static int rf230_receiving_packet(void);
|
|||
static int pending_packet(void);
|
||||
static int rf230_cca(void);
|
||||
|
||||
signed char rf230_last_rssi;
|
||||
uint8_t rf230_last_correlation;
|
||||
uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
|
||||
|
||||
const struct radio_driver rf230_driver =
|
||||
{
|
||||
|
@ -700,6 +702,27 @@ rf230_init(void)
|
|||
PRINTF("rf230: Unsupported manufacturer ID %u\n",tmanu);
|
||||
|
||||
PRINTF("rf230: Version %u, ID %u\n",tvers,tmanu);
|
||||
|
||||
rf230_warm_reset();
|
||||
|
||||
/* Start the packet receive process */
|
||||
process_start(&rf230_process, NULL);
|
||||
|
||||
/* Leave radio in on state (?)*/
|
||||
on();
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Used to reinitialize radio parameters without losing pan and mac address, channel, power, etc. */
|
||||
void rf230_warm_reset(void) {
|
||||
#if RF230_CONF_SNEEZER && JACKDAW
|
||||
/* Take jackdaw radio out of test mode */
|
||||
#warning Manipulating PORTB pins for RF230 Sneezer mode!
|
||||
PORTB &= ~(1<<7);
|
||||
DDRB &= ~(1<<7);
|
||||
#endif
|
||||
|
||||
hal_register_write(RG_IRQ_MASK, RF230_SUPPORTED_INTERRUPT_MASK);
|
||||
|
||||
/* Set up number of automatic retries 0-15 (0 implies PLL_ON sends instead of the extended TX_ARET mode */
|
||||
|
@ -711,6 +734,24 @@ rf230_init(void)
|
|||
hal_register_write(RG_CSMA_SEED_0,hal_register_read(RG_PHY_RSSI) );//upper two RSSI reg bits RND_VALUE are random in rf231
|
||||
// hal_register_write(CSMA_SEED_1,42 );
|
||||
|
||||
/* CCA Mode Mode 1=Energy above threshold 2=Carrier sense only 3=Both 0=Either (RF231 only) */
|
||||
//hal_subregister_write(SR_CCA_MODE,1); //1 is the power-on default
|
||||
|
||||
/* Carrier sense threshold (not implemented in RF230 or RF231) */
|
||||
// hal_subregister_write(SR_CCA_CS_THRES,1);
|
||||
|
||||
/* CCA energy threshold = -91dB + 2*SR_CCA_ED_THRESH. Reset defaults to -77dB */
|
||||
/* Use RF230 base of -91; RF231 base is -90 according to datasheet */
|
||||
#if RF230_CONF_CCA_THRES < -91
|
||||
#warning RF230_CONF_CCA_THRES below hardware limit, setting to -91dBm
|
||||
hal_subregister_write(SR_CCA_ED_THRES,0);
|
||||
#elif RF230_CONF_CCA_THRES > -61
|
||||
#warning RF230_CONF_CCA_THRES above hardware limit, setting to -61dBm
|
||||
hal_subregister_write(SR_CCA_ED_THRES,15);
|
||||
#else
|
||||
hal_subregister_write(SR_CCA_ED_THRES,(RF230_CONF_CCA_THRES+91)/2);
|
||||
#endif
|
||||
|
||||
/* Use automatic CRC unless manual is specified */
|
||||
#if RF230_CONF_CHECKSUM
|
||||
hal_subregister_write(SR_TX_AUTO_CRC_ON, 0);
|
||||
|
@ -718,19 +759,10 @@ rf230_init(void)
|
|||
hal_subregister_write(SR_TX_AUTO_CRC_ON, 1);
|
||||
#endif
|
||||
|
||||
/* Start the packet receive process */
|
||||
process_start(&rf230_process, NULL);
|
||||
|
||||
/* Limit tx power for testing miniature Raven mesh */
|
||||
#ifdef RF230_MAX_TX_POWER
|
||||
set_txpower(RF230_MAX_TX_POWER); //0=3dbm 15=-17.2dbm
|
||||
#endif
|
||||
|
||||
/* Leave radio in on state (?)*/
|
||||
on();
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH+AUX_LEN];
|
||||
|
@ -758,6 +790,7 @@ rf230_transmit(unsigned short payload_len)
|
|||
// delay_us(TIME_SLEEP_TO_TRX_OFF);
|
||||
RF230_sleeping=0;
|
||||
} else {
|
||||
#if RADIOCALIBRATE
|
||||
/* If on, do periodic calibration. See clock.c */
|
||||
if (rf230_calibrate) {
|
||||
hal_subregister_write(SR_PLL_CF_START,1); //takes 80us max
|
||||
|
@ -766,6 +799,7 @@ rf230_transmit(unsigned short payload_len)
|
|||
rf230_calibrated=1;
|
||||
delay_us(80); //?
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Wait for any previous operation or state transition to finish */
|
||||
|
@ -878,7 +912,6 @@ rf230_transmit(unsigned short payload_len)
|
|||
}
|
||||
|
||||
RELEASE_LOCK();
|
||||
|
||||
if (tx_result==1) { //success, data pending from adressee
|
||||
tx_result=0; //Just show success?
|
||||
} else if (tx_result==3) { //CSMA channel access failure
|
||||
|
@ -1327,6 +1360,10 @@ if (RF230_receive_on) {
|
|||
#endif
|
||||
#endif /* speed vs. generality */
|
||||
|
||||
/* Save the smallest rssi. The display routine can reset by setting it to zero */
|
||||
if ((rf230_smallest_rssi==0) || (rf230_last_rssi<rf230_smallest_rssi))
|
||||
rf230_smallest_rssi=rf230_last_rssi;
|
||||
|
||||
// rf230_last_correlation = rxframe[rxframe_head].lqi;
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf230_last_rssi);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf230_last_correlation);
|
||||
|
@ -1446,10 +1483,18 @@ rf230_cca(void)
|
|||
rf230_on();
|
||||
}
|
||||
|
||||
// cca = CCA_IS_1;
|
||||
DEBUGFLOW('c');
|
||||
cca=1;
|
||||
/* CCA Mode Mode 1=Energy above threshold 2=Carrier sense only 3=Both 0=Either (RF231 only) */
|
||||
/* Use the current mode. Note triggering a manual CCA is not recommended in extended mode */
|
||||
//hal_subregister_write(SR_CCA_MODE,1);
|
||||
|
||||
/* Start the CCA, wait till done, return result */
|
||||
hal_subregister_write(SR_CCA_REQUEST,1);
|
||||
delay_us(TIME_CCA);
|
||||
//while ((hal_register_read(RG_TRX_STATUS) & 0x80) == 0 ) {continue;}
|
||||
while (!hal_subregister_read(SR_CCA_DONE)) {continue;}
|
||||
cca=hal_subregister_read(SR_CCA_STATUS);
|
||||
|
||||
if(radio_was_off) {
|
||||
rf230_off();
|
||||
}
|
||||
|
@ -1476,4 +1521,46 @@ pending_packet(void)
|
|||
return pending;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if RF230_CONF_SNEEZER && JACKDAW
|
||||
/* See A.2 in the datasheet for the sequence needed.
|
||||
* This version for RF230 only, hence Jackdaw.
|
||||
* A full reset seems not necessary and allows keeping the pan address, etc.
|
||||
* for an easy reset back to network mode.
|
||||
*/
|
||||
void rf230_start_sneeze(void) {
|
||||
//write buffer with random data for uniform spectral noise
|
||||
|
||||
//uint8_t txpower = hal_register_read(0x05); //save auto_crc bit and power
|
||||
// hal_set_rst_low();
|
||||
// hal_set_slptr_low();
|
||||
// delay_us(TIME_RESET);
|
||||
// hal_set_rst_high();
|
||||
hal_register_write(0x0E, 0x01);
|
||||
hal_register_write(0x02, 0x03);
|
||||
hal_register_write(0x03, 0x10);
|
||||
// hal_register_write(0x08, 0x20+26); //channel 26
|
||||
hal_subregister_write(SR_CCA_MODE,1); //leave channel unchanged
|
||||
|
||||
// hal_register_write(0x05, 0x00); //output power maximum
|
||||
hal_subregister_write(SR_TX_AUTO_CRC_ON, 0); //clear AUTO_CRC, leave output power unchanged
|
||||
|
||||
hal_register_read(0x01); //should be trx-off state=0x08
|
||||
hal_frame_write(buffer, 127); //maximum length, random for spectral noise
|
||||
|
||||
hal_register_write(0x36,0x0F); //configure continuous TX
|
||||
hal_register_write(0x3D,0x00); //Modulated frame, other options are:
|
||||
// hal_register_write(RG_TX_2,0x10); //CW -2MHz
|
||||
// hal_register_write(RG_TX_2,0x80); //CW -500KHz
|
||||
// hal_register_write(RG_TX_2,0xC0); //CW +500KHz
|
||||
|
||||
DDRB |= 1<<7; //Raven USB stick has PB7 connected to the RF230 TST pin.
|
||||
PORTB |= 1<<7; //Raise it to enable continuous TX Test Mode.
|
||||
|
||||
hal_register_write(0x02,0x09); //Set TRX_STATE to PLL_ON
|
||||
delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE);
|
||||
delay_us(TIME_PLL_LOCK);
|
||||
delay_us(TIME_PLL_LOCK);
|
||||
// while (hal_register_read(0x0f)!=1) {continue;} //wait for pll lock-hangs
|
||||
hal_register_write(0x02,0x02); //Set TRX_STATE to TX_START
|
||||
}
|
||||
#endif
|
|
@ -202,6 +202,8 @@ typedef void (*radio_rx_callback) (uint16_t data);
|
|||
const struct radio_driver rf230_driver;
|
||||
|
||||
int rf230_init(void);
|
||||
void rf230_warm_reset(void);
|
||||
void rf230_start_sneeze(void);
|
||||
//int rf230_on(void);
|
||||
//int rf230_off(void);
|
||||
void rf230_set_channel(uint8_t channel);
|
||||
|
@ -214,8 +216,7 @@ uint8_t rf230_get_txpower(void);
|
|||
void rf230_set_promiscuous_mode(bool isPromiscuous);
|
||||
bool rf230_is_ready_to_send();
|
||||
|
||||
extern signed char rf230_last_rssi;
|
||||
extern uint8_t rf230_last_correlation;
|
||||
extern uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
|
||||
|
||||
uint8_t rf230_get_raw_rssi(void);
|
||||
|
||||
|
@ -223,4 +224,4 @@ uint8_t rf230_get_raw_rssi(void);
|
|||
|
||||
#endif
|
||||
/** @} */
|
||||
/*EOF*/
|
||||
/*EOF*/
|
|
@ -28,45 +28,92 @@
|
|||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* @(#)$Id: watchdog.c,v 1.3 2010/12/18 20:51:11 dak664 Exp $
|
||||
*/
|
||||
|
||||
/* Dummy watchdog routines for the Raven 1284p */
|
||||
/* Watchdog routines for the AVR */
|
||||
|
||||
/* The default timeout of 2 seconds works on most MCUs.
|
||||
* It should be disabled during sleep (unless used for wakeup) since
|
||||
* it draws significant current (~5 uamp on 1284p, 20x the MCU consumption).
|
||||
*
|
||||
* Note the wdt is not properly simulated in AVR Studio 4 Simulator 1:
|
||||
* On many devices calls to wdt_reset will have no effect, and a wdt reboot will occur.
|
||||
* The MCUSR will not show the cause of a wdt reboot.
|
||||
* A 1MHz clock is assumed; at 8MHz timeout occurs 8x faster than it should.
|
||||
* Simulator 2 is supposed to work on supported devices (not atmega128rfa1),
|
||||
* but neither it nor Studio 5 beta do any resets on the 1284p.
|
||||
*
|
||||
* Setting WATCHDOG_CONF_TIMEOUT -1 will disable the WDT.
|
||||
*/
|
||||
//#define WATCHDOG_CONF_TIMEOUT -1
|
||||
|
||||
#ifndef WATCHDOG_CONF_TIMEOUT
|
||||
#define WATCHDOG_CONF_TIMEOUT WDTO_2S
|
||||
#endif
|
||||
|
||||
/* While balancing start and stop calls is a good idea, an imbalance will cause
|
||||
* resets that can take a lot of time to track down.
|
||||
* Some low power protocols may cause this.
|
||||
* The default is no balance; define WATCHDOG_CONF_BALANCE 1 to override.
|
||||
*/
|
||||
#ifndef WATCHDOG_CONF_BALANCE
|
||||
#define WATCHDOG_CONF_BALANCE 0
|
||||
#endif
|
||||
|
||||
#include "dev/watchdog.h"
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#if WATCHDOG_CONF_BALANCE && WATCHDOG_CONF_TIMEOUT >= 0
|
||||
static int stopped = 0;
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_init(void)
|
||||
{
|
||||
/* Clear startup bit and disable the wdt, whether or not it will be used.
|
||||
Random code may have caused the last reset.
|
||||
*/
|
||||
MCUSR&=~(1<<WDRF);
|
||||
stopped = 0;
|
||||
watchdog_stop();
|
||||
wdt_disable();
|
||||
#if WATCHDOG_CONF_BALANCE && WATCHDOG_CONF_TIMEOUT >= 0
|
||||
stopped = 1;
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_start(void)
|
||||
{
|
||||
#if WATCHDOG_CONF_TIMEOUT >= 0
|
||||
#if WATCHDOG_CONF_BALANCE
|
||||
stopped--;
|
||||
// if(!stopped)
|
||||
wdt_enable(WDTO_2S);
|
||||
if(!stopped)
|
||||
#endif
|
||||
wdt_enable(WATCHDOG_CONF_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_periodic(void)
|
||||
{
|
||||
// if(!stopped)
|
||||
#if WATCHDOG_CONF_TIMEOUT >= 0
|
||||
#if WATCHDOG_CONF_BALANCE
|
||||
if(!stopped)
|
||||
#endif
|
||||
wdt_reset();
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_stop(void)
|
||||
{
|
||||
// stopped++;
|
||||
#if WATCHDOG_CONF_TIMEOUT >= 0
|
||||
#if WATCHDOG_CONF_BALANCE
|
||||
stopped++;
|
||||
#endif
|
||||
wdt_disable();
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -77,3 +124,9 @@ watchdog_reboot(void)
|
|||
while(1); //loop
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if 0
|
||||
/* Not all AVRs implement the wdt interrupt */
|
||||
ISR(WDT_vect)
|
||||
{
|
||||
}
|
||||
#endif
|
|
@ -72,7 +72,12 @@ CUSTOM_RULE_C_TO_O=yes
|
|||
CFLAGS += -I$(OBJECTDIR) -I$(CONTIKI_CPU)/board -DBOARD=$(TARGET)
|
||||
|
||||
$(OBJECTDIR)/board.h: $(OBJECTDIR)
|
||||
ifneq (,$(findstring Windows,$(OS)))
|
||||
${info Cygwin detected.}
|
||||
ln -f $(CONTIKI_CPU)/board/$(TARGET).h $(OBJECTDIR)/board.h
|
||||
else
|
||||
ln -sf ../$(CONTIKI_CPU)/board/$(TARGET).h $(OBJECTDIR)/board.h
|
||||
endif
|
||||
|
||||
|
||||
$(OBJECTDIR)/isr.o: $(CONTIKI_CPU)/src/isr.c
|
||||
|
@ -85,8 +90,6 @@ $(OBJECTDIR)/%.o: %.c
|
|||
$(CC) $(CFLAGS) $(THUMB_FLAGS) -c $< -o $@
|
||||
|
||||
CUSTOM_RULE_S_TO_OBJECTDIR_O = yes
|
||||
%.o: %.S
|
||||
$(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c
|
||||
|
||||
$(OBJECTDIR)/%.o: %.S
|
||||
$(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c -o $@
|
||||
|
|
138
cpu/mc1322x/lib/adc.c
Normal file
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);
|
||||
|
||||
/* COP watchdog timer helpers */
|
||||
|
||||
/* set the cop timout in milliseconds */
|
||||
#define cop_timeout_ms(x) (CRM->COP_CNTLbits.COP_TIMEOUT = x/87)
|
||||
#define cop_service() (CRM->COP_SERVICE = 0xc0de5afe)
|
||||
|
||||
/* Old register definitions, for compatibility */
|
||||
#ifndef REG_NO_COMPAT
|
||||
|
|
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 asm_isr(void) __attribute__((weak));
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -121,8 +121,8 @@ enum {
|
|||
#define LFSR 6 /* 1 use polynomial for Turbolink */
|
||||
#define TM 5
|
||||
|
||||
#define MODE 3
|
||||
#define MODE_MASK bit_mask(2,MODE)
|
||||
#define MACA_MODE 3
|
||||
#define MODE_MASK bit_mask(2,MACA_MODE)
|
||||
#define NO_CCA 0
|
||||
#define NO_SLOT_CCA 1
|
||||
#define SLOT_CCA 2
|
||||
|
|
|
@ -46,5 +46,6 @@
|
|||
#include "packet.h"
|
||||
#include "uart1.h"
|
||||
#include "utils.h"
|
||||
#include "asm.h"
|
||||
|
||||
#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 */
|
||||
*MACA_CONTROL =
|
||||
(prm_mode << PRM) |
|
||||
(NO_CCA << MODE);
|
||||
(NO_CCA << MACA_MODE);
|
||||
|
||||
enable_irq(MACA);
|
||||
*INTFRC = (1 << INT_NUM_MACA);
|
||||
|
@ -368,7 +368,9 @@ void post_receive(void) {
|
|||
( 4 << PRECOUNT) |
|
||||
( fcs_mode << NOFC ) |
|
||||
( prm_mode << PRM) |
|
||||
#if 0 //dak says removing ctrl auto fixes the autoack checksum error --- doesn't cause a performance issue either
|
||||
(1 << maca_ctrl_auto) |
|
||||
#endif
|
||||
(maca_ctrl_seq_rx));
|
||||
/* status bit 10 is set immediately */
|
||||
/* then 11, 10, and 9 get set */
|
||||
|
|
254
cpu/mc1322x/lib/pwm.c
Normal file
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;
|
||||
ABT_STACK_SIZE = 16;
|
||||
UND_STACK_SIZE = 16;
|
||||
HEAP_SIZE = 1024;
|
||||
HEAP_SIZE = 4096;
|
||||
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = 0x00400000); . = 0x00400000;
|
||||
|
|
|
@ -87,6 +87,9 @@ void irq(void)
|
|||
cal_isr();
|
||||
}
|
||||
}
|
||||
if(bit_is_set(pending, INT_NUM_ASM)) {
|
||||
if(asm_isr != 0) { asm_isr(); }
|
||||
}
|
||||
|
||||
*INTFRC = 0; /* stop forcing interrupts */
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ TARGETS := blink-red blink-green blink-blue blink-white blink-allio \
|
|||
uart1-loopback \
|
||||
tmr tmr-ints \
|
||||
sleep \
|
||||
printf
|
||||
printf \
|
||||
asm \
|
||||
adc \
|
||||
pwm \
|
||||
wdt
|
||||
|
||||
# these targets are built with space reserved for variables needed by ROM services
|
||||
# this space is initialized with a rom call to rom_data_init
|
||||
|
|
63
cpu/mc1322x/tests/adc.c
Normal file
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,
|
||||
'terminal=s' => \$term,
|
||||
'verbose' => \$verbose,
|
||||
'baud=s' => \$baud,
|
||||
'u|baud=s' => \$baud,
|
||||
'rts=s' => \$rts,
|
||||
'command=s' => \$command,
|
||||
'a=s' => \$first_delay,
|
||||
|
@ -41,8 +41,8 @@ if($filename eq '') {
|
|||
print " -f required: binary file to load\n";
|
||||
print " -s optional: secondary binary file to send\n";
|
||||
print " -z optional: send a zero length file as secondary\n";
|
||||
print " -t terminal default: /dev/ttyUSB0\n";
|
||||
print " -b baud rate default: 115200\n";
|
||||
print " -t, terminal default: /dev/ttyUSB0\n";
|
||||
print " -u, --baud baud rate default: 115200\n";
|
||||
print " -r [none|rts] flow control default: rts\n";
|
||||
print " -c command to run for autoreset: \n";
|
||||
print " e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n";
|
||||
|
|
|
@ -5,11 +5,14 @@ my $bin = shift;
|
|||
my $terms = shift;
|
||||
|
||||
my $addr = "0x1e000";
|
||||
my $company_id;
|
||||
my $iab = 0xabc; # Redwire, LLC's IAB
|
||||
my $iab = 0xa8c; # Redwire, LLC's IAB
|
||||
|
||||
my $mac_h;
|
||||
my $mac_l;
|
||||
|
||||
if(defined($iab)) {
|
||||
$company_id = (0x0050C2 << 12) | $iab;
|
||||
$mac_h = 0x0050C200 | ($iab >> 4);
|
||||
$mac_l = ($iab & 0xf) << 28;
|
||||
}
|
||||
|
||||
if (! $terms) {
|
||||
|
@ -19,15 +22,17 @@ if (! $terms) {
|
|||
|
||||
for (my $t=0; $t<$terms; $t++) {
|
||||
my $dev_num = 2 * $t + 1;
|
||||
$mac_l |= $dev_num;
|
||||
#stupid 32-bit thing...
|
||||
my $mac;
|
||||
if(defined($iab)) {
|
||||
$mac = ($company_id << 28) | $dev_num;
|
||||
} else {
|
||||
$mac = ($company_id << 40) | $dev_num;
|
||||
}
|
||||
printf("mac_h %x\n", $mac_h);
|
||||
printf("mac_l %x\n", $mac_l);
|
||||
my @words;
|
||||
for(my $i=0; $i<8; $i++) {
|
||||
push @words, ($mac >> ($i * 8)) & 0xff;
|
||||
for(my $i=0; $i<4; $i++) {
|
||||
push @words, ($mac_h >> ($i * 8)) & 0xff;
|
||||
}
|
||||
for(my $i=0; $i<4; $i++) {
|
||||
push @words, ($mac_l >> ($i * 8)) & 0xff;
|
||||
}
|
||||
reverse @words;
|
||||
foreach my $byte (@words) {
|
||||
|
|
|
@ -111,7 +111,7 @@ loader_arch_load(unsigned short startaddr)
|
|||
/* If the checksum was wrong, we beep. The number of beeps indicate
|
||||
the numerival value of the calculated checksum. */
|
||||
if(sum != 0xff) {
|
||||
leds_red(LEDS_ON);
|
||||
leds_on(LEDS_RED);
|
||||
|
||||
for(i = 0; i < (sum >> 4); ++i) {
|
||||
beep_beep(200);
|
||||
|
@ -131,23 +131,23 @@ loader_arch_load(unsigned short startaddr)
|
|||
}
|
||||
}
|
||||
|
||||
leds_red(LEDS_OFF);
|
||||
leds_off(LEDS_RED);
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
leds_green(LEDS_ON);
|
||||
leds_on(LEDS_GREEN);
|
||||
for(i = 0; i < 4; ++i) {
|
||||
beep_beep(200);
|
||||
for(j = 0; j < 2; ++j) {
|
||||
clock_delay(60000);
|
||||
}
|
||||
}
|
||||
leds_green(LEDS_OFF);
|
||||
leds_off(LEDS_GREEN);
|
||||
}
|
||||
|
||||
|
||||
leds_yellow(LEDS_ON);
|
||||
leds_on(LEDS_YELLOW);
|
||||
startaddr += 2;
|
||||
|
||||
/* Read the size of the code segment from the next two bytes in EEPROM. */
|
||||
|
@ -185,9 +185,9 @@ loader_arch_load(unsigned short startaddr)
|
|||
|
||||
flash_done();
|
||||
|
||||
leds_yellow(LEDS_OFF);
|
||||
leds_off(LEDS_YELLOW);
|
||||
|
||||
leds_green(LEDS_ON);
|
||||
leds_on(LEDS_GREEN);
|
||||
|
||||
/* Read the size of the code segment from the first two bytes in EEPROM. */
|
||||
eeprom_read(startaddr + 2 + codelen, (char *)&datalen, 2);
|
||||
|
@ -205,7 +205,7 @@ loader_arch_load(unsigned short startaddr)
|
|||
clock_delay(20000);
|
||||
}
|
||||
|
||||
leds_green(LEDS_OFF);
|
||||
leds_off(LEDS_GREEN);
|
||||
|
||||
/* Execute the loaded program. */
|
||||
init = ((void (*)(void *))FLASHADDR);
|
||||
|
|
|
@ -45,9 +45,9 @@ ifdef IAR
|
|||
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library.a
|
||||
else
|
||||
ifdef PRINTF_FLOAT
|
||||
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library.a $(CONTIKI_CPU)/hal/micro/cortexm3/e_stdio_thumb2.a
|
||||
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library-gnu.a $(CONTIKI_CPU)/hal/micro/cortexm3/e_stdio_thumb2.a
|
||||
else
|
||||
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library.a $(CONTIKI_CPU)/hal/micro/cortexm3/e_stdio_intonly_thumb2.a
|
||||
TARGET_LIBFILES = $(CONTIKI_CPU)/simplemac/library/simplemac-library-gnu.a $(CONTIKI_CPU)/lib/e_stdio_intonly_thumb2.a
|
||||
endif
|
||||
endif
|
||||
# `$(CC) -print-file-name=thumb2/libc.a` `$(CC) -print-file-name=thumb2/libgcc.a`
|
||||
|
@ -74,7 +74,7 @@ AROPTS = --create
|
|||
ASFLAGS = -s+ -w+ --cpu Cortex-M3 -L$(OBJECTDIR)
|
||||
LDFLAGS += --redirect _Printf=_PrintfSmall --redirect _Scanf=_ScanfSmall --map=contiki-$(TARGET).map
|
||||
ifndef COFFEE
|
||||
LDFLAGS+= --config $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/iar-cfg.icf
|
||||
LDFLAGS+= --config $(CONTIKI_CPU)/iar-cfg.icf
|
||||
endif
|
||||
OBJOPTS = --bin
|
||||
|
||||
|
@ -101,7 +101,7 @@ ASFLAGS = -mthumb -mcpu=cortex-m3 -fsigned-char -c -g -Wall -Os -ffunction-secti
|
|||
-mlittle-endian -fshort-enums -x assembler-with-cpp -Wa,-EL
|
||||
LDFLAGS += -mcpu=cortex-m3 \
|
||||
-mthumb \
|
||||
-Wl,-T -Xlinker $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/gnu.ld \
|
||||
-Wl,-T -Xlinker $(CONTIKI_CPU)/gnu.ld \
|
||||
-Wl,-static \
|
||||
-u Default_Handler \
|
||||
-nostartfiles \
|
||||
|
@ -118,8 +118,6 @@ OBJOPTS = -O binary
|
|||
endif
|
||||
|
||||
|
||||
ifndef IAR
|
||||
|
||||
ifdef COFFEE_ADDRESS
|
||||
COFFEE = 1
|
||||
endif
|
||||
|
@ -147,15 +145,18 @@ ifeq ($(COFFEE),1)
|
|||
|
||||
else
|
||||
# Coffee starts at the end of the flash, before NVM section.
|
||||
COFFEE_ADDRESS = 0x801F400
|
||||
COFFEE_ADDRESS = 0x801F800
|
||||
endif
|
||||
|
||||
|
||||
ifndef IAR
|
||||
|
||||
LDFLAGS+= -Wl,--section-start=.coffee=$(COFFEE_ADDRESS)
|
||||
|
||||
else #IAR
|
||||
|
||||
ifeq ($(COFFEE),1)
|
||||
LDFLAGS+= --config $(CONTIKI_CPU)/hal/micro/cortexm3/stm32w108/iar-cfg-coffee.icf
|
||||
LDFLAGS+= --config $(CONTIKI_CPU)/iar-cfg-coffee.icf
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
/* If using IAR, COFFEE_ADDRESS reflects the static value in the linker script
|
||||
iar-cfg-coffee.icf, so it can't be passed as a parameter for Make.*/
|
||||
#ifdef __ICCARM__
|
||||
#define COFFEE_ADDRESS 0x8010000
|
||||
#define COFFEE_ADDRESS 0x8010c00
|
||||
#endif
|
||||
#if (COFFEE_ADDRESS & 0x3FF) !=0
|
||||
#error "COFFEE_ADDRESS not aligned to a 1024-bytes page boundary."
|
||||
|
@ -96,9 +96,10 @@
|
|||
#define COFFEE_LOG_SIZE 128 // COFFEE_MICRO_LOGS is 0.
|
||||
|
||||
|
||||
#if COFFEE_PAGES <= 0x100
|
||||
#define coffee_page_t uint8_t
|
||||
#elif COFFEE_PAGES <= 0x10000
|
||||
#if COFFEE_PAGES <= 127
|
||||
#define coffee_page_t int8_t
|
||||
#elif COFFEE_PAGES <= 0x7FFF
|
||||
#define coffee_page_t int16_t
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
||||
* File Name : stm32f10x_conf.h
|
||||
* File Name : stm32w_conf.h
|
||||
* Author : MCD Application Team
|
||||
* Version : V2.0.3
|
||||
* Date : 09/22/2008
|
||||
|
@ -18,7 +18,7 @@
|
|||
#define __STM32F10x_CONF_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32w_type.h"
|
||||
#include "stm32w108_type.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
||||
* File Name : stm32f10x_systick.c
|
||||
* File Name : stm32w108_systick.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V2.0.3
|
||||
* Date : 09/22/2008
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef __STM32W_SYSTICK_H
|
||||
#define __STM32W_SYSTICK_H
|
||||
|
||||
#include "stm32w_type.h"
|
||||
#include "stm32w108_type.h"
|
||||
#include "stm32w_conf.h"
|
||||
|
||||
#ifndef EXT
|
||||
|
|
|
@ -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