From 03ab3fe31778a76b9ba32cf0e17043214e7fb21d Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sat, 20 Oct 2012 22:29:16 -0400 Subject: [PATCH] Newer and cleaner TARGET=econotag as well as robust mc13224v configuration system. (also deprecate TARGET=redbee-econotag) - mc13224v now automatically probes hardware config for buck converter and 32kHz crystal as well as automatically monitors battery voltage and manages the buck accordingly. - new flashed based config system for mc13224v parameters such has radio modes (demod, autoack), nvmtype, mac address, channel and power. - considerably cleaned up econotag platform code (suffered from severe case of bit-rot) --- cpu/mc1322x/Makefile.mc1322x | 2 +- cpu/mc1322x/config.c | 83 ++++++ cpu/mc1322x/config.h | 35 +++ cpu/mc1322x/contiki-maca.c | 78 ++++-- cpu/mc1322x/init.c | 201 ++++++++++++++ cpu/mc1322x/lib/rtc.c | 4 +- platform/econotag/Makefile.econotag | 22 ++ platform/econotag/button-sensor.c | 92 +++++++ platform/econotag/contiki-conf.h | 246 ++++++++++++++++++ platform/econotag/main.c | 148 +++++++++++ platform/econotag/platform_prints.c | 45 ++++ platform/econotag/platform_prints.h | 3 + .../redbee-econotag/Makefile.redbee-econotag | 11 + platform/redbee-econotag/contiki-conf.h | 3 + .../redbee-econotag/contiki-mc1322x-main.c | 2 +- 15 files changed, 950 insertions(+), 25 deletions(-) create mode 100644 cpu/mc1322x/config.c create mode 100644 cpu/mc1322x/config.h create mode 100644 cpu/mc1322x/init.c create mode 100644 platform/econotag/Makefile.econotag create mode 100644 platform/econotag/button-sensor.c create mode 100644 platform/econotag/contiki-conf.h create mode 100644 platform/econotag/main.c create mode 100644 platform/econotag/platform_prints.c create mode 100644 platform/econotag/platform_prints.h diff --git a/cpu/mc1322x/Makefile.mc1322x b/cpu/mc1322x/Makefile.mc1322x index 64e0711e4..443c26f8f 100644 --- a/cpu/mc1322x/Makefile.mc1322x +++ b/cpu/mc1322x/Makefile.mc1322x @@ -10,7 +10,7 @@ CONTIKI_CPU=$(CONTIKI)/cpu/mc1322x CONTIKI_CPU_DIRS = . lib src board dev ../arm/common/dbg-io -MC1322X = debug-uart.c rtimer-arch.c watchdog.c contiki-crm.c contiki-maca.c contiki-misc.c leds-arch.c leds.c contiki-uart.c slip-uart1.c +MC1322X = debug-uart.c rtimer-arch.c watchdog.c contiki-crm.c contiki-maca.c contiki-misc.c leds-arch.c leds.c contiki-uart.c slip-uart1.c init.c config.c DBG_IO = dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c diff --git a/cpu/mc1322x/config.c b/cpu/mc1322x/config.c new file mode 100644 index 000000000..2d7b10049 --- /dev/null +++ b/cpu/mc1322x/config.c @@ -0,0 +1,83 @@ +/* MC1322x flash config system */ + +#include +#include "config.h" + +/* debug */ +#define DEBUG DEBUG_FULL +#include "net/uip-debug.h" + +mc1322xConfig mc1322x_config; + +void dump_bytes(uint32_t addr, uint16_t num); + +/* takes an mc1322xConf and initializes to default values */ +void mc1322x_config_set_default(mc1322xConfig *c) { + nvmType_t type; + c->magic = MC1322X_CONFIG_MAGIC; + c->version = MC1322X_CONFIG_VERSION; + c->eui = 0; + c->channel = RF_CHANNEL - 11; + c->power = 0x11; + c->flags.demod = DEMOD_DCD; + c->flags.autoack = AUTOACK; + nvm_detect(gNvmInternalInterface_c, &type); + c->flags.nvmtype = type; +} + +/* write out config to flash */ +void mc1322x_config_save(mc1322xConfig *c) { + nvmErr_t err; + err = nvm_erase(gNvmInternalInterface_c, c->flags.nvmtype, 1 << MC1322X_CONFIG_PAGE/4096); + err = nvm_write(gNvmInternalInterface_c, c->flags.nvmtype, (uint8_t *)c, MC1322X_CONFIG_PAGE, sizeof(mc1322xConfig)); +} + +/* load the config from flash to the pass conf structure */ +void mc1322x_config_restore(mc1322xConfig *c) { + nvmErr_t err; + nvmType_t type; + if (c->flags.nvmtype == 0) { nvm_detect(gNvmInternalInterface_c, &type); } + c->flags.nvmtype = type; + err = nvm_read(gNvmInternalInterface_c, c->flags.nvmtype, c, MC1322X_CONFIG_PAGE, sizeof(mc1322xConfig)); +} + +/* check the flash for magic number and proper version */ +int mc1322x_config_valid(mc1322xConfig *c) { + if (c->magic == MC1322X_CONFIG_MAGIC && + c->version == MC1322X_CONFIG_VERSION) { + return 1; + } else { +#if DEBUG + if (c->magic != MC1322X_CONFIG_MAGIC) { PRINTF("config bad magic %04x\n\r", c->magic); } + if (c->version != MC1322X_CONFIG_MAGIC) { PRINTF("config bad version %04x\n\r", c->version); } +#endif + return -1; + } +} + +void mc1322x_config_print(void) { + uint64_t eui64; + PRINTF("mc1322x config:\n\r"); + PRINTF(" magic: %04x\n\r", mc1322x_config.magic); + PRINTF(" version: %d\n\r", mc1322x_config.version); + PRINTF(" eui: %08x%08x\n\r", (uint32_t)(mc1322x_config.eui>>32), (uint32_t)(mc1322x_config.eui & 0xffffffff)); + PRINTF(" channel: %d\n\r", mc1322x_config.channel); + PRINTF(" power: %d\n\r", mc1322x_config.power); + PRINTF(" flags: %08x\n\r", mc1322x_config.flags); + PRINTF(" demod: %d\n\r", mc1322x_config.flags.demod); + PRINTF(" autoack: %d\n\r", mc1322x_config.flags.autoack); + PRINTF(" nvm type: %d\n\r", mc1322x_config.flags.nvmtype); +} + +void dump_bytes(uint32_t addr, uint16_t num) { + uint32_t buf[num/4]; + nvmErr_t err; + uint16_t i; + + err = nvm_read(gNvmInternalInterface_c, mc1322x_config.flags.nvmtype, (uint8_t *)buf, addr, num); + PRINTF("nvm_read returned: 0x%02x\r\n", err); + + for(i=0; i < num/4; i++) { + printf("0x%08x\r\n", (unsigned int)buf[i]); + } +} diff --git a/cpu/mc1322x/config.h b/cpu/mc1322x/config.h new file mode 100644 index 000000000..becc118af --- /dev/null +++ b/cpu/mc1322x/config.h @@ -0,0 +1,35 @@ +/* MC1322x flash config system */ + +#ifndef MC1322X_CONFIG_H +#define MC1322X_CONFIG_H + +#define MC1322X_CONFIG_PAGE 0x1E000 /* nvm page where conf will be stored */ +#define MC1322X_CONFIG_VERSION 1 +#define MC1322X_CONFIG_MAGIC 0x1322 + +/* bitfield for various config flags */ +struct FLAGS { + uint32_t demod:1; /* radio demodulation mode */ + uint32_t autoack:1; /* radio autoack vs. promiscuous mode */ + uint32_t nvmtype:4; /* stores the result of nvm_detect */ + uint32_t : 26; +}; + +typedef struct { + uint16_t magic; /* mc1322x magic number 0x1322 */ + uint16_t version; /* mc1322x config version number */ + uint64_t eui; + uint8_t channel; /* value to pass to set_channel */ + uint8_t power; /* value to pass to set_power */ + struct FLAGS flags; +} mc1322xConfig; + +extern mc1322xConfig mc1322x_config; + +void mc1322x_config_set_default(mc1322xConfig *c); +void mc1322x_config_save(mc1322xConfig *c); +void mc1322x_config_restore(mc1322xConfig *c); +int mc1322x_config_valid(mc1322xConfig *c); +void mc1322x_config_print(void); + +#endif diff --git a/cpu/mc1322x/contiki-maca.c b/cpu/mc1322x/contiki-maca.c index 886b15ac2..17e975087 100644 --- a/cpu/mc1322x/contiki-maca.c +++ b/cpu/mc1322x/contiki-maca.c @@ -37,21 +37,21 @@ #include #include +/* debug */ +#define DEBUG DEBUG_ANNOTATE +#include "net/uip-debug.h" + /* contiki */ #include "radio.h" #include "sys/process.h" #include "net/packetbuf.h" #include "net/netstack.h" -#include "mc1322x.h" #include "contiki-conf.h" -#define CONTIKI_MACA_DEBUG 0 -#if CONTIKI_MACA_DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif +/* mc1322x */ +#include "mc1322x.h" +#include "config.h" #ifndef CONTIKI_MACA_PREPEND_BYTE #define CONTIKI_MACA_PREPEND_BYTE 0xff @@ -61,6 +61,8 @@ #define BLOCKING_TX 1 #endif +unsigned short node_id = 0; + static volatile uint8_t tx_complete; static volatile uint8_t tx_status; @@ -98,6 +100,40 @@ static process_event_t event_data_ready; static volatile packet_t prepped_p; +void contiki_maca_set_mac_address(uint64_t eui) { + rimeaddr_t addr; + uint8_t i; + + /* setup mac address registers in maca hardware */ + *MACA_MACPANID = 0xcdab; /* this is the hardcoded contiki pan, register is PACKET order */ + *MACA_MAC16ADDR = 0xffff; /* short addressing isn't used, set this to 0xffff for now */ + + *MACA_MAC64HI = (uint32_t) (eui >> 32); + *MACA_MAC64LO = (uint32_t) eui; + + ANNOTATE("setting panid 0x%04x\n\r", *MACA_MACPANID); + ANNOTATE("setting short mac 0x%04x\n\r", *MACA_MAC16ADDR); + ANNOTATE("setting long mac 0x%08x_%08x\n\r", *MACA_MAC64HI, *MACA_MAC64LO); + + /* setup mac addresses in Contiki (RIME) */ + rimeaddr_copy(&addr, &rimeaddr_null); + + for(i=0; i < RIMEADDR_CONF_SIZE; i++) { + addr.u8[RIMEADDR_CONF_SIZE - 1 - i] = (mc1322x_config.eui >> (i * 8)) & 0xff; + } + + node_id = (addr.u8[6] << 8 | addr.u8[7]); + rimeaddr_set_node_addr(&addr); + +#if DEBUG_ANNOTATE + ANNOTATE("Rime configured with address "); + for(i = 0; i < sizeof(addr.u8) - 1; i++) { + ANNOTATE("%02X:", addr.u8[i]); + } + ANNOTATE("%02X\n", addr.u8[i]); +#endif +} + int contiki_maca_init(void) { // trim_xtal(); // vreg_init(); @@ -143,7 +179,7 @@ int contiki_maca_off_request(void) { int contiki_maca_read(void *buf, unsigned short bufsize) { volatile uint32_t i; volatile packet_t *p; - + if((p = rx_packet())) { PRINTF("maca read"); #if CONTIKI_MACA_RAW_MODE @@ -162,7 +198,7 @@ int contiki_maca_read(void *buf, unsigned short bufsize) { for( i = p->offset ; i < (bufsize + p->offset) ; i++) { PRINTF(" %02x",p->data[i]); } -#endif +#endif PRINTF("\n\r"); free_packet(p); return bufsize; @@ -177,12 +213,12 @@ int contiki_maca_read(void *buf, unsigned short bufsize) { /* the same packet repeatedly */ int contiki_maca_prepare(const void *payload, unsigned short payload_len) { volatile int i; - + PRINTF("contiki maca prepare"); #if CONTIKI_MACA_RAW_MODE prepped_p.offset = 1; prepped_p.length = payload_len + 1; -#else +#else prepped_p.offset = 0; prepped_p.length = payload_len; #endif @@ -200,7 +236,7 @@ int contiki_maca_prepare(const void *payload, unsigned short payload_len) { } PRINTF("\n\r"); #endif - + return RADIO_TX_OK; } @@ -216,10 +252,10 @@ int contiki_maca_transmit(unsigned short transmit_len) { tx_complete = 0; #endif if(p = get_free_packet()) { - p->offset = prepped_p.offset; - p->length = prepped_p.length; - memcpy((uint8_t *)(p->data + p->offset), - (const uint8_t *)(prepped_p.data + prepped_p.offset), + p->offset = prepped_p.offset; + p->length = prepped_p.length; + memcpy((uint8_t *)(p->data + p->offset), + (const uint8_t *)(prepped_p.data + prepped_p.offset), prepped_p.length); tx_packet(p); } else { @@ -230,7 +266,7 @@ int contiki_maca_transmit(unsigned short transmit_len) { #if BLOCKING_TX /* block until tx_complete, set by contiki_maca_tx_callback */ while(!tx_complete && (tx_head != 0)); -#endif +#endif } int contiki_maca_send(const void *payload, unsigned short payload_len) { @@ -255,7 +291,7 @@ PROCESS_THREAD(contiki_maca_process, ev, data) { volatile uint32_t i; int len; - + PROCESS_BEGIN(); while (1) { @@ -276,7 +312,7 @@ PROCESS_THREAD(contiki_maca_process, ev, data) packetbuf_clear(); len = contiki_maca_read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { - packetbuf_set_datalen(len); + packetbuf_set_datalen(len); NETSTACK_RDC.input(); } } @@ -284,9 +320,9 @@ PROCESS_THREAD(contiki_maca_process, ev, data) if (rx_head != NULL) { process_poll(&contiki_maca_process); } - + }; - + PROCESS_END(); } diff --git a/cpu/mc1322x/init.c b/cpu/mc1322x/init.c new file mode 100644 index 000000000..00019c407 --- /dev/null +++ b/cpu/mc1322x/init.c @@ -0,0 +1,201 @@ +#include + +/* debug */ +#define DEBUG DEBUG_FULL +#include "net/uip-debug.h" + +/* contiki */ +#include "sys/process.h" + +/* mc1322x */ +#include "mc1322x.h" +#include "contiki-maca.h" +#include "config.h" + +/* Threshold for buck converter; buck will be disabled if vbatt is below this */ +#define MC1322X_BUCK_THRES 2425 +/* Hysterisis window around buck threshold */ +#define MC1322X_BUCK_WINDOW 150 +#define MC1322X_BUCK_THRES_H (MC1322X_BUCK_THRES + MC1322X_BUCK_WINDOW/2) +#define MC1322X_BUCK_THRES_L (MC1322X_BUCK_THRES - MC1322X_BUCK_WINDOW/2) +/* Time between vbatt checks for the buck */ +#define MC1322X_BUCK_MONITOR_PERIOD 600 * CLOCK_SECOND + +/* periodically poll adc_vbatt and manages the buck appropriately */ +static struct etimer et_buck; +PROCESS(buck_monitor, "buck monitor"); +PROCESS_THREAD(buck_monitor, ev, data) +{ + + PROCESS_BEGIN(); + PRINTF("starting vbatt monitor\n"); + + etimer_set(&et_buck, MC1322X_BUCK_MONITOR_PERIOD); + + while (1) { + PROCESS_WAIT_EVENT(); + if(etimer_expired(&et_buck)) + { + adc_service(); + PRINTF("buck monitor: vbatt: %d mV\n\r", adc_vbatt); + if( CRM->VREG_CNTLbits.BUCK_EN == 1 && adc_vbatt < MC1322X_BUCK_THRES_L ) { + PRINTF("vbatt low, disabling buck\n\r", adc_vbatt); + CRM->SYS_CNTLbits.PWR_SOURCE = 0; + CRM->VREG_CNTLbits.BUCK_SYNC_REC_EN = 0; + CRM->VREG_CNTLbits.BUCK_BYPASS_EN = 1; + CRM->VREG_CNTLbits.BUCK_EN = 0; + } else if ( CRM->VREG_CNTLbits.BUCK_EN == 0 && adc_vbatt > MC1322X_BUCK_THRES_H ) { + PRINTF("vbatt high, enabling buck\n\r", adc_vbatt); + CRM->SYS_CNTLbits.PWR_SOURCE = 1; + CRM->VREG_CNTLbits.BUCK_SYNC_REC_EN = 1; + CRM->VREG_CNTLbits.BUCK_BYPASS_EN = 0; + CRM->VREG_CNTLbits.BUCK_EN = 1; + } + etimer_set(&et_buck, MC1322X_BUCK_MONITOR_PERIOD); + } + } + + PROCESS_END(); + +} + +void buck_setup(void) { + nvmType_t type; + nvmErr_t err; + volatile int i; + + default_vreg_init(); + + while(CRM->STATUSbits.VREG_1P5V_RDY == 0) { continue; } + while(CRM->STATUSbits.VREG_1P8V_RDY == 0) { continue; } + + /* takes time for the flash supply to fail (if there is no buck) */ + /* spin while this happens doing nvm_detects */ + /* XXX todo: don't probe buck if Vbatt < 2.5V */ + + adc_service(); + PRINTF("vbatt: %04u mV\n\r", adc_vbatt); + + type = 1; + for(i = 0; i < 128 && type != 0; i++) { + err = nvm_detect(gNvmInternalInterface_c, &type); + } + if (type == gNvmType_NoNvm_c) + { + PRINTF("NVM failed without buck, trying with buck\n\r"); + + if (adc_vbatt < MC1322X_BUCK_THRES_L) + { + PRINTF("Vbatt is low, bypassing buck\n\r"); + CRM->SYS_CNTLbits.PWR_SOURCE = 0; + CRM->VREG_CNTLbits.BUCK_SYNC_REC_EN = 0; + CRM->VREG_CNTLbits.BUCK_BYPASS_EN = 1; + CRM->VREG_CNTLbits.BUCK_EN = 0; + } else { + CRM->SYS_CNTLbits.PWR_SOURCE = 1; + CRM->VREG_CNTLbits.BUCK_SYNC_REC_EN = 1; + CRM->VREG_CNTLbits.BUCK_BYPASS_EN = 0; + CRM->VREG_CNTLbits.BUCK_EN = 1; + } + + while(CRM->STATUSbits.VREG_BUCK_RDY == 0) { continue; } + CRM->VREG_CNTLbits.VREG_1P5V_SEL = 3; + CRM->VREG_CNTLbits.VREG_1P5V_EN = 3; + CRM->VREG_CNTLbits.VREG_1P8V_EN = 1; + while(CRM->STATUSbits.VREG_1P5V_RDY == 0) { continue; } + while(CRM->STATUSbits.VREG_1P8V_RDY == 0) { continue; } + + type = 1; + for(i = 0; i < 128 && type != 0; i++) { + err = nvm_detect(gNvmInternalInterface_c, &type); + } + if (type != gNvmType_NoNvm_c) { + PRINTF("buck ok\n\r"); + /* start a process to monitor vbatt and enable/disable the buck as necessary */ + process_start(&buck_monitor, NULL); + } else { + printf("fatal: couldn't detect NVM\n\r"); + } + } else { + PRINTF("NVM ok without buck\n\r"); + } +} + +/* setup the RTC */ +/* try to start the 32kHz xtal */ +void rtc_setup(void) { + volatile uint32_t rtc_count; + volatile uint32_t i; + + ring_osc_off(); + xtal32_on(); + xtal32_exists(); + rtc_count = CRM->RTC_COUNT; + PRINTF("trying to start 32kHz xtal\n\r"); + + for(i = 0; i < 150000 && CRM->RTC_COUNT == rtc_count; i++) { continue; } + if(CRM->RTC_COUNT == rtc_count) { + PRINTF("32xtal failed, using ring osc\n\r"); + CRM->SYS_CNTLbits.XTAL32_EXISTS = 0; + CRM->XTAL32_CNTLbits.XTAL32_EN = 0; + ring_osc_on(); + + /* Set default tune values from datasheet */ + CRM->RINGOSC_CNTLbits.ROSC_CTUNE = 0x6; + CRM->RINGOSC_CNTLbits.ROSC_FTUNE = 0x17; + + /* Trigger calibration */ + rtc_calibrate(); + PRINTF("RTC calibrated to %d Hz\r\n", rtc_freq); + } else { + PRINTF("32kHz xtal started\n\r"); + } +} + +/* call mc1322x_init once to initalize everything with the current config */ +void mc1322x_init(void) { + + /* XXX TODO load config from flash */ + /* config should say what uart to use for debug console */ + /* config should also set the baud rate */ + /* for now, just clean up contiki-conf.h */ + /* maybe factor into conf.h -> contiki-conf.h and mc1322x-conf.h platform-conf.h */ + + /* print out config in debug */ + /* initialize the uarts */ + uart_init(CONSOLE_UART, CONSOLE_BAUD); + PRINTF("mc1322x init\n\r"); + + adc_init(); + clock_init(); + ctimer_init(); + process_init(); + process_start(&etimer_process, NULL); + process_start(&contiki_maca_process, NULL); + buck_setup(); + rtc_setup(); + + /* start with a default config */ + + mc1322x_config_restore(&mc1322x_config); + if ( mc1322x_config_valid(&mc1322x_config) != 1 ) { + PRINTF("flash invalid\n\r"); + /* save the default config to flash */ + mc1322x_config_set_default(&mc1322x_config); + mc1322x_config_save(&mc1322x_config); + } + +#if DEBUG_FULL + mc1322x_config_print(); +#endif + + /* setup the radio */ + maca_init(); + set_power(mc1322x_config.power); + set_channel(mc1322x_config.channel); + set_demodulator_type(mc1322x_config.flags.demod); + set_prm_mode(mc1322x_config.flags.autoack); + + +} + diff --git a/cpu/mc1322x/lib/rtc.c b/cpu/mc1322x/lib/rtc.c index 383384c38..7387352a9 100644 --- a/cpu/mc1322x/lib/rtc.c +++ b/cpu/mc1322x/lib/rtc.c @@ -174,14 +174,14 @@ void rtc_calibrate(void) #define TIMEOUT 100 /* 50 msec per attempt */ - for (i = 0; i < 9; i++) + for (i = 0; i < 16; 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) + if (rtc_freq > 2048) low = mid; // increase loading else high = mid; // decrease loading diff --git a/platform/econotag/Makefile.econotag b/platform/econotag/Makefile.econotag new file mode 100644 index 000000000..95c93a56b --- /dev/null +++ b/platform/econotag/Makefile.econotag @@ -0,0 +1,22 @@ +# -*- makefile -*- + +CONTIKI_TARGET_DIRS = . dev apps net +CONTIKI_CORE = main +CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o + +CONTIKI_TARGET_SOURCEFILES += main.c clock.c button-sensor.c sensors.c slip.c platform_prints.c + +${warning $(CONTIKI)} +CONTIKIMC1322X=$(CONTIKI)/cpu/mc1322x +CONTIKIBOARD=. + +CONTIKI_PLAT_DEFS = + +MCU=arm7tdmi-s + +ifdef UIP_CONF_IPV6 +CFLAGS += -DWITH_UIP6=1 +endif + +include $(CONTIKIMC1322X)/Makefile.mc1322x + diff --git a/platform/econotag/button-sensor.c b/platform/econotag/button-sensor.c new file mode 100644 index 000000000..f89cd6544 --- /dev/null +++ b/platform/econotag/button-sensor.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) and Contiki. + * + * 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 OS. + * + * $Id: button-sensor.c,v 1.1 2010/06/09 14:46:30 maralvira Exp $ + */ + +#include "lib/sensors.h" +#include "dev/button-sensor.h" + +#include "mc1322x.h" + +#include + +const struct sensors_sensor button_sensor; + +static struct timer debouncetimer; +static int status(int type); + +void kbi4_isr(void) { + if(timer_expired(&debouncetimer)) { + timer_set(&debouncetimer, CLOCK_SECOND / 4); + sensors_changed(&button_sensor); + } + clear_kbi_evnt(4); +} + +static int +value(int type) +{ + return GPIO->DATA.GPIO_26 || !timer_expired(&debouncetimer); +} + +static int +configure(int type, int c) +{ + switch (type) { + case SENSORS_ACTIVE: + if (c) { + if(!status(SENSORS_ACTIVE)) { + timer_set(&debouncetimer, 0); + enable_irq_kbi(4); + } + } else { + disable_irq_kbi(4); + } + return 1; + } + return 0; +} + +static int +status(int type) +{ + switch (type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return bit_is_set(*CRM_WU_CNTL, 20); /* check if kbi4 irq is enabled */ + } + return 0; +} + +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + value, configure, status); diff --git a/platform/econotag/contiki-conf.h b/platform/econotag/contiki-conf.h new file mode 100644 index 000000000..f4de30e5f --- /dev/null +++ b/platform/econotag/contiki-conf.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) and Contiki. + * + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$$ + */ + +/** + * \file + * Configuration for Econotag + * + * \author + * Original by: + * Simon Barner + * This version by: + * Mariano Alvira + */ + +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#include + +/* mc1322x files */ +#include "contiki-mc1322x-conf.h" + +/* Econotag I tune parameters */ +#define ECONOTAG_CTUNE_4PF 1 +/* Coarse tune: add 0-15 pf (CTUNE is 4 bits) */ +#define ECONOTAG_CTUNE 11 +/* Fine tune: add FTUNE * 156fF (FTUNE is 5bits) */ +#define ECONOTAG_FTUNE 7 + +/* M12 tune parameters */ +#define M12_CTUNE_4PF 1 +#define M12_CTUNE 3 +#define M12_FTUNE 3 + +/* the econotag platform will correctly detect an Econotag I (no M12) vs. Econotag II (w/M12) */ +/* and trim the main crystal accordingly */ +/* this detection will be incorrect if you populate the 32.768kHz crystal on the Econotag I */ +/* In that case, you should FORCE_ECONOTAG_I below */ +#define FORCE_ECONOTAG_I 0 + +/* if you define a serial number then it will be used to comput the mac address */ +/* otherwise, a random mac address in the Redwire development IAB will be used */ +/* #define M12_CONF_SERIAL 0x000000 */ + +/* Clock ticks per second */ +#define CLOCK_CONF_SECOND 100 + +#define CCIF +#define CLIF + +#define CONSOLE_UART UART1 +#define CONSOLE_BAUD 115200 + +#define dbg_putchar(x) uart1_putc(x) + +#define USE_FORMATTED_STDIO 1 +#define MACA_DEBUG 0 +#define CONTIKI_MACA_RAW_MODE 0 + +#define BLOCKING_TX 1 +#define MACA_AUTOACK 1 +#define NULLRDC_CONF_802154_AUTOACK_HW 1 + +#define USE_WDT 0 + +#ifndef WDT_TIMEOUT +#define WDT_TIMEOUT 5000 /* watchdog timeout in ms */ +#endif + +/* end of mc1322x specific config. */ + +/* start of conitki config. */ +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON 1 + +/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_LT is defined */ +typedef unsigned long rtimer_clock_t; +#define RTIMER_CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) + +#define RIMEADDR_CONF_SIZE 8 + +#if WITH_UIP6 +/* Network setup for IPv6 */ +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_RADIO contiki_maca_driver +#define NETSTACK_CONF_FRAMER framer_802154 + +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define XMAC_CONF_ANNOUNCEMENTS 0 + +#else /* WITH_UIP6 */ +/* Network setup for non-IPv6 (rime). */ + +#define NETSTACK_CONF_NETWORK rime_driver +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC sicslowmac_driver +#define NETSTACK_CONF_RADIO contiki_maca_driver +#define NETSTACK_CONF_FRAMER framer_802154 + +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 + +#define COLLECT_CONF_ANNOUNCEMENTS 1 +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define XMAC_CONF_ANNOUNCEMENTS 0 +#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 + +#define CONTIKIMAC_CONF_COMPOWER 0 +#define XMAC_CONF_COMPOWER 0 +#define CXMAC_CONF_COMPOWER 0 + +#define COLLECT_NEIGHBOR_CONF_MAX_NEIGHBORS 32 + +#endif /* WITH_UIP6 */ + +#define QUEUEBUF_CONF_NUM 16 + +#define PACKETBUF_CONF_ATTRS_INLINE 1 + +#ifndef RF_CHANNEL +#define RF_CHANNEL 26 +#endif /* RF_CHANNEL */ + +#define CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT 0 + +#define IEEE802154_CONF_PANID 0xABCD + +#define PROFILE_CONF_ON 0 +#define ENERGEST_CONF_ON 0 + +#define AODV_COMPLIANCE +#define AODV_NUM_RT_ENTRIES 32 + +#define WITH_ASCII 1 + +#define PROCESS_CONF_NUMEVENTS 8 +#define PROCESS_CONF_STATS 1 + +#ifdef WITH_UIP6 + +#define RIMEADDR_CONF_SIZE 8 + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +#define UIP_CONF_ROUTER 1 +#define UIP_CONF_IPV6_RPL 1 + +#define UIP_CONF_DS6_NBR_NBU 30 +#define UIP_CONF_DS6_ROUTE_NBU 30 + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#define UIP_CONF_IPV6 1 +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 +#define UIP_CONF_ND6_MAX_PREFIXES 3 +#define UIP_CONF_ND6_MAX_NEIGHBORS 4 +#define UIP_CONF_ND6_MAX_DEFROUTERS 2 +#define UIP_CONF_IP_FORWARD 0 +#define UIP_CONF_BUFFER_SIZE 1300 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 + +#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 +#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 +#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 +#endif /* SICSLOWPAN_CONF_FRAG */ +#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 +#else /* WITH_UIP6 */ +#define UIP_CONF_IP_FORWARD 1 +#define UIP_CONF_BUFFER_SIZE 1300 +#endif /* WITH_UIP6 */ + +#define UIP_CONF_ICMP_DEST_UNREACH 1 + +#define UIP_CONF_DHCP_LIGHT +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_RECEIVE_WINDOW 48 +#define UIP_CONF_TCP_MSS 48 +#define UIP_CONF_MAX_CONNECTIONS 4 +#define UIP_CONF_MAX_LISTENPORTS 8 +#define UIP_CONF_UDP_CONNS 12 +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + +#define UIP_CONF_TCP_SPLIT 0 + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/econotag/main.c b/platform/econotag/main.c new file mode 100644 index 000000000..76f572548 --- /dev/null +++ b/platform/econotag/main.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2012, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) and Contiki. + * + * 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. + * + */ + +#include + +/* debug */ +#define DEBUG DEBUG_FULL +#include "net/uip-debug.h" + +/* contiki */ +#include "contiki.h" +#include "dev/button-sensor.h" +#include "net/rime/rimeaddr.h" +#include "net/netstack.h" + +/* mc1322x */ +#include "mc1322x.h" +#include "config.h" +#include "contiki-uart.h" + +/* econotag */ +#include "platform_prints.h" + +SENSORS(&button_sensor); + +#ifndef M12_CONF_SERIAL +#define M12_SERIAL 0x000000 +#else +#define M12_SERIAL M12_CONF_SERIAL +#endif + +int main(void) { + + mc1322x_init(); + + /* m12_init() flips the mux switch */ + + /* trims the main crystal load capacitance */ + if (!FORCE_ECONOTAG_I && CRM->SYS_CNTLbits.XTAL32_EXISTS) { + /* M12 based econotag */ + PRINTF("trim xtal for M12\n\r"); + CRM->XTAL_CNTLbits.XTAL_CTUNE = (M12_CTUNE_4PF << 4) | M12_CTUNE; + CRM->XTAL_CNTLbits.XTAL_FTUNE = M12_FTUNE; + } else { + /* econotag I */ + PRINTF("trim xtal for Econotag I\n\r"); + CRM->XTAL_CNTLbits.XTAL_CTUNE = (ECONOTAG_CTUNE_4PF << 4) | ECONOTAG_CTUNE; + CRM->XTAL_CNTLbits.XTAL_FTUNE = ECONOTAG_FTUNE; + } + + /* create mac address if blank*/ + if (mc1322x_config.eui == 0) { + /* mac address is blank */ + /* construct a new mac address based on IAB or OUI definitions */ + + /* if an M12_SERIAL number is not defined */ + /* generate a random extension in the Redwire experimental IAB */ + /* The Redwire IAB (for development only) is: */ + /* OUI: 0x0050C2 IAB: 0xA8C */ + /* plus a random 24-bit extension */ + /* Otherwise, construct a mac based on the M12_SERIAL */ + /* Owners of an Econotag I (not M12 based) can request a serial number from Redwire */ + /* to use here */ + + /* M12 mac is of the form "EC473C4D12000000" */ + /* Redwire's OUI: EC473C */ + /* M12: 4D12 */ + /* next six nibbles are the M12 serial number as hex */ + /* e.g. if the barcode reads: "12440021" = BDD1D5 */ + /* full mac is EC473C4D12BDD1D5 */ + +#if (M12_SERIAL == 0) + /* use random mac from experimental range */ + mc1322x_config.eui = (0x0050C2A8Cull << 24) | (*MACA_RANDOM & (0xffffff)); +#else + /* construct mac from serial number */ + mc1322x_config.eui = (0xEC473C4D12ull << 24) | M12_SERIAL; +#endif + mc1322x_config_save(&mc1322x_config); + } + + /* configure address on maca hardware and RIME */ + contiki_maca_set_mac_address(mc1322x_config.eui); + +#if WITH_UIP6 + memcpy(&uip_lladdr.addr, &rimeaddr_node_addr.u8, sizeof(uip_lladdr.addr)); + queuebuf_init(); + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); + #if DEBUG_ANNOTATE + print_netstack(); + #endif + process_start(&tcpip_process, NULL); + #if DEBUG_ANNOTATE + print_lladdrs(); + #endif +#endif /* endif WITH_UIP6 */ + + process_start(&sensors_process, NULL); + + print_processes(autostart_processes); + autostart_start(autostart_processes); + + /* Main scheduler loop */ + while(1) { + check_maca(); + + if(uart1_input_handler != NULL) { + if(uart1_can_get()) { + uart1_input_handler(uart1_getc()); + } + } + + process_run(); + } + + return 0; +} diff --git a/platform/econotag/platform_prints.c b/platform/econotag/platform_prints.c new file mode 100644 index 000000000..d8b960770 --- /dev/null +++ b/platform/econotag/platform_prints.c @@ -0,0 +1,45 @@ +/* Temp place to put informational printing that happens a lot in platform code */ +/* XXX TODO Factor this out to some place, almost all of the platforms use it */ + +#include "contiki.h" +#include "net/netstack.h" +#include "net/uip-ds6.h" + +void +print_processes(struct process * const processes[]) +{ + /* const struct process * const * p = processes;*/ + printf("Starting"); + while(*processes != NULL) { + printf(" '%s'", (*processes)->name); + processes++; + } + printf("\n"); +} + +void +print_netstack(void) { + printf("%s %s, channel check rate %lu Hz, radio channel %u\n", + NETSTACK_MAC.name, NETSTACK_RDC.name, + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1: + NETSTACK_RDC.channel_check_interval()), + RF_CHANNEL); +} + +void print_lladdrs(void) { + int i, a; + printf("Tentative link-local IPv6 address "); + + for(a = 0; a < UIP_DS6_ADDR_NB; a++) { + if (uip_ds6_if.addr_list[a].isused) { + for(i = 0; i < 7; ++i) { + printf("%02x%02x:", + uip_ds6_if.addr_list[a].ipaddr.u8[i * 2], + uip_ds6_if.addr_list[a].ipaddr.u8[i * 2 + 1]); + } + printf("%02x%02x\n", + uip_ds6_if.addr_list[a].ipaddr.u8[14], + uip_ds6_if.addr_list[a].ipaddr.u8[15]); + } + } +} diff --git a/platform/econotag/platform_prints.h b/platform/econotag/platform_prints.h new file mode 100644 index 000000000..96571ac3d --- /dev/null +++ b/platform/econotag/platform_prints.h @@ -0,0 +1,3 @@ +void print_processes(struct process * const processes[]); +void print_netstack(void); +void print_lladdrs(void); diff --git a/platform/redbee-econotag/Makefile.redbee-econotag b/platform/redbee-econotag/Makefile.redbee-econotag index c6ab63a56..61d809d1a 100644 --- a/platform/redbee-econotag/Makefile.redbee-econotag +++ b/platform/redbee-econotag/Makefile.redbee-econotag @@ -1,5 +1,16 @@ # -*- makefile -*- +define nl + + +endef + +ifndef ALLOW_OLD_PLATFORMS +${error $(nl)$(nl)**** This platform is old and will soon be removed **** $(nl)$(nl)\ +please use TARGET=econotag instead.$(nl)$(nl) \ + (or set ALLOW_OLD_PLATFORMS=1 to proceed)$(nl)$(nl) } +endif + CONTIKI_TARGET_DIRS = . dev apps net CONTIKI_CORE=contiki-mc1322x-main CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o diff --git a/platform/redbee-econotag/contiki-conf.h b/platform/redbee-econotag/contiki-conf.h index 6c31cb12a..ae1172aa0 100644 --- a/platform/redbee-econotag/contiki-conf.h +++ b/platform/redbee-econotag/contiki-conf.h @@ -81,6 +81,9 @@ #define SAMP UCON_SAMP_8X //#define SAMP UCON_SAMP_16X +#define CONSOLE_UART UART1 +#define CONSOLE_BAUD 115200 + //#define uart_init uart1_init #define dbg_putchar(x) uart1_putc(x) diff --git a/platform/redbee-econotag/contiki-mc1322x-main.c b/platform/redbee-econotag/contiki-mc1322x-main.c index 98079f718..f3bc8f5a3 100644 --- a/platform/redbee-econotag/contiki-mc1322x-main.c +++ b/platform/redbee-econotag/contiki-mc1322x-main.c @@ -280,7 +280,7 @@ void oui_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint64_t ext) { eui64->u8[7] = ext & 0xff; } -unsigned short node_id = 0; +extern unsigned short node_id; void set_rimeaddr(rimeaddr_t *addr)