From a3412a0b81fea569dabfad5aba0a812e1c4f56d7 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Wed, 6 Apr 2011 05:53:18 -0400 Subject: [PATCH 1/9] set the UART1 pin directions in uart1_init() patch from Hedde Bosman --- src/default_lowlevel.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/default_lowlevel.c b/src/default_lowlevel.c index 918567bbe..452771085 100644 --- a/src/default_lowlevel.c +++ b/src/default_lowlevel.c @@ -50,6 +50,14 @@ void uart1_init(uint16_t inc, uint16_t mod, uint8_t samp) { *UART1_UCON = 0; *UART1_UBRCNT = ( inc << 16 ) | mod; + /* TX and CTS as outputs */ + GPIO->PAD_DIR_SET.GPIO_14 = 1; + GPIO->PAD_DIR_SET.GPIO_16 = 1; + + /* RX and RTS as inputs */ + GPIO->PAD_DIR_RESET.GPIO_15 = 1; + GPIO->PAD_DIR_RESET.GPIO_17 = 1; + /* see Section 11.5.1.2 Alternate Modes */ /* you must enable the peripheral first BEFORE setting the function in GPIO_FUNC_SEL */ /* From the datasheet: "The peripheral function will control operation of the pad IF */ From 928bf6b6c13bf8de81ac78499a56830b9b04bdfb Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Wed, 6 Apr 2011 20:08:48 +0200 Subject: [PATCH 2/9] fixed cpu/msp430 for compilation with IAR compiler --- cpu/msp430/Makefile.msp430 | 44 +++++++++++++++++++++++++++++++++++--- cpu/msp430/dev/hwconf.h | 7 ++++++ cpu/msp430/dev/lpm.h | 1 - cpu/msp430/flash.c | 8 ++++++- cpu/msp430/msp430def.h | 4 ++++ cpu/msp430/mtarch.c | 10 +++++++++ cpu/msp430/mtarch.h | 2 +- cpu/msp430/rtimer-arch.c | 6 ++++++ cpu/msp430/rtimer-arch.h | 1 - 9 files changed, 76 insertions(+), 7 deletions(-) diff --git a/cpu/msp430/Makefile.msp430 b/cpu/msp430/Makefile.msp430 index 599a7cf01..870e3137f 100644 --- a/cpu/msp430/Makefile.msp430 +++ b/cpu/msp430/Makefile.msp430 @@ -25,6 +25,40 @@ CONTIKI_TARGET_SOURCEFILES += $(MSP430) \ CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) ### Compiler definitions +ifdef IAR +CC = icc430 +LD = xlink +AS = iasm430 +AR = xar +OBJCOPY = ielftool +STRIP = strip + + +ifndef IAR_PATH +# This works with cygwin... +IAR_BIN_PATH = $(shell dirname `which $(CC)`) +IAR_PATH_C = $(shell dirname $(IAR_BIN_PATH)) +IAR_PATH = $(shell cygpath -m $(IAR_PATH_C)) +endif + +CFLAGSNO = --dlib_config $(IAR_PATH)/LIB/DLIB/dl430xlfn.h -Ohz --multiplier=32 --multiplier_location=4C0 --hw_workaround=CPU40 --core=430X $(CFLAGSWERROR) --data_model large --double=32 +CUSTOM_RULE_C_TO_O = 1 +%.o: %.c + $(CC) $(CFLAGS) $< -o $@ + +CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 +$(OBJECTDIR)/%.o: %.c + $(CC) $(CFLAGS) $< -o $@ +# @$(FINALIZE_DEPENDENCY) +CUSTOM_RULE_C_TO_CO = 1 +%.co: %.c + $(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@ + +AROPTS = -o +LDFLAGS += -B $(IAR_PATH)/lib/dlib/dl430xlfn.r43 -f $(IAR_PATH)/config/lnk430f5437.xcl -l contiki-$(TARGET).map -Fintel-extended -s __program_start + +else +GCC = 1 CC = msp430-gcc LD = msp430-gcc AS = msp430-as @@ -33,12 +67,16 @@ NM = msp430-nm OBJCOPY = msp430-objcopy STRIP = msp430-strip BSL = msp430-bsl -ifdef WERROR -CFLAGSWERROR=-Werror -endif CFLAGSNO = -Wall -mmcu=$(MCU) -g $(CFLAGSWERROR) CFLAGS += $(CFLAGSNO) -Os LDFLAGS += -mmcu=$(MCU) -Wl,-Map=contiki-$(TARGET).map +endif + +ifdef WERROR +CFLAGSWERROR=-Werror +endif + +CFLAGS += $(CFLAGSNO) ### These flags can reduce the code size and RAM usage with up to 10% diff --git a/cpu/msp430/dev/hwconf.h b/cpu/msp430/dev/hwconf.h index 34d850f06..9c764c5b9 100644 --- a/cpu/msp430/dev/hwconf.h +++ b/cpu/msp430/dev/hwconf.h @@ -35,7 +35,14 @@ #include "sys/cc.h" +#ifdef __GNUC__ #include +#include +#endif + +#ifdef __IAR_SYSTEMS_ICC__ +#include +#endif #define HWCONF_PIN(name, port, bit) \ static CC_INLINE void name##_SELECT() {P##port##SEL &= ~(1 << bit);} \ diff --git a/cpu/msp430/dev/lpm.h b/cpu/msp430/dev/lpm.h index b921aaf59..f68d7b207 100644 --- a/cpu/msp430/dev/lpm.h +++ b/cpu/msp430/dev/lpm.h @@ -33,7 +33,6 @@ #ifndef __LPM_H__ #define __LPM_H__ -#include #include "contiki-conf.h" #ifdef LPM_CONF_ON diff --git a/cpu/msp430/flash.c b/cpu/msp430/flash.c index 50ff315a2..febe777d1 100644 --- a/cpu/msp430/flash.c +++ b/cpu/msp430/flash.c @@ -35,9 +35,15 @@ * */ -#include +#include "contiki.h" +#ifdef __IAR_SYSTEMS_ICC__ +#include +#else +#include #include #include +#endif + #include "dev/flash.h" #include "dev/watchdog.h" diff --git a/cpu/msp430/msp430def.h b/cpu/msp430/msp430def.h index 77bc48999..ca2a7b4f6 100644 --- a/cpu/msp430/msp430def.h +++ b/cpu/msp430/msp430def.h @@ -69,7 +69,11 @@ void splx_(spl_t); spl_t splhigh_(void); #define splhigh() splhigh_() +#ifdef __IAR_SYSTEMS_ICC__ +#define splx(sr) sr = __get_SR_register() +#else #define splx(sr) __asm__ __volatile__("bis %0, r2" : : "r" (sr)) +#endif /* Workaround for bug in msp430-gcc compiler */ #if defined(__MSP430__) && defined(__GNUC__) && MSP430_MEMCPY_WORKAROUND diff --git a/cpu/msp430/mtarch.c b/cpu/msp430/mtarch.c index 0a184ab2f..59e9f0694 100644 --- a/cpu/msp430/mtarch.c +++ b/cpu/msp430/mtarch.c @@ -34,6 +34,10 @@ #include #include "sys/mt.h" +#ifdef __IAR_SYSTEMS_ICC__ +#define __asm__ asm +#endif + static unsigned short *sptmp; static struct mtarch_thread *running; @@ -97,8 +101,14 @@ sw(void) __asm__("push r14"); __asm__("push r15"); +#ifdef __IAR_SYSTEMS_ICC__ +/* use IAR intrinsic functions */ + running->sp = (unsigned short *) __get_SP_register(); + __set_SP_register((unsigned short) sptmp); +#else __asm__("mov.w r1,%0" : "=r" (running->sp)); __asm__("mov.w %0,r1" : : "m" (sptmp)); +#endif __asm__("pop r15"); __asm__("pop r14"); diff --git a/cpu/msp430/mtarch.h b/cpu/msp430/mtarch.h index fd9cc9557..68913d866 100644 --- a/cpu/msp430/mtarch.h +++ b/cpu/msp430/mtarch.h @@ -39,7 +39,7 @@ struct mtarch_thread { unsigned short stack[MTARCH_STACKSIZE]; unsigned short *sp; void *data; - void *function; + void (* function)(void *); }; struct mt_thread; diff --git a/cpu/msp430/rtimer-arch.c b/cpu/msp430/rtimer-arch.c index 8f2fc49fa..f60dd59e5 100644 --- a/cpu/msp430/rtimer-arch.c +++ b/cpu/msp430/rtimer-arch.c @@ -38,8 +38,14 @@ * Adam Dunkels */ +#ifdef __GNUC__ #include #include +#endif + +#ifdef __IAR_SYSTEMS_ICC__ +#include +#endif #include "sys/energest.h" #include "sys/rtimer.h" diff --git a/cpu/msp430/rtimer-arch.h b/cpu/msp430/rtimer-arch.h index 52c96502c..d90d1e437 100644 --- a/cpu/msp430/rtimer-arch.h +++ b/cpu/msp430/rtimer-arch.h @@ -41,7 +41,6 @@ #ifndef __RTIMER_ARCH_H__ #define __RTIMER_ARCH_H__ -#include #include "sys/rtimer.h" #define RTIMER_ARCH_SECOND (4096U*8) From d8e54ca5853ffe515232d36628e4fc5e216cec54 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Wed, 6 Apr 2011 20:14:30 +0200 Subject: [PATCH 3/9] fixed for compilation with IAR compiler --- core/dev/cc2420-aes.c | 1 + core/dev/cc2420.c | 4 ++++ core/lib/me_tabs.h | 6 +++--- core/net/rpl/rpl-dag.c | 6 +++++- core/net/rpl/rpl-private.h | 5 +++++ core/net/sicslowpan.c | 10 ++++++++-- core/net/uip-ds6.c | 2 +- 7 files changed, 27 insertions(+), 7 deletions(-) diff --git a/core/dev/cc2420-aes.c b/core/dev/cc2420-aes.c index 6ed4020f7..9cf59a901 100644 --- a/core/dev/cc2420-aes.c +++ b/core/dev/cc2420-aes.c @@ -39,6 +39,7 @@ */ #include "contiki.h" +#include "io.h" #include "dev/cc2420.h" #include "dev/cc2420-aes.h" #include "dev/spi.h" diff --git a/core/dev/cc2420.c b/core/dev/cc2420.c index 8e8a1b657..6f3d808f7 100644 --- a/core/dev/cc2420.c +++ b/core/dev/cc2420.c @@ -41,8 +41,12 @@ #if defined(__AVR__) #include #elif defined(__MSP430__) +#ifdef __IAR_SYSTEMS_ICC__ +#include +#else #include #endif +#endif #include "dev/leds.h" #include "dev/spi.h" diff --git a/core/lib/me_tabs.h b/core/lib/me_tabs.h index 2c88cea99..6dce73af5 100644 --- a/core/lib/me_tabs.h +++ b/core/lib/me_tabs.h @@ -33,9 +33,9 @@ #ifndef __ME_TABS_H__ #define __ME_TABS_H__ -const unsigned short me_encode_tab[256]; -const unsigned char me_decode_tab[256]; -const unsigned char me_valid_tab[256]; +extern const unsigned short me_encode_tab[256]; +extern const unsigned char me_decode_tab[256]; +extern const unsigned char me_valid_tab[256]; #endif /* __ME_TABS_H__ */ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 64201ca50..bcd16a514 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -142,6 +142,8 @@ remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank) static int should_send_dao(rpl_dag_t *dag, rpl_dio_t *dio, rpl_parent_t *p) { + /* if MOP is set to no downward routes no DAO should be sent */ + if(dag->mop == RPL_MOP_NO_DOWNWARD_ROUTES) return 0; return dio->dtsn > p->dtsn && p == dag->preferred_parent; } /************************************************************************/ @@ -352,7 +354,9 @@ rpl_select_parent(rpl_dag_t *dag) dag->of->update_metric_container(dag); rpl_set_default_route(dag, &best->addr); /* The DAO parent set changed - schedule a DAO transmission. */ - rpl_schedule_dao(dag); + if(dag->mop != RPL_MOP_NO_DOWNWARD_ROUTES) { + rpl_schedule_dao(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)); diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 764ed940a..4363c55ad 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -170,7 +170,12 @@ #define RPL_MOP_NON_STORING 1 #define RPL_MOP_STORING_NO_MULTICAST 2 #define RPL_MOP_STORING_MULTICAST 3 + +#ifdef RPL_CONF_MOP +#define RPL_MOP_DEFAULT RPL_CONF_MOP +#else #define RPL_MOP_DEFAULT RPL_MOP_STORING_NO_MULTICAST +#endif /* * The ETX in the metric container is expressed as a fixed-point value diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index e58724126..74c0de07e 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -571,7 +571,10 @@ compress_hdr_hc06(rimeaddr_t *rime_destaddr) iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT, &UIP_IP_BUF->srcipaddr, &uip_lladdr); /* No context found for this address */ - } else if(uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) { + } else if(uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) && + UIP_IP_BUF->destipaddr.u16[1] == 0 && + UIP_IP_BUF->destipaddr.u16[2] == 0 && + UIP_IP_BUF->destipaddr.u16[3] == 0) { iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT, &UIP_IP_BUF->srcipaddr, &uip_lladdr); } else { @@ -619,7 +622,10 @@ compress_hdr_hc06(rimeaddr_t *rime_destaddr) iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT, &UIP_IP_BUF->destipaddr, (uip_lladdr_t *)rime_destaddr); /* No context found for this address */ - } else if(uip_is_addr_link_local(&UIP_IP_BUF->destipaddr)) { + } else if(uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) && + UIP_IP_BUF->destipaddr.u16[1] == 0 && + UIP_IP_BUF->destipaddr.u16[2] == 0 && + UIP_IP_BUF->destipaddr.u16[3] == 0) { iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT, &UIP_IP_BUF->destipaddr, (uip_lladdr_t *)rime_destaddr); } else { diff --git a/core/net/uip-ds6.c b/core/net/uip-ds6.c index 7e3cf1882..9d794cc17 100644 --- a/core/net/uip-ds6.c +++ b/core/net/uip-ds6.c @@ -47,7 +47,7 @@ #include "net/uip-ds6.h" #include "net/uip-packetqueue.h" -#define DEBUG DEBUG_NONE +#define DEBUG DEBUG_ANNOTATE #include "net/uip-debug.h" #ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED From 236c459ecf181c11832c5e0eec08173620c49f2f Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Thu, 7 Apr 2011 09:26:12 +0200 Subject: [PATCH 4/9] Added missing include --- platform/esb/dev/irq.c | 1 + platform/esb/dev/radio-sensor.c | 1 + platform/esb/dev/sound-sensor.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/esb/dev/irq.c b/platform/esb/dev/irq.c index 4babd2edc..d9efdd084 100644 --- a/platform/esb/dev/irq.c +++ b/platform/esb/dev/irq.c @@ -33,6 +33,7 @@ #include "lib/sensors.h" #include "dev/irq.h" #include "dev/lpm.h" +#include #include #define ADC12MCTL_NO(adcno) ((unsigned char *) ADC12MCTL0_)[adcno] diff --git a/platform/esb/dev/radio-sensor.c b/platform/esb/dev/radio-sensor.c index 898a2ea30..b13c7b345 100644 --- a/platform/esb/dev/radio-sensor.c +++ b/platform/esb/dev/radio-sensor.c @@ -34,6 +34,7 @@ #include "dev/radio-sensor.h" #include "dev/irq.h" #include "dev/tr1001.h" +#include const struct sensors_sensor radio_sensor; diff --git a/platform/esb/dev/sound-sensor.c b/platform/esb/dev/sound-sensor.c index 593c838ce..309f2d9cb 100644 --- a/platform/esb/dev/sound-sensor.c +++ b/platform/esb/dev/sound-sensor.c @@ -30,9 +30,10 @@ * * @(#)$Id: sound-sensor.c,v 1.5 2010/02/08 00:00:45 nifi Exp $ */ -#include #include "dev/sound-sensor.h" #include "dev/irq.h" +#include +#include #define MIC_MIN_SENS 150 #define SAMPLE 1 From 5a4a39afb3b33f3664c27c806ba2e581a0e8516d Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Thu, 7 Apr 2011 09:46:37 +0200 Subject: [PATCH 5/9] changed etx to metric --- core/net/neighbor-info.h | 6 +++--- examples/ipv6/rpl-collect/udp-sender.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/net/neighbor-info.h b/core/net/neighbor-info.h index f292c2ef1..0332142f3 100644 --- a/core/net/neighbor-info.h +++ b/core/net/neighbor-info.h @@ -82,10 +82,10 @@ int neighbor_info_subscribe(neighbor_info_subscriber_t); /** - * Get link ETX value for a specific neighbor. + * Get link metric value for a specific neighbor. * - * \return Returns ETX if the neighbor exists, and 0 if not. + * \return Returns link metric if the neighbor exists, and 0 if not. */ -link_metric_t neighbor_info_get_etx(const rimeaddr_t *addr); +link_metric_t neighbor_info_get_metric(const rimeaddr_t *addr); #endif /* NEIGHBOR_INFO_H */ diff --git a/examples/ipv6/rpl-collect/udp-sender.c b/examples/ipv6/rpl-collect/udp-sender.c index 430e55e29..6652f5f0b 100644 --- a/examples/ipv6/rpl-collect/udp-sender.c +++ b/examples/ipv6/rpl-collect/udp-sender.c @@ -136,7 +136,7 @@ collect_common_send(void) nbr = uip_ds6_nbr_lookup(&preferred_parent->addr); if(nbr != NULL) { rimeaddr_copy(&parent, (rimeaddr_t *)&nbr->ipaddr.u8[8]); - parent_etx = neighbor_info_get_etx((rimeaddr_t *) &nbr->lladdr) / 2; + parent_etx = neighbor_info_get_metric((rimeaddr_t *) &nbr->lladdr) / 2; } } rtmetric = dag->rank; From 02fcf5835a77c1169f8840dde0f7ce949d34e7d6 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 7 Apr 2011 17:44:07 +0200 Subject: [PATCH 6/9] fixed RPL to handle inifinite rank better --- core/net/rpl/rpl-dag.c | 12 ++++++++++-- core/net/uip-ds6.c | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index bcd16a514..664422f0a 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -342,13 +342,20 @@ rpl_select_parent(rpl_dag_t *dag) best = NULL; for(p = list_head(dag->parents); p != NULL; p = p->next) { - if(best == NULL) { + if(p->rank == INFINITE_RANK) { + /* ignore this neighbor */ + } else if(best == NULL) { best = p; } else { best = dag->of->best_parent(best, p); } } + if(best == NULL) { + /* need to handle update of best... */ + return NULL; + } + if(dag->preferred_parent != best) { dag->preferred_parent = best; /* Cache the value. */ dag->of->update_metric_container(dag); @@ -642,7 +649,8 @@ rpl_process_parent_event(rpl_dag_t *dag, rpl_parent_t *p) rpl_reset_dio_timer(dag, 1); } - if(!acceptable_rank(dag, dag->of->calculate_rank(NULL, parent_rank))) { + if(parent_rank == INFINITE_RANK || + !acceptable_rank(dag, dag->of->calculate_rank(NULL, parent_rank))) { /* The candidate parent is no longer valid: the rank increase resulting from the choice of it as a parent would be too high. */ return 0; diff --git a/core/net/uip-ds6.c b/core/net/uip-ds6.c index 9d794cc17..7e3cf1882 100644 --- a/core/net/uip-ds6.c +++ b/core/net/uip-ds6.c @@ -47,7 +47,7 @@ #include "net/uip-ds6.h" #include "net/uip-packetqueue.h" -#define DEBUG DEBUG_ANNOTATE +#define DEBUG DEBUG_NONE #include "net/uip-debug.h" #ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED From 581d081ffec4db9d7c4663faee229ee80dc99bd1 Mon Sep 17 00:00:00 2001 From: dak664 Date: Thu, 7 Apr 2011 17:44:10 -0400 Subject: [PATCH 7/9] Don't use RF230_CONF_CCA_THRES if it is not defined. --- cpu/avr/radio/rf230bb/rf230bb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index fc9005704..8383327d4 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -742,14 +742,20 @@ void rf230_warm_reset(void) { /* 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 */ +#ifdef RF230_CONF_CCA_THRES #if RF230_CONF_CCA_THRES < -91 +#warning #warning RF230_CONF_CCA_THRES below hardware limit, setting to -91dBm +#warning hal_subregister_write(SR_CCA_ED_THRES,0); #elif RF230_CONF_CCA_THRES > -61 +#warning #warning RF230_CONF_CCA_THRES above hardware limit, setting to -61dBm +#warning hal_subregister_write(SR_CCA_ED_THRES,15); #else hal_subregister_write(SR_CCA_ED_THRES,(RF230_CONF_CCA_THRES+91)/2); +#endif #endif /* Use automatic CRC unless manual is specified */ From 89741bd322c16ba59151fd3c1c22b9daec278d62 Mon Sep 17 00:00:00 2001 From: dak664 Date: Thu, 7 Apr 2011 17:47:54 -0400 Subject: [PATCH 8/9] Exit on watchdog reboot call --- cpu/native/watchdog.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpu/native/watchdog.c b/cpu/native/watchdog.c index 0fbff9f21..6aa44e196 100644 --- a/cpu/native/watchdog.c +++ b/cpu/native/watchdog.c @@ -32,6 +32,7 @@ */ #include "dev/watchdog.h" +#include /*---------------------------------------------------------------------------*/ void @@ -57,5 +58,7 @@ watchdog_stop(void) void watchdog_reboot(void) { + // Death by watchdog. + exit(-1); } /*---------------------------------------------------------------------------*/ From 2e14df3981061cb42fb7ea3ca85e8a9f61ae964f Mon Sep 17 00:00:00 2001 From: dak664 Date: Fri, 8 Apr 2011 15:15:16 -0400 Subject: [PATCH 9/9] Options to extend mc1322x fifo to RAM buffer, or use hardware flow control with tunslip6. --- cpu/mc1322x/lib/include/uart1.h | 22 ++++- cpu/mc1322x/lib/uart1.c | 80 +++++++++++++++---- cpu/mc1322x/src/default_lowlevel.c | 23 ++++-- .../redbee-econotag/contiki-mc1322x-main.c | 2 +- tools/tunslip6.c | 18 +++-- 5 files changed, 115 insertions(+), 30 deletions(-) diff --git a/cpu/mc1322x/lib/include/uart1.h b/cpu/mc1322x/lib/include/uart1.h index d80eac65d..4e635e930 100644 --- a/cpu/mc1322x/lib/include/uart1.h +++ b/cpu/mc1322x/lib/include/uart1.h @@ -70,9 +70,29 @@ #define UART2_UCTS ((volatile uint32_t *) ( UART2_BASE + UCTS )) #define UART2_UBRCNT ((volatile uint32_t *) ( UART2_BASE + UBRCNT )) -extern volatile uint32_t u1_head, u1_tail; +/* The mc1322x has a 32 byte hardware FIFO for transmitted characters. + * Currently it is always filled from a larger RAM buffer. It would be + * possible to eliminate that overhead by filling directly from a chain + * of data buffer pointers, but printf's would be not so easy. + */ +#define UART1_TX_BUFFERSIZE 1024 +extern volatile uint32_t u1_tx_head, u1_tx_tail; void uart1_putc(char c); + +/* The mc1322x has a 32 byte hardware FIFO for received characters. + * If a larger rx buffersize is specified the FIFO will be extended into RAM. + * RAM transfers will occur on interrupt when the FIFO is nearly full. + * If a smaller buffersize is specified hardware flow control will be + * initiated at that FIFO level. + * Set to 32 for no flow control or RAM buffer. + */ +#define UART1_RX_BUFFERSIZE 128 +#if UART1_RX_BUFFERSIZE > 32 +extern volatile uint32_t u1_rx_head, u1_rx_tail; +#define uart1_can_get() ((u1_rx_head!=u1_rx_tail) || (*UART1_URXCON > 0)) +#else #define uart1_can_get() (*UART1_URXCON > 0) +#endif uint8_t uart1_getc(void); diff --git a/cpu/mc1322x/lib/uart1.c b/cpu/mc1322x/lib/uart1.c index 0d3fbd807..b3df668c7 100644 --- a/cpu/mc1322x/lib/uart1.c +++ b/cpu/mc1322x/lib/uart1.c @@ -36,43 +36,91 @@ #include #include -volatile char u1_tx_buf[1024]; -volatile uint32_t u1_head, u1_tail; +volatile char u1_tx_buf[UART1_TX_BUFFERSIZE]; +volatile uint32_t u1_tx_head, u1_tx_tail; + +#if UART1_RX_BUFFERSIZE > 32 +volatile char u1_rx_buf[UART1_RX_BUFFERSIZE-32]; +volatile uint32_t u1_rx_head, u1_rx_tail; +#endif void uart1_isr(void) { + +#if UART1_RX_BUFFERSIZE > 32 + if (*UART1_USTAT & ( 1 << 6)) { //receive interrupt + while( *UART1_URXCON != 0 ) { //flush the hardware fifo into the software buffer + uint32_t u1_rx_tail_next; + u1_rx_tail_next = u1_rx_tail+1; + if (u1_rx_tail_next >= sizeof(u1_rx_buf)) + u1_rx_tail_next = 0; + if (u1_rx_head != u1_rx_tail_next) { + u1_rx_buf[u1_rx_tail]= *UART1_UDATA; + u1_rx_tail = u1_rx_tail_next; + } + } + return; + } +#endif + while( *UART1_UTXCON != 0 ) { - if (u1_head == u1_tail) { + if (u1_tx_head == u1_tx_tail) { +#if UART1_RX_BUFFERSIZE > 32 + *UART1_UCON |= (1 << 13); /*disable tx interrupt */ +#else disable_irq(UART1); +#endif return; } - *UART1_UDATA = u1_tx_buf[u1_tail]; - u1_tail++; - if (u1_tail >= sizeof(u1_tx_buf)) - u1_tail = 0; + + *UART1_UDATA = u1_tx_buf[u1_tx_tail]; + u1_tx_tail++; + if (u1_tx_tail >= sizeof(u1_tx_buf)) + u1_tx_tail = 0; } } void uart1_putc(char c) { /* disable UART1 since */ - /* UART1 isr modifies u1_head and u1_tail */ - disable_irq(UART1); + /* UART1 isr modifies u1_tx_head and u1_tx_tail */ +#if UART1_RX_BUFFERSIZE > 32 + *UART1_UCON |= (1 << 13); /*disable tx interrupt */ +#else + disable_irq(UART1); +#endif - if( (u1_head == u1_tail) && + if( (u1_tx_head == u1_tx_tail) && (*UART1_UTXCON != 0)) { *UART1_UDATA = c; } else { - u1_tx_buf[u1_head] = c; - u1_head += 1; - if (u1_head >= sizeof(u1_tx_buf)) - u1_head = 0; - if (u1_head == u1_tail) { /* drop chars when no room */ - if (u1_head) { u1_head -=1; } else { u1_head = sizeof(u1_tx_buf); } + u1_tx_buf[u1_tx_head] = c; + u1_tx_head += 1; + if (u1_tx_head >= sizeof(u1_tx_buf)) + u1_tx_head = 0; + if (u1_tx_head == u1_tx_tail) { /* drop chars when no room */ + if (u1_tx_head) { u1_tx_head -=1; } else { u1_tx_head = sizeof(u1_tx_buf); } } + +#if UART1_RX_BUFFERSIZE > 32 + *UART1_UCON &= ~(1 << 13); /*enable tx interrupt */ +#else enable_irq(UART1); +#endif + } } uint8_t uart1_getc(void) { +#if UART1_RX_BUFFERSIZE > 32 +/* First pull from the ram buffer */ +uint8_t c=0; + if (u1_rx_head != u1_rx_tail) { + c = u1_rx_buf[u1_rx_head++]; + if (u1_rx_head >= sizeof(u1_rx_buf)) + u1_rx_head=0; + return c; + } +#endif +/* Then pull from the hardware fifo */ while(uart1_can_get() == 0) { continue; } return *UART1_UDATA; } diff --git a/cpu/mc1322x/src/default_lowlevel.c b/cpu/mc1322x/src/default_lowlevel.c index 1f603f113..27b35a889 100644 --- a/cpu/mc1322x/src/default_lowlevel.c +++ b/cpu/mc1322x/src/default_lowlevel.c @@ -47,7 +47,7 @@ void default_vreg_init(void) { void uart1_init(uint16_t inc, uint16_t mod, uint8_t samp) { - /* UART must be disabled to set the baudrate */ + /* UART must be disabled to set the baudrate */ *UART1_UCON = 0; *UART1_UBRCNT = ( inc << 16 ) | mod; @@ -63,18 +63,27 @@ void uart1_init(uint16_t inc, uint16_t mod, uint8_t samp) { /* you must enable the peripheral first BEFORE setting the function in GPIO_FUNC_SEL */ /* From the datasheet: "The peripheral function will control operation of the pad IF */ /* THE PERIPHERAL IS ENABLED. */ - *UART1_UCON = (1 << 0) | (1 << 1); /* enable receive, transmit */ + +#if UART1_RX_BUFFERSIZE > 32 + *UART1_UCON = (1 << 0) | (1 << 1) ; /* enable receive, transmit, and both interrupts */ + *UART1_URXCON = 30; /* interrupt when fifo is nearly full */ + u1_rx_head = 0; u1_rx_tail = 0; +#elif UART1_RX_BUFFERSIZE < 32 /* enable receive, transmit, flow control, disable rx interrupt */ + *UART1_UCON = (1 << 0) | (1 << 1) | (1 << 12) | (1 << 14); + *UART1_UCTS = UART1_RX_BUFFERSIZE; /* drop cts when tx buffer at trigger level */ + *GPIO_FUNC_SEL1 = ( (0x01 << (0*2)) | (0x01 << (1*2)) ); /* set GPIO17-16 to UART1 CTS and RTS */ +#else + *UART1_UCON = (1 << 0) | (1 << 1) | (1 << 14); /* enable receive, transmit, disable rx interrupt */ +#endif + if(samp == UCON_SAMP_16X) set_bit(*UART1_UCON,UCON_SAMP); *GPIO_FUNC_SEL0 = ( (0x01 << (14*2)) | (0x01 << (15*2)) ); /* set GPIO15-14 to UART (UART1 TX and RX)*/ - + /* interrupt when there are this number or more bytes free in the TX buffer*/ *UART1_UTXCON = 16; + u1_tx_head = 0; u1_tx_tail = 0; - u1_head = 0; u1_tail = 0; - - /* tx and rx interrupts are enabled in the UART by default */ - /* see status register bits 13 and 14 */ /* enable UART1 interrupts in the interrupt controller */ enable_irq(UART1); } diff --git a/platform/redbee-econotag/contiki-mc1322x-main.c b/platform/redbee-econotag/contiki-mc1322x-main.c index 268d1602a..e49282d65 100644 --- a/platform/redbee-econotag/contiki-mc1322x-main.c +++ b/platform/redbee-econotag/contiki-mc1322x-main.c @@ -48,6 +48,7 @@ #include "lib/random.h" #include "net/netstack.h" #include "net/mac/frame802154.h" +#include "lib/include/uart1.h" #if WITH_UIP6 #include "net/sicslowpan.h" @@ -490,7 +491,6 @@ main(void) cop_service(); #endif - /* TODO: replace this with a uart rx interrupt */ if(uart1_input_handler != NULL) { if(uart1_can_get()) { uart1_input_handler(uart1_getc()); diff --git a/tools/tunslip6.c b/tools/tunslip6.c index 82ab3f433..2b1c28acf 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -60,7 +60,7 @@ const char *netmask; int slipfd = 0; uint16_t basedelay=0,delaymsec=0; uint32_t startsec,startmsec,delaystartsec,delaystartmsec; -int timestamp = 0; +int timestamp = 0, flowcontrol=0; int ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); @@ -172,7 +172,7 @@ serial_to_tun(FILE *inslip, int outfd) if(inbufptr >= sizeof(uip.inbuf)) { inbufptr = 0; if(timestamp) stamptime(); - fprintf(stderr, "*** dropping too large packet\n"); + fprintf(stderr, "*** dropping large %d byte packet\n",inbufptr); } ret = fread(&c, 1, 1, inslip); #ifdef linux @@ -459,7 +459,10 @@ stty_telos(int fd) /* Nonblocking read. */ tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = 0; - tty.c_cflag &= ~CRTSCTS; + if (flowcontrol) + tty.c_cflag |= CRTSCTS; + else + tty.c_cflag &= ~CRTSCTS; tty.c_cflag &= ~HUPCL; tty.c_cflag &= ~CLOCAL; @@ -616,12 +619,16 @@ main(int argc, char **argv) prog = argv[0]; setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ - while((c = getopt(argc, argv, "B:D:Lhs:t:v::d::a:p:T")) != -1) { + while((c = getopt(argc, argv, "B:H:D:Lhs:t:v::d::a:p:T")) != -1) { switch(c) { case 'B': baudrate = atoi(optarg); break; + case 'H': + flowcontrol=1; + break; + case 'L': timestamp=1; break; @@ -671,6 +678,7 @@ fprintf(stderr,"usage: %s [options] ipaddress\n", prog); fprintf(stderr,"example: tunslip6 -L -v2 -s ttyUSB1 aaaa::1/64\n"); fprintf(stderr,"Options are:\n"); fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default)\n"); +fprintf(stderr," -H Hardware CTS/RTS flow control (default disabled)\n"); fprintf(stderr," -L Log output format (adds time stamps)\n"); fprintf(stderr," -s siodev Serial device (default /dev/ttyUSB0)\n"); fprintf(stderr," -T Make tap interface (default is tun interface)\n"); @@ -696,7 +704,7 @@ exit(1); argv += (optind - 1); if(argc != 2 && argc != 3) { - err(1, "usage: %s [-B baudrate] [-L] [-s siodev] [-t tundev] [-T] [-v verbosity] [-d delay] [-a serveraddress] [-p serverport] ipaddress", prog); + err(1, "usage: %s [-B baudrate] [-H] [-L] [-s siodev] [-t tundev] [-T] [-v verbosity] [-d delay] [-a serveraddress] [-p serverport] ipaddress", prog); } ipaddr = argv[1];