From ad256e50148ab7ca44fd73bac7cc3e9fce2be47c Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Mon, 5 Mar 2012 15:47:01 +0000 Subject: [PATCH] New platform: TI cc2530 Development Kit This commits adds support for TI's SmartRF05 Eval. Board with cc2530 EMs Some initial support for cc2531 USB dongles --- cpu/cc253x/8051def.h | 79 +++ cpu/cc253x/Makefile.cc253x | 198 ++++++ cpu/cc253x/bank-alloc.py | 245 +++++++ cpu/cc253x/cc253x.h | 669 ++++++++++++++++++ cpu/cc253x/dev/cc2530-rf.c | 489 +++++++++++++ cpu/cc253x/dev/cc2530-rf.h | 127 ++++ cpu/cc253x/dev/clock-isr.h | 46 ++ cpu/cc253x/dev/clock.c | 182 +++++ cpu/cc253x/dev/dma.c | 69 ++ cpu/cc253x/dev/dma.h | 148 ++++ cpu/cc253x/dev/dma_intr.c | 68 ++ cpu/cc253x/dev/lpm.h | 57 ++ cpu/cc253x/dev/port.h | 145 ++++ cpu/cc253x/dev/random.c | 111 +++ cpu/cc253x/dev/uart-intr.c | 70 ++ cpu/cc253x/dev/uart.h | 43 ++ cpu/cc253x/dev/uart0.c | 75 ++ cpu/cc253x/dev/uart0.h | 41 ++ cpu/cc253x/dev/uart1.c | 74 ++ cpu/cc253x/dev/uart1.h | 38 + cpu/cc253x/dev/watchdog.c | 88 +++ cpu/cc253x/mtarch.h | 50 ++ cpu/cc253x/rtimer-arch.c | 113 +++ cpu/cc253x/rtimer-arch.h | 61 ++ cpu/cc253x/segment.rules | 22 + cpu/cc253x/sfr-bits.h | 195 +++++ cpu/cc253x/soc.c | 54 ++ cpu/cc253x/soc.h | 46 ++ examples/cc2530dk/Makefile | 6 + examples/cc2530dk/Makefile.target | 1 + examples/cc2530dk/blink-hello.c | 62 ++ examples/cc2530dk/border-router/Makefile | 15 + .../cc2530dk/border-router/Makefile.target | 1 + examples/cc2530dk/border-router/README | 16 + .../cc2530dk/border-router/border-router.c | 131 ++++ .../cc2530dk/border-router/project-conf.h | 48 ++ examples/cc2530dk/border-router/slip-bridge.c | 105 +++ examples/cc2530dk/hello-world.c | 23 + examples/cc2530dk/sensors-demo.c | 193 +++++ examples/cc2530dk/sniffer/Makefile | 10 + examples/cc2530dk/sniffer/Makefile.target | 1 + examples/cc2530dk/sniffer/netstack.c | 50 ++ examples/cc2530dk/sniffer/project-conf.h | 50 ++ examples/cc2530dk/sniffer/sniffer.c | 54 ++ examples/cc2530dk/sniffer/stub-rdc.c | 91 +++ examples/cc2530dk/timer-test.c | 139 ++++ examples/cc2530dk/udp-ipv6/Makefile | 14 + examples/cc2530dk/udp-ipv6/Makefile.target | 1 + examples/cc2530dk/udp-ipv6/client.c | 159 +++++ examples/cc2530dk/udp-ipv6/ping6.c | 139 ++++ examples/cc2530dk/udp-ipv6/project-conf.h | 49 ++ examples/cc2530dk/udp-ipv6/server.c | 174 +++++ platform/cc2530dk/Makefile.cc2530dk | 52 ++ platform/cc2530dk/contiki-conf.h | 225 ++++++ platform/cc2530dk/contiki-main.c | 333 +++++++++ platform/cc2530dk/debug.c | 42 ++ platform/cc2530dk/debug.h | 54 ++ platform/cc2530dk/dev/adc-sensor.c | 123 ++++ platform/cc2530dk/dev/adc-sensor.h | 82 +++ platform/cc2530dk/dev/button-sensor.c | 105 +++ platform/cc2530dk/dev/button-sensor.h | 80 +++ platform/cc2530dk/dev/leds-arch.c | 87 +++ platform/cc2530dk/dev/leds-arch.h | 53 ++ platform/cc2530dk/dev/slip-arch.c | 50 ++ platform/cc2530dk/dev/smartrf-sensors.c | 54 ++ platform/cc2530dk/putchar.c | 38 + platform/cc2530dk/segment.rules | 13 + platform/cc2530dk/viztool.c | 298 ++++++++ 68 files changed, 6824 insertions(+) create mode 100644 cpu/cc253x/8051def.h create mode 100644 cpu/cc253x/Makefile.cc253x create mode 100644 cpu/cc253x/bank-alloc.py create mode 100644 cpu/cc253x/cc253x.h create mode 100644 cpu/cc253x/dev/cc2530-rf.c create mode 100644 cpu/cc253x/dev/cc2530-rf.h create mode 100644 cpu/cc253x/dev/clock-isr.h create mode 100644 cpu/cc253x/dev/clock.c create mode 100644 cpu/cc253x/dev/dma.c create mode 100644 cpu/cc253x/dev/dma.h create mode 100644 cpu/cc253x/dev/dma_intr.c create mode 100644 cpu/cc253x/dev/lpm.h create mode 100644 cpu/cc253x/dev/port.h create mode 100644 cpu/cc253x/dev/random.c create mode 100644 cpu/cc253x/dev/uart-intr.c create mode 100644 cpu/cc253x/dev/uart.h create mode 100644 cpu/cc253x/dev/uart0.c create mode 100644 cpu/cc253x/dev/uart0.h create mode 100644 cpu/cc253x/dev/uart1.c create mode 100644 cpu/cc253x/dev/uart1.h create mode 100644 cpu/cc253x/dev/watchdog.c create mode 100644 cpu/cc253x/mtarch.h create mode 100644 cpu/cc253x/rtimer-arch.c create mode 100644 cpu/cc253x/rtimer-arch.h create mode 100644 cpu/cc253x/segment.rules create mode 100644 cpu/cc253x/sfr-bits.h create mode 100644 cpu/cc253x/soc.c create mode 100644 cpu/cc253x/soc.h create mode 100644 examples/cc2530dk/Makefile create mode 100644 examples/cc2530dk/Makefile.target create mode 100644 examples/cc2530dk/blink-hello.c create mode 100644 examples/cc2530dk/border-router/Makefile create mode 100644 examples/cc2530dk/border-router/Makefile.target create mode 100644 examples/cc2530dk/border-router/README create mode 100644 examples/cc2530dk/border-router/border-router.c create mode 100644 examples/cc2530dk/border-router/project-conf.h create mode 100644 examples/cc2530dk/border-router/slip-bridge.c create mode 100644 examples/cc2530dk/hello-world.c create mode 100644 examples/cc2530dk/sensors-demo.c create mode 100644 examples/cc2530dk/sniffer/Makefile create mode 100644 examples/cc2530dk/sniffer/Makefile.target create mode 100644 examples/cc2530dk/sniffer/netstack.c create mode 100644 examples/cc2530dk/sniffer/project-conf.h create mode 100644 examples/cc2530dk/sniffer/sniffer.c create mode 100644 examples/cc2530dk/sniffer/stub-rdc.c create mode 100644 examples/cc2530dk/timer-test.c create mode 100644 examples/cc2530dk/udp-ipv6/Makefile create mode 100644 examples/cc2530dk/udp-ipv6/Makefile.target create mode 100644 examples/cc2530dk/udp-ipv6/client.c create mode 100644 examples/cc2530dk/udp-ipv6/ping6.c create mode 100644 examples/cc2530dk/udp-ipv6/project-conf.h create mode 100644 examples/cc2530dk/udp-ipv6/server.c create mode 100644 platform/cc2530dk/Makefile.cc2530dk create mode 100644 platform/cc2530dk/contiki-conf.h create mode 100644 platform/cc2530dk/contiki-main.c create mode 100644 platform/cc2530dk/debug.c create mode 100644 platform/cc2530dk/debug.h create mode 100644 platform/cc2530dk/dev/adc-sensor.c create mode 100644 platform/cc2530dk/dev/adc-sensor.h create mode 100644 platform/cc2530dk/dev/button-sensor.c create mode 100644 platform/cc2530dk/dev/button-sensor.h create mode 100644 platform/cc2530dk/dev/leds-arch.c create mode 100644 platform/cc2530dk/dev/leds-arch.h create mode 100644 platform/cc2530dk/dev/slip-arch.c create mode 100644 platform/cc2530dk/dev/smartrf-sensors.c create mode 100644 platform/cc2530dk/putchar.c create mode 100644 platform/cc2530dk/segment.rules create mode 100644 platform/cc2530dk/viztool.c diff --git a/cpu/cc253x/8051def.h b/cpu/cc253x/8051def.h new file mode 100644 index 000000000..7314edcd7 --- /dev/null +++ b/cpu/cc253x/8051def.h @@ -0,0 +1,79 @@ +/* + * \file + * This file contains a set of configuration for using SDCC as a compiler. + * Modified from z80 port for cc2430 port. + * + * \author + * Takahide Matsutsuka (Original) + * George Oikonomou - + * (updates for the cc2530 ports) + */ + +#ifndef __8051_DEF_H__ +#define __8051_DEF_H__ + +#include + +/* + * lint - style defines to help syntax parsers with sdcc-specific 8051 code + * They don't interfere with actual compilation + */ +#if !defined(__SDCC_mcs51) && !defined(SDCC_mcs51) +#define __data +#define __xdata +#define __code +#define __bit bool +#define __sfr volatile unsigned char +#define __sbit volatile bool +#define __critical +#define __at(x) +#define __using(x) +#define __interrupt(x) +#define __naked +#endif + +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_FASTCALL +#define CC_CONF_VA_ARGS 1 +#define CC_CONF_UNSIGNED_CHAR_BUGS 0 +#define CC_CONF_REGISTER_ARGS 0 +#define CC_CONF_FUNCTION_POINTER_KEYWORD __reentrant + +/* Generic types. */ +typedef unsigned char u8_t; /* 8 bit type */ +typedef unsigned short u16_t; /* 16 bit type */ +typedef unsigned long u32_t; /* 32 bit type */ +typedef signed long s32_t; /* 32 bit type */ +typedef unsigned short uip_stats_t; + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Single asm instruction without messing up syntax highlighting */ +#if defined SDCC_mcs51 +#define ASM(x) __asm \ + x \ + __endasm +#else +#define ASM(x) +#endif + +/* Critical section management */ +#define DISABLE_INTERRUPTS() do {EA = 0;} while(0) +#define ENABLE_INTERRUPTS() do {EA = 1;} while(0) + +/* Macro for a soft reset. In many respects better than H/W reboot via W/D */ +#define SOFT_RESET() {((void (__code *) (void)) 0x0000) ();} + +/* We don't provide architecture-specific checksum calculations */ +#define UIP_ARCH_ADD32 0 +#define UIP_ARCH_CHKSUM 0 + +#define CC_CONF_ASSIGN_AGGREGATE(dest, src) \ + memcpy(dest, src, sizeof(*dest)) + +#define uip_ipaddr_copy(dest, src) \ + memcpy(dest, src, sizeof(*dest)) + +#endif /* __8051_DEF_H__ */ diff --git a/cpu/cc253x/Makefile.cc253x b/cpu/cc253x/Makefile.cc253x new file mode 100644 index 000000000..568d8f2d9 --- /dev/null +++ b/cpu/cc253x/Makefile.cc253x @@ -0,0 +1,198 @@ +### Compiler definitions +CC = sdcc +LD = sdcc +AS = sdcc +AR = sdcclib +OBJCOPY = objcopy +STRIP = strip + +### Hex file conversions +PACKIHX = packihx +SREC_CAT = srec_cat +SREC_FLAGS = -disable_sequence_warnings + +BANK_ALLOC = $(CONTIKI_CPU)/bank-alloc.py +SEGMENT_RULES = $(OBJECTDIR)/segment.rules + +CFLAGS += --model-$(MEMORY_MODEL) --stack-auto --std-c99 + +LDFLAGS += --model-$(MEMORY_MODEL) --stack-auto --out-fmt-ihx +LDFLAGS += --xram-loc 0x0000 --xram-size 0x1F00 +LDFLAGS += --code-loc $(START_ADDR) --code-size $(CODE_SIZE) + +ASFLAGS += -plosgff + +AROPTS = -a + +### Our object files are .rel, so we can't use the default finalize dependency +### generation. Override here. +define FINALIZE_SDCC_DEPENDENCY +cp $(@:.rel=.d) $(@:.rel=.$$$$); \ +sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:.rel=.$$$$) >> $(@:.rel=.d); \ +rm -f $(@:.rel=.$$$$) +endef + +### Banking Guesswork: +### Generic examples do not specify banking. +### We automatically turn it on if its unspecified and if we are building with +### UIP_CONF_IPV6 +ifndef HAVE_BANKING + ifeq ($(UIP_CONF_IPV6),1) + HAVE_BANKING=1 + else + HAVE_BANKING=0 + endif +endif + +### Does the project want us to offset the firmware? +### define start address and max code size accordingly +ifeq ($(OFFSET_FIRMWARE),1) + START_ADDR = 0x01000 + HOME_START = 00001000 + ifeq ($(HAVE_BANKING),1) + CODE_SIZE = 0x3F000 + else + CODE_SIZE = 0x0F000 + endif +else + START_ADDR = 0x00000 + HOME_START = 00000000 + ifeq ($(HAVE_BANKING),1) + CODE_SIZE = 0x40000 + else + CODE_SIZE = 0x10000 + endif +endif + +### Are we building with BANKing supoprt? +ifeq ($(HAVE_BANKING),1) + ## Yes + MEMORY_MODEL=huge + LDFLAGS += -Wl-r + LD_PRE_FLAGS += -Wl-bBANK1=0x018000 + CFLAGS += -DHAVE_SDCC_BANKING + #use this in $(call c_seg,$<) to get segment for a source file. + c_seg = --codeseg $(shell python $(BANK_ALLOC) $1 $(SEGMENT_RULES) $2) +else + ## No banking + MEMORY_MODEL=large + c_seg = +endif + +### CPU-dependent cleanup files +CLEAN += *.lnk *.lk *.sym *.lib *.ihx *.rel *.mem *.rst *.asm *.hex +CLEAN += *.omf *.cdb *.banks *.flags *.banked-hex +CLEAN += symbols.c symbols.h + +### CPU-dependent directories +CONTIKI_CPU_DIRS = . dev + +### CPU-dependent source files +CONTIKI_SOURCEFILES += soc.c clock.c +CONTIKI_SOURCEFILES += uart0.c uart1.c uart-intr.c +CONTIKI_SOURCEFILES += dma.c dma_intr.c +CONTIKI_SOURCEFILES += cc2530-rf.c +CONTIKI_SOURCEFILES += watchdog.c rtimer-arch.c +CONTIKI_ASMFILES += + +CONTIKI_ASMOBJECTFILES = $(addprefix $(OBJECTDIR)/,$(CONTIKI_ASMFILES:.S=.rel)) + +CONTIKI_CASMOBJECTFILES = $(addprefix $(OBJECTDIR)/, \ + $(CONTIKI_CASMFILES:.cS=.rel)) + +CONTIKI_PLATFORM_DIRS = $(PLATFORM_APPDIRS) \ + $(addprefix $(CONTIKI)/platform/$(TARGET)/, $(CONTIKI_TARGET_DIRS)) + +CONTIKI_CPU_DIRS_LIST = $(addprefix $(CONTIKI_CPU)/, \ + $(CONTIKI_CPU_DIRS)) + +oname = $(patsubst %.c,%.rel,$(patsubst %.S,%.rel,$(1))) + +CONTIKI_OBJECTFILES = $(addprefix $(OBJECTDIR)/, \ + $(call oname, $(CONTIKI_SOURCEFILES))) + +PROJECT_OBJECTFILES = $(addprefix $(OBJECTDIR)/, \ + $(call oname, $(PROJECT_SOURCEFILES))) + +### Compilation rules + +SEGMENT_RULE_FILES = $(foreach dir, . $(CONTIKI_PLATFORM_DIRS) \ + $(CONTIKI_CPU_DIRS_LIST), $(wildcard $(dir)/segment.rules) ) + +$(SEGMENT_RULES): $(SEGMENT_RULE_FILES) + cat $(SEGMENT_RULE_FILES) | \ + sed -e 's/#.*$$//' -e 's/^\s*//' -e '/^$$/d' > $@ + +CUSTOM_RULE_LINK=1 +CUSTOM_RULE_C_TO_OBJECTDIR_O=1 +CUSTOM_RULE_ALLOBJS_TO_TARGETLIB=1 + +$(OBJECTDIR)/%.rel: %.c $(SEGMENT_RULES) + $(CC) $(call c_seg,$<,$@) $(CFLAGS) -c $< -o $@ -Wp,-MMD,$(@:.rel=.d),-MQ,$@ + @$(FINALIZE_SDCC_DEPENDENCY) + +$(OBJECTDIR)/%.rel: %.cS + cp $< $(OBJECTDIR)/$*.c + $(CC) $(CFLAGS) -E $(OBJECTDIR)/$*.c > $(OBJECTDIR)/tmp + perl -pe "s/^#(.*)/;$$1/" $(OBJECTDIR)/tmp > $(OBJECTDIR)/$*.S + $(AS) $(ASFLAGS) -o $@ $(OBJECTDIR)/$*.S + rm -f $(OBJECTDIR)/tmp + +contiki-$(TARGET).lib: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) \ + $(CONTIKI_ASMOBJECTFILES) $(CONTIKI_CASMOBJECTFILES) + rm -f $@ + for target in $^; do echo $$target >> $@; done + +.PRECIOUS: %.$(TARGET) %.hex + +# build app/example local object files. We need a separate rule so that we can +# pass -DAUTOSTART_ENABLE for those files only +$(OBJECTDIR)/%.app.rel: %.c $(SEGMENT_RULES) + $(CC) $(call c_seg,$<,$@) -DAUTOSTART_ENABLE $(CFLAGS) -c $< -o $@ + +# .ihx is the sdcc binary output file +ifeq ($(HAVE_BANKING),1) +### Build bankable firmware +%.ihx: $(OBJECTDIR)/%.app.rel $(CONTIKI_TARGET_MAIN) contiki-$(TARGET).lib + @echo "\nFirst Link" + @echo "===============" + $(CC) $(LDFLAGS) $(LD_PRE_FLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib > /dev/null + +%.flags: %.ihx +### Allocate modules to banks and relocate object files + @echo "\nBank Allocation" + @echo "===============" + python $(BANK_ALLOC) $(basename $(@F)) $(SEGMENT_RULES) $(OFFSET_FIRMWARE) + +%.banked-hex: %.flags +### Link again with new bank allocations + @echo "\nFinal Link" + @echo "===============" + $(CC) $(LDFLAGS) $(shell cat $<) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib > /dev/null + +%.hex: %.banked-hex +### Post-process the hex file for programmers which dislike SDCC output hex format + $(eval BANKS := $(shell egrep '(^BANK[0-9])=' $(@:.hex=.map) | sed -e 's/BANK\([0-9]\).*/\1/' | uniq)) + $(eval FILES := $(addsuffix .hex,$(addprefix bank,$(BANKS)))) + @echo "\nPack hex file" + @echo "===============" + @for bank in $(BANKS); do \ + echo $(SREC_CAT) $(SREC_FLAGS) $(@:.hex=.banked-hex) -intel \ + -crop 0x"$$bank"8000 "0x"$$bank"FFFF" \ + -offset -$$((0x8000 * $$bank + 0x08000)) -o bank"$$bank".hex -intel; \ + $(SREC_CAT) $(SREC_FLAGS) $(@:.hex=.banked-hex) -intel \ + -crop 0x"$$bank"8000 "0x"$$bank"FFFF" \ + -offset -$$((0x8000 * $$bank + 0x08000)) -o bank"$$bank".hex -intel; \ + done + $(SREC_CAT) $(SREC_FLAGS) $(@:.hex=.banked-hex) -intel -crop 0x00000 0x07FFF -o home.ihx -intel + srec_cat home.ihx -intel $(foreach file,$(FILES),$(file) -intel) -o $@ -intel + rm -f home.ihx $(FILES) +else +### Build non-banked firmware +%.ihx: $(OBJECTDIR)/%.app.rel $(CONTIKI_TARGET_MAIN) contiki-$(TARGET).lib + $(CC) $(LDFLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib > /dev/null + +%.hex: %.ihx + $(PACKIHX) $< > $@ +endif diff --git a/cpu/cc253x/bank-alloc.py b/cpu/cc253x/bank-alloc.py new file mode 100644 index 000000000..f2d264538 --- /dev/null +++ b/cpu/cc253x/bank-alloc.py @@ -0,0 +1,245 @@ +#!/usr/bin/env python + +# Copyright (c) 2010, Loughborough University - 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. + +# \file +# Automatic allocation of modules to code segments for bankable builds +# with SDCC's huge memory model. +# +# \author +# George Oikonomou - +import sys +import re +import operator +import fileinput +import os + +# Open a module object file (.rel) and read it's code size +def retrieve_module_size(file_name): + size_pat = re.compile('^A\s+(?:HOME|BANK[0-9])\s+size\s+([1-9A-F][0-9A-F]*)') + for code_line in open(file_name): + matches = size_pat.search(code_line) + if matches is not None: + return int(matches.group(1), 16) + return 0 + +# Searches for a code segment rule for file_name in the segment_rules file +# If there is a rule, we respect it. Otherwise, we can move the file around +def get_source_seg(source_file, object_file, segment_rules): + for line in open(segment_rules): + tokens = line.split(None) + match = re.search(tokens[1], source_file) + if match is not None: + # Save it in basename.seg + base, ext = os.path.splitext(object_file) + of = open(base + '.seg', 'w') + of.write(tokens[0] + '\n') + of.close + return tokens[0] + return None + +# If segment.rules specified a rule for a source file, the respective object +# file's banking requirement will be stored in object_file.seg +def get_object_seg(object_file): + base, ext = os.path.splitext(object_file) + seg = base + '.seg' + bank = None + if os.path.isfile(seg) is True: + of = open(base + '.seg', 'r') + bank = of.readline().strip() + of.close() + return bank + +# Open project.mem and retreive the project's total code footprint +def get_total_size(project): + mem_file = project + '.mem' + pat = re.compile('FLASH\s+(0x[0-9a-f]+\s+){2}([0-9]+)') + for line in open(mem_file): + l = pat.search(line) + if l is not None: + return int(l.group(2)) + +# Open project.map and retrieve the list of modules linked in +# This will only consider contiki sources, not SDCC libraries +# NB: Sometimes object filenames get truncated: +# contiki-sensinode.lib [ obj_sensinode/watchdog-cc2430.re ] +# See how for this file the 'l' in 'rel' is missing. For that reason, we retrieve +# the filaname until the last '.' but without the extension and we append 'rel' +# As long as the filename doesn't get truncated, we're good +def populate(project, modules, segment_rules, bins): + bankable_total = 0 + user_total = 0 + + map_file = project + '.map' + file_pat = re.compile('obj_cc2530dk[^ ]+\.') + for line in open(map_file): + file_name = file_pat.search(line) + if file_name is not None: + mod = file_name.group(0) + 'rel' + code_size = retrieve_module_size(mod) + seg = get_object_seg(mod) + if seg is not None: + # This module has been assigned to a bank by the user + #print 'In', seg, file_name.group(0), 'size', code_size + bins[seg][0] += code_size + user_total += code_size + else: + # We are free to allocate this module + modules.append([mod, code_size, "NONE"]) + bankable_total += code_size + return bankable_total, user_total + +# Allocate bankable modules to banks according to a simple +# 'first fit, decreasing' bin packing heuristic. +def bin_pack(modules, bins, offset, log): + if offset==1: + bins['HOME'][1] -= 4096 + + # Sort by size, descending, in=place + modules.sort(key=operator.itemgetter(1), reverse=True) + + for module in modules: + # We want to iterate in a specific order and dict.keys() won't do that + for bin_id in ['HOME', 'BANK1', 'BANK2', 'BANK3', 'BANK4', 'BANK5', 'BANK6', 'BANK7']: + if bins[bin_id][0] + module[1] < bins[bin_id][1]: + bins[bin_id][0] += module[1] + module[2] = bin_id + log.writelines(' '.join([module[2].ljust(8), \ + str(module[1]).rjust(5), module[0], '\n'])) + break + else: + if bin_id == 'BANK7': + print "Failed to allocate", module[0], "with size", module[1], \ + "to a code bank. This is fatal" + return 1 + return 0 + +# Hack the new bank directly in the .rel file +def relocate(module, bank): + code_pat = re.compile('(A\s+)(?:HOME|BANK[0-9])(\s+size\s+[1-9A-F][0-9A-F]*.+\n)') + + for line in fileinput.input(module, inplace=1): + m = code_pat.search(line) + if m is not None: + line = m.group(1) + bank + m.group(2) + sys.stdout.write(line) + return + +if len(sys.argv) < 3: + print 'Usage:' + print 'bank-alloc.py project path_to_segment_rules [offset]' + print 'bank-alloc.py source_file path_to_segment_rules object_file' + sys.exit(1) + +modules = list() +file_name = sys.argv[1] +segment_rules = sys.argv[2] + +# Magic: Guess whether we want to determine the code bank for a code file +# or whether we want to bin-pack +basename, ext = os.path.splitext(file_name) +if ext == '.c': + # Code Segment determination + if len(sys.argv) < 4: + print 'Usage:' + print 'bank-alloc.py project path_to_segment_rules [offset]' + print 'bank-alloc.py source_file path_to_segment_rules object_file' + sys.exit(1) + object_file = sys.argv[3] + seg = get_source_seg(file_name, object_file, segment_rules) + if seg is None: + print "BANK1" + else: + print seg + exit() + +# Bin-Packing +offset = 0 +if len(sys.argv) > 3 and sys.argv[3] is not None: + offset = int(sys.argv[3]) + +sizes = {'total': 0, 'bankable': 0, 'user': 0, 'libs': 0} + +# Name : [Allocated, capacity, start_addr] +bins = { + 'HOME': [0, 32768, '0x000000'], + 'BANK1': [0, 32768, '0x018000'], + 'BANK2': [0, 32768, '0x028000'], + 'BANK3': [0, 32768, '0x038000'], + 'BANK4': [0, 32768, '0x048000'], + 'BANK5': [0, 32768, '0x058000'], + 'BANK6': [0, 32768, '0x068000'], + 'BANK7': [0, 32768, '0x078000'], +} + +sizes['total'] = get_total_size(basename) +sizes['bankable'], sizes['user'] = populate(basename, modules, segment_rules, bins) +sizes['libs'] = sizes['total'] - sizes['bankable'] - sizes['user'] + +print 'Total Size =', sizes['total'], 'bytes (' + \ + str(sizes['bankable']), 'bankable,', \ + str(sizes['user']), 'user-allocated,', \ + str(sizes['libs']), 'const+libs)' + +bins['HOME'][0] += sizes['libs'] + +print 'Preallocations: HOME=' + str(bins['HOME'][0]), +for bin_id in ['BANK1', 'BANK2', 'BANK3', 'BANK4', 'BANK5', 'BANK6', 'BANK7']: + if bins[bin_id][0] > 0: + print ", " + bin_id + "=" + str(bins[bin_id][0]), +print + +# Open a log file +of = open(basename + '.banks', 'w') +pack = bin_pack(modules, bins, offset, of) +of.close() + +print "Bin-Packing results (target allocation):" +print "Segment - max - alloc" +for bin_id in ['HOME', 'BANK1', 'BANK2', 'BANK3', 'BANK4', 'BANK5', 'BANK6', 'BANK7']: + if bins[bin_id][0] > 0: + print bin_id.rjust(7), str(bins[bin_id][1]).rjust(6), str(bins[bin_id][0]).rjust(6) + +if pack > 0: + sys.exit(1) + +# If we reach here we seem to have a sane allocation. Start changing .rel files +for module in modules: + relocate(module[0], module[2]) + +flags = "" +# Export LD_POST_FLAGS +for bin_id in ['BANK1', 'BANK2', 'BANK3', 'BANK4', 'BANK5', 'BANK6', 'BANK7']: + if bins[bin_id][0] > 0: + flags += "-Wl-b" + bin_id + "=" + bins[bin_id][2] + " " +# Write LD_POST_FLAGS in project.flags +of = open(basename + '.flags', 'w') +of.write(flags + '\n') +of.close() diff --git a/cpu/cc253x/cc253x.h b/cpu/cc253x/cc253x.h new file mode 100644 index 000000000..27c022eec --- /dev/null +++ b/cpu/cc253x/cc253x.h @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Definitions for TI/Chipcon cc2530, cc2531 and cc2533 SFR registers. + * + * Based on information in: + * "CC253x System-on-Chip Solution for 2.4-GHz IEEE 802.15.4 and ZigBee® + * Applications" + * Literature Number: SWRU191B. April 2009–Revised September 2010 + * + * \author + * George Oikonomou - + */ + +#ifndef __CC253X_H__ +#define __CC253X_H__ + +/*---------------------------------------------------------------------------*/ +/* Compiler Abstraction */ +#include +/*--------------------------------------------------------------------------- + * Interrupt Vectors + * (Table 2.5, page 40) + *---------------------------------------------------------------------------*/ +#define RFERR_VECTOR 0 /* RF TXFIFO underflow and RXFIFO overflow. */ +#define ADC_VECTOR 1 /* ADC end of conversion */ +#define URX0_VECTOR 2 /* USART 0 RX complete */ +#define URX1_VECTOR 3 /* USART 1 RX complete */ +#define ENC_VECTOR 4 /* AES encryption/decryption complete */ +#define ST_VECTOR 5 /* Sleep Timer compare */ +#define P2INT_VECTOR 6 /* Port 2 inputs/USB/I2C */ +#define UTX0_VECTOR 7 /* USART 0 TX complete */ +#define DMA_VECTOR 8 /* DMA transfer complete */ +#define T1_VECTOR 9 /* Timer 1 (16-bit) capture/compare/overflow */ +#define T2_VECTOR 10 /* Timer 2 (MAC Timer) */ +#define T3_VECTOR 11 /* Timer 3 (8-bit) compare/overflow */ +#define T4_VECTOR 12 /* Timer 4 (8-bit) compare/overflow */ +#define P0INT_VECTOR 13 /* Port 0 inputs */ +#define UTX1_VECTOR 14 /* USART1 TX complete */ +#define P1INT_VECTOR 15 /* Port 1 inputs */ +#define RF_VECTOR 16 /* RF general interrupts */ +#define WDT_VECTOR 17 /* Watchdog overflow in timer mode */ +/*--------------------------------------------------------------------------- + * Special Function Registers and BITs + * (Table 2.1, page 27) + *---------------------------------------------------------------------------*/ +/* 8051 Internals */ +SFR(P0, 0x80); /* Port 0 */ + SBIT(P0_7, 0x80, 7); /* Port 0 bit 7 */ + SBIT(P0_6, 0x80, 6); /* Port 0 bit 6 */ + SBIT(P0_5, 0x80, 5); /* Port 0 bit 5 */ + SBIT(P0_4, 0x80, 4); /* Port 0 bit 4 */ + SBIT(P0_3, 0x80, 3); /* Port 0 bit 3 */ + SBIT(P0_2, 0x80, 2); /* Port 0 bit 2 */ + SBIT(P0_1, 0x80, 1); /* Port 0 bit 1 */ + SBIT(P0_0, 0x80, 0); /* Port 0 bit 0 */ +SFR(SP, 0x81); /* Stack pointer */ +SFR(DPL0, 0x82); /* Data pointer 0 low byte */ +SFR(DPH0, 0x83); /* Data pointer 0 high byte */ +SFR(DPL1, 0x84); /* Data pointer 1 low byte */ +SFR(DPH1, 0x85); /* Data pointer 1 high byte */ +SFR(PCON, 0x87); /* Power mode control */ +SFR(TCON, 0x88); /* Interrupt flags */ + SBIT(URX1IF, 0x88, 7); /* USART1 RX interrupt flag */ + SBIT(ADCIF, 0x88, 5); /* ADC interrupt flag */ + SBIT(URX0IF, 0x88, 3); /* USART0 RX interrupt flag */ + SBIT(IT1, 0x88, 2); /* Reserved. Must always be set to 1 */ + SBIT(RFERRIF, 0x88, 1); /* RF TXFIFO/RXFIFO interrupt flag */ + SBIT(IT0, 0x88, 0); /* Reserved. Must always be set to 1 */ +SFR(P1, 0x90); /* Port 1 */ + SBIT(P1_7, 0x90, 7); /* Port 1 bit 7 */ + SBIT(P1_6, 0x90, 6); /* Port 1 bit 6 */ + SBIT(P1_5, 0x90, 5); /* Port 1 bit 5 */ + SBIT(P1_4, 0x90, 4); /* Port 1 bit 4 */ + SBIT(P1_3, 0x90, 3); /* Port 1 bit 3 */ + SBIT(P1_2, 0x90, 2); /* Port 1 bit 2 */ + SBIT(P1_1, 0x90, 1); /* Port 1 bit 1 */ + SBIT(P1_0, 0x90, 0); /* Port 1 bit 0 */ +SFR(DPS, 0x92); /* Data pointer select */ +SFR(S0CON, 0x98); /* Interrupt flags 2 */ + SBIT(ENCIF_1, 0x98, 1); /* AES Interrupt flag 1 */ + SBIT(ENCIF_0, 0x98, 0); /* AES Interrupt flag 0 */ +SFR(IEN2, 0x9A); /* Interrupt enable 2 */ +SFR(S1CON, 0x9B); /* Interrupt flags 3 */ +SFR(P2, 0xA0); /* Port 2 */ + SBIT(P2_7, 0xA0, 7); /* Port 2 bit 7 */ + SBIT(P2_6, 0xA0, 6); /* Port 2 bit 6 */ + SBIT(P2_5, 0xA0, 5); /* Port 2 bit 5 */ + SBIT(P2_4, 0xA0, 4); /* Port 2 bit 4 */ + SBIT(P2_3, 0xA0, 3); /* Port 2 bit 3 */ + SBIT(P2_2, 0xA0, 2); /* Port 2 bit 2 */ + SBIT(P2_1, 0xA0, 1); /* Port 2 bit 1 */ + SBIT(P2_0, 0xA0, 0); /* Port 2 bit 0 */ +SFR(IEN0, 0xA8); /* Interrupt enable 0 */ + SBIT(EA, 0xA8, 7); /* All interrupts - enable/disable */ + SBIT(STIE, 0xA8, 5); /* Sleep Timer interrupt enable */ + SBIT(ENCIE, 0xA8, 4); /* AES encryption/decryption interrupt enable */ + SBIT(URX1IE, 0xA8, 3); /* USART1 RX interrupt enable */ + SBIT(URX0IE, 0xA8, 2); /* USART0 RX interrupt enable */ + SBIT(ADCIE, 0xA8, 1); /* ADC interrupt enable */ + SBIT(RFERRIE, 0xA8, 0); /* RF TXFIFO/RXFIFO interrupt enable */ +SFR(IP0, 0xA9); /* Interrupt priority 0 */ +SFR(IEN1, 0xB8); /* Interrupt enable 1 */ + SBIT(P0IE, 0xB8, 5); /* Port 0 interrupt enable */ + SBIT(T4IE, 0xB8, 4); /* Timer 4 interrupt enable */ + SBIT(T3IE, 0xB8, 3); /* Timer 3 interrupt enable */ + SBIT(T2IE, 0xB8, 2); /* Timer 2 interrupt enable */ + SBIT(T1IE, 0xB8, 1); /* Timer 1 interrupt enable */ + SBIT(DMAIE, 0xB8, 0); /* DMA Transfer interrupt enable */ +SFR(IP1, 0xB9); /* Interrupt priority 1 */ +SFR(IRCON, 0xC0); /* Interrupt flags 4 */ + SBIT(STIF, 0xC0, 7); /* Sleep Timer interrupt flag */ + SBIT(P0IF, 0xC0, 5); /* Port 0 interrupt flag */ + SBIT(T4IF, 0xC0, 4); /* Timer 4 interrupt flag */ + SBIT(T3IF, 0xC0, 3); /* Timer 3 interrupt flag */ + SBIT(T2IF, 0xC0, 2); /* Timer 2 interrupt flag */ + SBIT(T1IF, 0xC0, 1); /* Timer 1 interrupt flag */ + SBIT(DMAIF, 0xC0, 0); /* DMA-complete interrupt flag */ +SFR(PSW, 0xD0); /* Program status word */ + SBIT(CY, 0xD0, 7); /* Carry flag */ + SBIT(AC, 0xD0, 6); /* Auxiliary carry flag */ + SBIT(F0, 0xD0, 5); /* User-defined flag 1, bit addressable */ + SBIT(RS1, 0xD0, 4); /* Register bank select, bit 1 */ + SBIT(RS0, 0xD0, 3); /* Register bank select, bit 0 */ + SBIT(OV, 0xD0, 2); /* Overflow flag */ + SBIT(F1, 0xD0, 1); /* User-defined flag 0, bit addressable */ + SBIT(P, 0xD0, 0); /* Parity flag */ +SFR(ACC, 0xE0); /* Accumulator */ + SBIT(ACC_7, 0xE0, 7); /* Accumulator bit 7 */ + SBIT(ACC_6, 0xE0, 6); /* Accumulator bit 6 */ + SBIT(ACC_5, 0xE0, 5); /* Accumulator bit 5 */ + SBIT(ACC_4, 0xE0, 4); /* Accumulator bit 4 */ + SBIT(ACC_3, 0xE0, 3); /* Accumulator bit 3 */ + SBIT(ACC_2, 0xE0, 2); /* Accumulator bit 2 */ + SBIT(ACC_1, 0xE0, 1); /* Accumulator bit 1 */ + SBIT(ACC_0, 0xE0, 0); /* Accumulator bit 0 */ +SFR(IRCON2, 0xE8); /* Interrupt flags 5 */ + SBIT(WDTIF, 0xE8, 4); /* Watchdog Timer interrupt flag */ + SBIT(P1IF, 0xE8, 3); /* Port 1 Interrupt flag */ + SBIT(UTX1IF, 0xE8, 2); /* USART1 TX interrupt flag */ + SBIT(UTX0IF, 0xE8, 1); /* USART0 TX interrupt flag */ + SBIT(P2IF, 0xE8, 0); /* Port 2 interrupt flag */ +SFR(B, 0xF0); /* B Register */ + SBIT(B_7, 0xF0, 7); /* Register B bit 7 */ + SBIT(B_6, 0xF0, 6); /* Register B bit 6 */ + SBIT(B_5, 0xF0, 5); /* Register B bit 5 */ + SBIT(B_4, 0xF0, 4); /* Register B bit 4 */ + SBIT(B_3, 0xF0, 3); /* Register B bit 3 */ + SBIT(B_2, 0xF0, 2); /* Register B bit 2 */ + SBIT(B_1, 0xF0, 1); /* Register B bit 1 */ + SBIT(B_0, 0xF0, 0); /* Register B bit 0 */ + +/* ADC */ +SFR(ADCCON1, 0xB4); /* ADC control 1 */ +SFR(ADCCON2, 0xB5); /* ADC control 2 */ +SFR(ADCCON3, 0xB6); /* ADC control 3 */ +SFR(ADCL, 0xBA); /* ADC data low */ +SFR(ADCH, 0xBB); /* ADC data high */ +SFR(RNDL, 0xBC); /* Random number generator data low */ +SFR(RNDH, 0xBD); /* Random number generator data high */ + +/* AES Coprocessor */ +SFR(ENCDI, 0xB1); /* Encryption/decryption input data */ +SFR(ENCDO, 0xB2); /* Encryption/decryption output data */ +SFR(ENCCS, 0xB3); /* Encryption/decryption control and status */ + +/* DMA Controller */ +SFR(DMAIRQ, 0xD1); /* DMA interrupt flag */ +SFR(DMA1CFGL, 0xD2); /* DMA channel 1–4 configuration address low */ +SFR(DMA1CFGH, 0xD3); /* DMA channel 1–4 configuration address high */ +SFR(DMA0CFGL, 0xD4); /* DMA channel 0 configuration address low */ +SFR(DMA0CFGH, 0xD5); /* DMA channel 0 configuration address high */ +SFR(DMAARM, 0xD6); /* DMA channel armed */ +SFR(DMAREQ, 0xD7); /* DMA channel start request and status */ + +/* I/O */ +SFR(P0IFG, 0x89); /* Port 0 interrupt status flag */ +SFR(P1IFG, 0x8A); /* Port 1 interrupt status flag */ +SFR(P2IFG, 0x8B); /* Port 2 interrupt status flag */ +SFR(PICTL, 0x8C); /* Port pins interrupt mask and edge */ +SFR(P0IEN, 0xAB); /* Port 0 interrupt mask */ +SFR(P1IEN, 0x8D); /* Port 1 interrupt mask */ +SFR(P2IEN, 0xAC); /* Port 2 interrupt mask */ +SFR(P0INP, 0x8F); /* Port 0 input Mode */ +SFR(PERCFG, 0xF1); /* Peripheral I/O control */ +SFR(APCFG, 0xF2); /* Analog peripheral I/O configuration */ +SFR(P0SEL, 0xF3); /* Port 0 function select */ +SFR(P1SEL, 0xF4); /* Port 1 function select */ +SFR(P2SEL, 0xF5); /* Port 2 function select */ +SFR(P1INP, 0xF6); /* Port 1 input mode */ +SFR(P2INP, 0xF7); /* Port 2 input mode */ +SFR(P0DIR, 0xFD); /* Port 0 direction */ +SFR(P1DIR, 0xFE); /* Port 1 direction */ +SFR(P2DIR, 0xFF); /* Port 2 direction */ +SFR(PMUX, 0xAE); /* Power-down signal mux */ + +/* Memory */ +SFR(MPAGE, 0x93); /* Memory page select */ +SFR(_XPAGE, 0x93); /* Memory page select - SDCC name */ +SFR(MEMCTR, 0xC7); /* Memory system control */ +SFR(FMAP, 0x9F); /* Flash-memory bank mapping */ +SFR(PSBANK, 0x9F); /* Flash-memory bank mapping - SDCC name */ + +/* RF */ +SFR(RFIRQF1, 0x91); /* RF interrupt flags MSB */ +SFR(RFD, 0xD9); /* RF data */ +SFR(RFST, 0xE1); /* RF command strobe */ +SFR(RFIRQF0, 0xE9); /* RF interrupt flags LSB */ +SFR(RFERRF, 0xBF); /* RF error interrupt flags */ + +/* Sleep Timer */ +SFR(ST0, 0x95); /* Sleep Timer 0 */ +SFR(ST1, 0x96); /* Sleep Timer 1 */ +SFR(ST2, 0x97); /* Sleep Timer 2 */ +SFR(STLOAD, 0xAD); /* Sleep-timer load status */ +SFR(SLEEPCMD, 0xBE); /* Sleep-mode control command */ +SFR(SLEEPSTA, 0x9D); /* Sleep-mode control status */ + +/* Power Management and Clocks */ +SFR(CLKCONCMD, 0xC6); /* Clock control command */ +SFR(CLKCONSTA, 0x9E); /* Clock control status */ + +/* Timer 1 */ +SFR(T1CC0L, 0xDA); /* Timer 1 channel 0 capture/compare value low */ +SFR(T1CC0H, 0xDB); /* Timer 1 channel 0 capture/compare value high */ +SFR(T1CC1L, 0xDC); /* Timer 1 channel 1 capture/compare value low */ +SFR(T1CC1H, 0xDD); /* Timer 1 channel 1 capture/compare value high */ +SFR(T1CC2L, 0xDE); /* Timer 1 channel 2 capture/compare value low */ +SFR(T1CC2H, 0xDF); /* Timer 1 channel 2 capture/compare value high */ +SFR(T1CNTL, 0xE2); /* Timer 1 counter low */ +SFR(T1CNTH, 0xE3); /* Timer 1 counter high */ +SFR(T1CTL, 0xE4); /* Timer 1 control and status */ +SFR(T1CCTL0, 0xE5); /* Timer 1 channel 0 capture/compare control */ +SFR(T1CCTL1, 0xE6); /* Timer 1 channel 1 capture/compare control */ +SFR(T1CCTL2, 0xE7); /* Timer 1 channel 2 capture/compare control */ +SFR(T1STAT, 0xAF); /* Timer 1 status */ + +/* Timer 2 (MAC Timer) */ +SFR(T2CTRL, 0x94); /* Timer 2 control */ +SFR(T2EVTCFG, 0x9C); /* Timer 2 event configuration */ +SFR(T2IRQF, 0xA1); /* Timer 2 interrupt flags */ +SFR(T2M0, 0xA2); /* Timer 2 multiplexed register 0 */ +SFR(T2M1, 0xA3); /* Timer 2 multiplexed register 1 */ +SFR(T2MOVF0, 0xA4); /* Timer 2 multiplexed overflow register 0 */ +SFR(T2MOVF1, 0xA5); /* Timer 2 multiplexed overflow register 1 */ +SFR(T2MOVF2, 0xA6); /* Timer 2 multiplexed overflow register 2 */ +SFR(T2IRQM, 0xA7); /* Timer 2 interrupt mask */ +SFR(T2MSEL, 0xC3); /* Timer 2 multiplex select */ + +/* Timer 3 */ +SFR(T3CNT, 0xCA); /* Timer 3 counter */ +SFR(T3CTL, 0xCB); /* Timer 3 control */ +SFR(T3CCTL0, 0xCC); /* Timer 3 channel 0 compare control */ +SFR(T3CC0, 0xCD); /* Timer 3 channel 0 compare value */ +SFR(T3CCTL1, 0xCE); /* Timer 3 channel 1 compare control */ +SFR(T3CC1, 0xCF); /* Timer 3 channel 1 compare value */ + +/* Timer 4 */ +SFR(T4CNT, 0xEA); /* Timer 4 counter */ +SFR(T4CTL, 0xEB); /* Timer 4 control */ +SFR(T4CCTL0, 0xEC); /* Timer 4 channel 0 compare control */ +SFR(T4CC0, 0xED); /* Timer 4 channel 0 compare value */ +SFR(T4CCTL1, 0xEE); /* Timer 4 channel 1 compare control */ +SFR(T4CC1, 0xEF); /* Timer 4 channel 1 compare value */ + +/* Timer 1, 3, 4 join Interrupts */ +SFR(TIMIF, 0xD8); /* Timers 1/3/4 joint interrupt mask/flags */ + SBIT(OVFIM, 0xD8, 6); /* Timer 1 overflow interrupt mask */ + SBIT(T4CH1IF, 0xD8, 5); /* Timer 4 channel 1 interrupt flag */ + SBIT(T4CH0IF, 0xD8, 4); /* Timer 4 channel 0 interrupt flag */ + SBIT(T4OVFIF, 0xD8, 3); /* Timer 4 overflow interrupt flag */ + SBIT(T3CH1IF, 0xD8, 2); /* Timer 3 channel 1 interrupt flag */ + SBIT(T3CH0IF, 0xD8, 1); /* Timer 3 channel 0 interrupt flag */ + SBIT(T3OVFIF, 0xD8, 0); /* Timer 3 overflow interrupt flag */ + +/* USART 0 */ +SFR(U0CSR, 0x86); /* USART 0 control and status */ +SFR(U0DBUF, 0xC1); /* USART 0 receive/transmit data buffer */ +SFR(U0BAUD, 0xC2); /* USART 0 baud-rate control */ +SFR(U0UCR, 0xC4); /* USART 0 UART control */ +SFR(U0GCR, 0xC5); /* USART 0 generic control */ + +/* USART 1 */ +SFR(U1CSR, 0xF8); /* USART 1 control and status */ + SBIT(MODE, 0xF8, 7); /* USART mode select */ + SBIT(RE, 0xF8, 6); /* UART receiver enable */ + SBIT(SLAVE, 0xF8, 5); /* SPI master- or slave mode select */ + SBIT(FE, 0xF8, 4); /* UART framing error status */ + SBIT(ERR, 0xF8, 3); /* UART parity error status */ + SBIT(RX_BYTE, 0xF8, 2); /* Receive byte status */ + SBIT(TX_BYTE, 0xF8, 1); /* Transmit byte status */ + SBIT(ACTIVE, 0xF8, 0); /* USART transmit/receive active status */ +SFR(U1DBUF, 0xF9); /* USART 1 receive/transmit data buffer */ +SFR(U1BAUD, 0xFA); /* USART 1 baud-rate control */ +SFR(U1UCR, 0xFB); /* USART 1 UART control */ +SFR(U1GCR, 0xFC); /* USART 1 Generic control */ + +/* Watchdog Timer */ +SFR(WDCTL, 0xC9); /* Watchdog Timer Control */ +/*--------------------------------------------------------------------------- + * XREG Registers (0x6000–0x63FF), excluding RF and USB registers + * (Table 2.2, page 31) + *---------------------------------------------------------------------------*/ +SFRX(MONMUX , 0x61A6); /* Operational amplifier mode control (cc2530/31) */ +SFRX(OPAMPMC, 0x61A6); /* Battery monitor MUX (cc2533) */ +/* I2C registers - cc2533 only */ +SFRX(I2CCFG, 0x6230); /* I2C control */ +SFRX(I2CSTAT, 0x6231); /* I2C status */ +SFRX(I2CDATA, 0x6232); /* I2C data */ +SFRX(I2CADDR, 0x6233); /* I2C own slave address */ +SFRX(I2CWC, 0x6234); /* Wrapper Control */ +SFRX(I2CIO, 0x6235); /* GPIO */ +/* End I2C registers */ +SFRX(OBSSEL0, 0x6243); /* Observation output control - register 0 */ +SFRX(OBSSEL1, 0x6244); /* Observation output control - register 1 */ +SFRX(OBSSEL2, 0x6245); /* Observation output control - register 2 */ +SFRX(OBSSEL3, 0x6246); /* Observation output control - register 3 */ +SFRX(OBSSEL4, 0x6247); /* Observation output control - register 4 */ +SFRX(OBSSEL5, 0x6248); /* Observation output control - register 5 */ +SFRX(CHVER, 0x6249); /* Chip version */ +SFRX(CHIPID, 0x624A); /* Chip identification */ +SFRX(TR0, 0x624B); /* Test register 0 */ +SFRX(DBGDATA, 0x6260); /* Debug interface write data */ +SFRX(SRCRC, 0x6262); /* Sleep reset CRC */ +SFRX(BATTMON, 0x6264); /* Battery monitor */ +SFRX(IVCTRL, 0x6265); /* Analog control register */ +SFRX(FCTL, 0x6270); /* Flash control */ +SFRX(FADDRL, 0x6271); /* Flash address low */ +SFRX(FADDRH, 0x6272); /* Flash address high */ +SFRX(FWDATA, 0x6273); /* Flash write data */ +SFRX(CHIPINFO0, 0x6276); /* Chip information byte 0 */ +SFRX(CHIPINFO1, 0x6277); /* Chip information byte 1 */ +SFRX(IRCTL, 0x6281); /* Timer 1 IR generation control */ +SFRX(CLD, 0x6290); /* Clock-loss detection */ +SFRX(XX_T1CCTL0, 0x62A0); /* Timer 1 channel 0 capture/compare control (additional XREG mapping of SFR) */ +SFRX(XX_T1CCTL1, 0x62A1); /* Timer 1 channel 1 capture/compare control (additional XREG mapping of SFR register) */ +SFRX(XX_T1CCTL2, 0x62A2); /* Timer 1 channel 2 capture/compare control (additional XREG mapping of SFR register) */ +SFRX(T1CCTL3, 0x62A3); /* Timer 1 channel 3 capture/compare control */ +SFRX(T1CCTL4, 0x62A4); /* Timer 1 channel 4 capture/compare control */ +SFRX(XX_T1CC0L, 0x62A6); /* Timer 1 channel 0 capture/compare value low (additional XREG mapping of SFR register) */ +SFRX(XX_T1CC0H, 0x62A7); /* Timer 1 channel 0 capture/compare value high (additional XREG mapping of SFR register) */ +SFRX(XX_T1CC1L, 0x62A8); /* Timer 1 channel 1 capture/compare value low (additional XREG mapping of SFR register) */ +SFRX(XX_T1CC1H, 0x62A9); /* Timer 1 channel 1 capture/compare value high (additional XREG mapping of SFR register) */ +SFRX(XX_T1CC2L, 0x62AA); /* Timer 1 channel 2 capture/compare value low (additional XREG mapping of SFR register) */ +SFRX(XX_T1CC2H, 0x62AB); /* Timer 1 channel 2 capture/compare value high (additional XREG mapping of SFR register) */ +SFRX(T1CC3L, 0x62AC); /* Timer 1 channel 3 capture/compare value low */ +SFRX(T1CC3H, 0x62AD); /* Timer 1 channel 3 capture/compare value high */ +SFRX(T1CC4L, 0x62AE); /* Timer 1 channel 4 capture/compare value low */ +SFRX(T1CC4H, 0x62AF); /* Timer 1 channel 4 capture/compare value high */ +SFRX(STCC, 0x62B0); /* Sleep Timer capture control */ +SFRX(STCS, 0x62B1); /* Sleep Timer capture status */ +SFRX(STCV0, 0x62B2); /* Sleep Timer capture value byte 0 */ +SFRX(STCV1, 0x62B3); /* Sleep Timer capture value byte 1 */ +SFRX(STCV2, 0x62B4); /* Sleep Timer capture value byte 2 */ +SFRX(OPAMPC, 0x62C0); /* Operational amplifier control */ +SFRX(OPAMPS, 0x62C1); /* Operational amplifier status */ +SFRX(CMPCTL, 0x62D0); /* Analog comparator control and status */ +/*--------------------------------------------------------------------------- + * Radio Registers + * (Sec. 23, page 211) + *---------------------------------------------------------------------------*/ +SFRX(RFCORE_RAM, 0x6000); /* RF Core Memory Map (0x6000 to 0x0617F) */ +SFRX(RXFIFO, 0x6000); /* TXFIFO Direct Access (0x6000 to 0x607F) */ +SFRX(TXFIFO, 0x6080); /* TXFIFO Direct Access (0x6080 to 0x60FF) */ + +SFRX(SRC_ADDR_TABLE, 0x6100); /* Source Address Table Start */ + +/* Source Address Matching Result */ +SFRX(SRCRESMASK0, 0x6160); /* Extended address matching */ +SFRX(SRCRESMASK1, 0x6161); /* Short address matching */ +SFRX(SRCRESMASK2, 0x6162); /* Source address match - 24-bit mask */ +SFRX(SRCRESINDEX, 0x6163); /* Bit index of least-significant 1 in SRCRESMASK */ + +/* Source Address Matching Control */ +SFRX(SRCEXTPENDEN0, 0x6164); /* Ext. Address bit-mask 0 (LSB) */ +SFRX(SRCEXTPENDEN1, 0x6165); /* Ext. Address bit-mask 1 */ +SFRX(SRCEXTPENDEN2, 0x6166); /* Ext. Address bit-mask 2 (MSB) */ +SFRX(SRCSHORTPENDEN0, 0x6167); /* Short Address bit-mask 0 (LSB) */ +SFRX(SRCSHORTPENDEN1, 0x6168); /* Short Address bit-mask 1 */ +SFRX(SRCSHORTPENDEN2, 0x6169); /* Short Address bit-mask 2 (MSB) */ + +/* Local Address Information (used during destination address filtering) */ +SFRX(EXT_ADDR0, 0x616A); /* IEEE extended address 0 */ +SFRX(EXT_ADDR1, 0x616B); /* IEEE extended address 1 */ +SFRX(EXT_ADDR2, 0x616C); /* IEEE extended address 2 */ +SFRX(EXT_ADDR3, 0x616D); /* IEEE extended address 3 */ +SFRX(EXT_ADDR4, 0x616E); /* IEEE extended address 4 */ +SFRX(EXT_ADDR5, 0x616F); /* IEEE extended address 5 */ +SFRX(EXT_ADDR6, 0x6170); /* IEEE extended address 6 */ +SFRX(EXT_ADDR7, 0x6171); /* IEEE extended address 7 */ +SFRX(PAN_ID0, 0x6172); /* PAN ID 0 */ +SFRX(PAN_ID1, 0x6173); /* PAN ID 1 */ +SFRX(SHORT_ADDR0, 0x6174); /* Short Address 0 */ +SFRX(SHORT_ADDR1, 0x6175); /* Short Address 1 */ + +SFRX(FRMFILT0, 0x6180); /* Frame Filtering 0 */ +SFRX(FRMFILT1, 0x6181); /* Frame Filtering 1 */ +SFRX(SRCMATCH, 0x6182); /* Source Address Matching and Pending Bits */ +SFRX(SRCSHORTEN0, 0x6183); /* Short Address Matching 0 */ +SFRX(SRCSHORTEN1, 0x6184); /* Short Address Matching 1 */ +SFRX(SRCSHORTEN2, 0x6185); /* Short Address Matching 2 */ +SFRX(SRCEXTEN0, 0x6186); /* Extended Address Matching 0 */ +SFRX(SRCEXTEN1, 0x6187); /* Extended Address Matching 1 */ +SFRX(SRCEXTEN2, 0x6188); /* Extended Address Matching 2 */ +SFRX(FRMCTRL0, 0x6189); /* Frame Handling */ +SFRX(FRMCTRL1, 0x618A); /* Frame Handling */ +SFRX(RXENABLE, 0x618B); /* RX Enabling */ +SFRX(RXMASKSET, 0x618C); /* RX Enabling */ +SFRX(RXMASKCLR, 0x618D); /* RX Disabling */ +SFRX(FREQTUNE, 0x618E); /* Crystal Oscillator Frequency Tuning */ +SFRX(FREQCTRL, 0x618F); /* RF Frequency Control */ +SFRX(TXPOWER, 0x6190); /* Controls the Output Power */ +SFRX(TXCTRL, 0x6191); /* Controls the TX Settings */ +SFRX(FSMSTAT0, 0x6192); /* Radio Status Register */ +SFRX(FSMSTAT1, 0x6193); /* Radio Status Register */ +SFRX(FIFOPCTRL, 0x6194); /* FIFOP Threshold */ +SFRX(FSMCTRL, 0x6195); /* FSM Options */ +SFRX(CCACTRL0, 0x6196); /* CCA Threshold */ +SFRX(CCACTRL1, 0x6197); /* Other CCA Options */ +SFRX(RSSI, 0x6198); /* RSSI Status Register */ +SFRX(RSSISTAT, 0x6199); /* RSSI Valid Status Register */ +SFRX(RXFIRST, 0x619A); /* First Byte in RXFIFO */ +SFRX(RXFIFOCNT, 0x619B); /* Number of Bytes in RXFIFO */ +SFRX(TXFIFOCNT, 0x619C); /* Number of Bytes in TXFIFO */ +SFRX(RXFIRST_PTR, 0x619D); /* RXFIFO Pointer */ +SFRX(RXLAST_PTR, 0x619E); /* RXFIFO Pointer */ +SFRX(RXP1_PTR, 0x619F); /* RXFIFO Pointer */ +SFRX(TXFIRST_PTR, 0x61A1); /* TXFIFO Pointer */ +SFRX(TXLAST_PTR, 0x61A2); /* TXFIFO Pointer */ +SFRX(RFIRQM0, 0x61A3); /* RF Interrupt Masks 0 */ +SFRX(RFIRQM1, 0x61A4); /* RF Interrupt Masks 1 */ +SFRX(RFERRM, 0x61A5); /* RF Error Interrupt Mask */ +SFRX(RFRND, 0x61A7); /* Random Data */ +SFRX(MDMCTRL0, 0x61A8); /* Controls Modem 0 */ +SFRX(MDMCTRL1, 0x61A9); /* Controls Modem 1 */ +SFRX(FREQEST, 0x61AA); /* Estimated RF Frequency Offset */ +SFRX(RXCTRL, 0x61AB); /* Tune Receive Section */ +SFRX(FSCTRL, 0x61AC); /* Tune Frequency Synthesizer */ +SFRX(FSCAL0, 0x61AD); /* Tune Frequency Calibration 0 */ +SFRX(FSCAL1, 0x61AE); /* Tune Frequency Calibration 1 */ +SFRX(FSCAL2, 0x61AF); /* Tune Frequency Calibration 2 */ +SFRX(FSCAL3, 0x61B0); /* Tune Frequency Calibration 3 */ +SFRX(AGCCTRL0, 0x61B1); /* AGC Dynamic Range Control */ +SFRX(AGCCTRL1, 0x61B2); /* AGC Reference Level */ +SFRX(AGCCTRL2, 0x61B3); /* AGC Gain Override */ +SFRX(AGCCTRL3, 0x61B4); /* AGC Control */ +SFRX(ADCTEST0, 0x61B5); /* ADC Tuning 0 */ +SFRX(ADCTEST1, 0x61B6); /* ADC Tuning 1 */ +SFRX(ADCTEST2, 0x61B7); /* ADC Tuning 2 */ +SFRX(MDMTEST0, 0x61B8); /* Test Register for Modem 0 */ +SFRX(MDMTEST1, 0x61B9); /* Test Register for Modem 1 */ +SFRX(DACTEST0, 0x61BA); /* DAC Override Value */ +SFRX(DACTEST1, 0x61BB); /* DAC Override Value */ +SFRX(DACTEST2, 0x61BC); /* DAC Test Setting */ +SFRX(ATEST, 0x61BD); /* Analog Test Control */ +SFRX(PTEST0, 0x61BE); /* Override Power-Down Register 0 */ +SFRX(PTEST1, 0x61BF); /* Override Power-Down Register 1 */ +SFRX(TXFILTCFG, 0x61FA); /* TX Filter Configuration */ +SFRX(RFC_OBS_CTRL0, 0x61EB); /* RF Observation Mux Control 0 */ +SFRX(RFC_OBS_CTRL1, 0x61EC); /* RF Observation Mux Control 1 */ +SFRX(RFC_OBS_CTRL2, 0x61ED); /* RF Observation Mux Control 2 */ + +/* Command Strobe/CSMA-CA Processor Registers */ +SFRX(CSPPROG0, 0x61C0); /* CSP Program Memory, Byte 0 */ +SFRX(CSPPROG1, 0x61C1); /* CSP Program Memory, Byte 1 */ +SFRX(CSPPROG2, 0x61C2); /* CSP Program Memory, Byte 2 */ +SFRX(CSPPROG3, 0x61C3); /* CSP Program Memory, Byte 3 */ +SFRX(CSPPROG4, 0x61C4); /* CSP Program Memory, Byte 4 */ +SFRX(CSPPROG5, 0x61C5); /* CSP Program Memory, Byte 5 */ +SFRX(CSPPROG6, 0x61C6); /* CSP Program Memory, Byte 6 */ +SFRX(CSPPROG7, 0x61C7); /* CSP Program Memory, Byte 7 */ +SFRX(CSPPROG8, 0x61C8); /* CSP Program Memory, Byte 8 */ +SFRX(CSPPROG9, 0x61C9); /* CSP Program Memory, Byte 9 */ +SFRX(CSPPROG10, 0x61CA); /* CSP Program Memory, Byte 10 */ +SFRX(CSPPROG11, 0x61CB); /* CSP Program Memory, Byte 11 */ +SFRX(CSPPROG12, 0x61CC); /* CSP Program Memory, Byte 12 */ +SFRX(CSPPROG13, 0x61CD); /* CSP Program Memory, Byte 13 */ +SFRX(CSPPROG14, 0x61CE); /* CSP Program Memory, Byte 14 */ +SFRX(CSPPROG15, 0x61CF); /* CSP Program Memory, Byte 15 */ +SFRX(CSPPROG16, 0x61D0); /* CSP Program Memory, Byte 16 */ +SFRX(CSPPROG17, 0x61D1); /* CSP Program Memory, Byte 17 */ +SFRX(CSPPROG18, 0x61D2); /* CSP Program Memory, Byte 18 */ +SFRX(CSPPROG19, 0x61D3); /* CSP Program Memory, Byte 19 */ +SFRX(CSPPROG20, 0x61D4); /* CSP Program Memory, Byte 20 */ +SFRX(CSPPROG21, 0x61D5); /* CSP Program Memory, Byte 21 */ +SFRX(CSPPROG22, 0x61D6); /* CSP Program Memory, Byte 22 */ +SFRX(CSPPROG23, 0x61D7); /* CSP Program Memory, Byte 23 */ +SFRX(CSPCTRL, 0x61E0); /* CSP Control Bit */ +SFRX(CSPSTAT, 0x61E1); /* CSP Status Register */ +SFRX(CSPX, 0x61E2); /* CSP X Register */ +SFRX(CSPY, 0x61E3); /* CSP Y Register */ +SFRX(CSPZ, 0x61E4); /* CSP Z Register */ +SFRX(CSPT, 0x61E5); /* CSP T Register */ +/*--------------------------------------------------------------------------- + * cc2531 USB Registers + * (Sec. 21.12, page 196) + *---------------------------------------------------------------------------*/ +SFRX(USBADDR, 0x6200); /* Function Address */ +SFRX(USBPOW, 0x6201); /* Power/Control Register */ +SFRX(USBIIF, 0x6202); /* IN Endpoints and EP0 Interrupt Flags */ +SFRX(USBOIF, 0x6204); /* OUT-Endpoint Interrupt Flags */ +SFRX(USBCIF, 0x6206); /* Common USB Interrupt Flags */ +SFRX(USBIIE, 0x6207); /* IN Endpoints and EP0 Interrupt-Enable Mask */ +SFRX(USBOIE, 0x6209); /* Out Endpoints Interrupt Enable Mask */ +SFRX(USBCIE, 0x620B); /* Common USB Interrupt-Enable Mask */ +SFRX(USBFRML, 0x620C); /* Current Frame Number (Low Byte) */ +SFRX(USBFRMH, 0x620D); /* Current Frame Number (High Byte) */ +SFRX(USBINDEX, 0x620E); /* Current-Endpoint Index Register */ +SFRX(USBCTRL, 0x620F); /* USB Control Register */ +SFRX(USBMAXI, 0x6210); /* Max. Packet Size for IN Endpoint{1–5} */ +SFRX(USBCS0, 0x6211); /* EP0 Control and Status (USBINDEX = 0) */ +SFRX(USBCSIL, 0x6211); /* IN EP{1–5} Control and Status, Low */ +SFRX(USBCSIH, 0x6212); /* IN EP{1–5} Control and Status, High */ +SFRX(USBMAXO, 0x6213); /* Max. Packet Size for OUT EP{1–5} */ +SFRX(USBCSOL, 0x6214); /* OUT EP{1–5} Control and Status, Low */ +SFRX(USBCSOH, 0x6215); /* OUT EP{1–5} Control and Status, High */ +SFRX(USBCNT0, 0x6216); /* Number of Received Bytes in EP0 FIFO (USBINDEX = 0) */ +SFRX(USBCNTL, 0x6216); /* Number of Bytes in EP{1–5} OUT FIFO, Low */ +SFRX(USBCNTH, 0x6217); /* Number of Bytes in EP{1–5} OUT FIFO, High */ +SFRX(USBF0, 0x6220); /* Endpoint-0 FIFO */ +SFRX(USBF1, 0x6222); /* Endpoint-1 FIFO */ +SFRX(USBF2, 0x6224); /* Endpoint-2 FIFO */ +SFRX(USBF3, 0x6226); /* Endpoint-3 FIFO */ +SFRX(USBF4, 0x6228); /* Endpoint-4 FIFO */ +SFRX(USBF5, 0x622A); /* Endpoint-5 FIFO */ +/*--------------------------------------------------------------------------- + * SFR Access via XDATA (0x7080 - 0x70FF) + *---------------------------------------------------------------------------*/ +SFRX(X_P0, 0x7080); /* Port 0 - Read Only */ +SFRX(X_U0CSR, 0x7086); /* USART 0 control and status */ +SFRX(X_P0IFG, 0x7089); /* Port 0 interrupt status flag */ +SFRX(X_P1IFG, 0x708A); /* Port 1 interrupt status flag */ +SFRX(X_P2IFG, 0x708B); /* Port 2 interrupt status flag */ +SFRX(X_PICTL, 0x708C); /* Port pins interrupt mask and edge */ +SFRX(X_P1IEN, 0x708D); /* Port 1 interrupt mask */ +SFRX(X_P0INP, 0x708F); /* Port 0 input Mode */ +SFRX(X_P1, 0x7090); /* Port 1 - Read Only */ +SFRX(X_RFIRQF1, 0x7091); /* RF interrupt flags MSB */ +SFRX(X_MPAGE, 0x7093); /* Memory page select */ +SFRX(X__XPAGE, 0x7093); /* Memory page select - SDCC name */ +SFRX(X_T2CTRL, 0x7094); /* Timer 2 control */ +SFRX(X_ST0, 0x7095); /* Sleep Timer 0 */ +SFRX(X_ST1, 0x7096); /* Sleep Timer 1 */ +SFRX(X_ST2, 0x7097); /* Sleep Timer 2 */ +SFRX(X_T2EVTCFG, 0x709C); /* Timer 2 event configuration */ +SFRX(X_SLEEPSTA, 0x709D); /* Sleep-mode control status */ +SFRX(X_CLKCONSTA, 0x709E); /* Clock control status */ +SFRX(X_FMAP, 0x709F); /* Flash-memory bank mapping */ +SFRX(X_PSBANK, 0x709F); /* Flash-memory bank mapping - SDCC name */ +SFRX(X_P2, 0x70A0); /* Port 2 - Read Only */ +SFRX(X_T2IRQF, 0x70A1); /* Timer 2 interrupt flags */ +SFRX(X_T2M0, 0x70A2); /* Timer 2 multiplexed register 0 */ +SFRX(X_T2M1, 0x70A3); /* Timer 2 multiplexed register 1 */ +SFRX(X_T2MOVF0, 0x70A4); /* Timer 2 multiplexed overflow register 0 */ +SFRX(X_T2MOVF1, 0x70A5); /* Timer 2 multiplexed overflow register 1 */ +SFRX(X_T2MOVF2, 0x70A6); /* Timer 2 multiplexed overflow register 2 */ +SFRX(X_T2IRQM, 0x70A7); /* Timer 2 interrupt mask */ +SFRX(X_P0IEN, 0x70AB); /* Port 0 interrupt mask */ +SFRX(X_P2IEN, 0x70AC); /* Port 2 interrupt mask */ +SFRX(X_STLOAD, 0x70AD); /* Sleep-timer load status */ +SFRX(X_PMUX, 0x70AE); /* Power-down signal mux */ +SFRX(X_T1STAT, 0x70AF); /* Timer 1 status */ +SFRX(X_ENCDI, 0x70B1); /* Encryption/decryption input data */ +SFRX(X_ENCDO, 0x70B2); /* Encryption/decryption output data */ +SFRX(X_ENCCS, 0x70B3); /* Encryption/decryption control and status */ +SFRX(X_ADCCON1, 0x70B4); /* ADC control 1 */ +SFRX(X_ADCCON2, 0x70B5); /* ADC control 2 */ +SFRX(X_ADCCON3, 0x70B6); /* ADC control 3 */ +SFRX(X_ADCL, 0x70BA); /* ADC data low */ +SFRX(X_ADCH, 0x70BB); /* ADC data high */ +SFRX(X_RNDL, 0x70BC); /* Random number generator data low */ +SFRX(X_RNDH, 0x70BD); /* Random number generator data high */ +SFRX(X_SLEEPCMD, 0x70BE); /* Sleep-mode control command */ +SFRX(X_RFERRF, 0x70BF); /* RF error interrupt flags */ +SFRX(X_U0DBUF, 0x70C1); /* USART 0 receive/transmit data buffer */ +SFRX(X_U0BAUD, 0x70C2); /* USART 0 baud-rate control */ +SFRX(X_T2MSEL, 0x70C3); /* Timer 2 multiplex select */ +SFRX(X_U0UCR, 0x70C4); /* USART 0 UART control */ +SFRX(X_U0GCR, 0x70C5); /* USART 0 generic control */ +SFRX(X_CLKCONCMD, 0x70C6); /* Clock control command */ +SFRX(X_MEMCTR, 0x70C7); /* Memory system control */ +SFRX(X_WDCTL, 0x70C9); /* Watchdog Timer Control */ +SFRX(X_T3CNT, 0x70CA); /* Timer 3 counter */ +SFRX(X_T3CTL, 0x70CB); /* Timer 3 control */ +SFRX(X_T3CCTL0, 0x70CC); /* Timer 3 channel 0 compare control */ +SFRX(X_T3CC0, 0x70CD); /* Timer 3 channel 0 compare value */ +SFRX(X_T3CCTL1, 0x70CE); /* Timer 3 channel 1 compare control */ +SFRX(X_T3CC1, 0x70CF); /* Timer 3 channel 1 compare value */ +SFRX(X_DMAIRQ, 0x70D1); /* DMA interrupt flag */ +SFRX(X_DMA1CFGL, 0x70D2); /* DMA channel 1–4 configuration address low */ +SFRX(X_DMA1CFGH, 0x70D3); /* DMA channel 1–4 configuration address high */ +SFRX(X_DMA0CFGL, 0x70D4); /* DMA channel 0 configuration address low */ +SFRX(X_DMA0CFGH, 0x70D5); /* DMA channel 0 configuration address high */ +SFRX(X_DMAARM, 0x70D6); /* DMA channel armed */ +SFRX(X_DMAREQ, 0x70D7); /* DMA channel start request and status */ +SFRX(X_TIMIF, 0x70D8); /* Timers 1/3/4 joint interrupt mask/flags */ +SFRX(X_RFD, 0x70D9); /* RF data */ +SFRX(X_T1CC0L, 0x70DA); /* Timer 1 channel 0 capture/compare value low */ +SFRX(X_T1CC0H, 0x70DB); /* Timer 1 channel 0 capture/compare value high */ +SFRX(X_T1CC1L, 0x70DC); /* Timer 1 channel 1 capture/compare value low */ +SFRX(X_T1CC1H, 0x70DD); /* Timer 1 channel 1 capture/compare value high */ +SFRX(X_T1CC2L, 0x70DE); /* Timer 1 channel 2 capture/compare value low */ +SFRX(X_T1CC2H, 0x70DF); /* Timer 1 channel 2 capture/compare value high */ +SFRX(X_RFST, 0x70E1); /* RF command strobe */ +SFRX(X_T1CNTL, 0x70E2); /* Timer 1 counter low */ +SFRX(X_T1CNTH, 0x70E3); /* Timer 1 counter high */ +SFRX(X_T1CTL, 0x70E4); /* Timer 1 control and status */ +SFRX(X_T1CCTL0, 0x70E5); /* Timer 1 channel 0 capture/compare control */ +SFRX(X_T1CCTL1, 0x70E6); /* Timer 1 channel 1 capture/compare control */ +SFRX(X_T1CCTL2, 0x70E7); /* Timer 1 channel 2 capture/compare control */ +SFRX(X_RFIRQF0, 0x70E9); /* RF interrupt flags LSB */ +SFRX(X_T4CNT, 0x70EA); /* Timer 4 counter */ +SFRX(X_T4CTL, 0x70EB); /* Timer 4 control */ +SFRX(X_T4CCTL0, 0x70EC); /* Timer 4 channel 0 compare control */ +SFRX(X_T4CC0, 0x70ED); /* Timer 4 channel 0 compare value */ +SFRX(X_T4CCTL1, 0x70EE); /* Timer 4 channel 1 compare control */ +SFRX(X_T4CC1, 0x70EF); /* Timer 4 channel 1 compare value */ +SFRX(X_PERCFG, 0x70F1); /* Peripheral I/O control */ +SFRX(X_APCFG, 0x70F2); /* Analog peripheral I/O configuration */ +SFRX(X_P0SEL, 0x70F3); /* Port 0 function select */ +SFRX(X_P1SEL, 0x70F4); /* Port 1 function select */ +SFRX(X_P2SEL, 0x70F5); /* Port 2 function select */ +SFRX(X_P1INP, 0x70F6); /* Port 1 input mode */ +SFRX(X_P2INP, 0x70F7); /* Port 2 input mode */ +SFRX(X_U1CSR, 0x70F8); /* USART 1 control and status */ +SFRX(X_U1DBUF, 0x70F9); /* USART 1 receive/transmit data buffer */ +SFRX(X_U1BAUD, 0x70FA); /* USART 1 baud-rate control */ +SFRX(X_U1UCR, 0x70FB); /* USART 1 UART control */ +SFRX(X_U1GCR, 0x70FC); /* USART 1 Generic control */ +SFRX(X_P0DIR, 0x70FD); /* Port 0 direction */ +SFRX(X_P1DIR, 0x70FE); /* Port 1 direction */ +SFRX(X_P2DIR, 0x70FF); /* Port 2 direction */ +/*--------------------------------------------------------------------------- + * Information Page (Read Only) + *---------------------------------------------------------------------------*/ +SFRX(X_INFOPAGE, 0x7800); /* Start of Information Page */ +SFRX(X_IEEE_ADDR, 0x780C); /* Start of unique IEEE Address */ + +#endif /* __CC253X_H__ */ diff --git a/cpu/cc253x/dev/cc2530-rf.c b/cpu/cc253x/dev/cc2530-rf.c new file mode 100644 index 000000000..fc01d8a37 --- /dev/null +++ b/cpu/cc253x/dev/cc2530-rf.c @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Implementation of the cc2530 RF driver + * + * \author + * George Oikonomou - + */ +#include "contiki.h" +#include "dev/radio.h" +#include "dev/cc2530-rf.h" +#include "cc253x.h" +#include "sfr-bits.h" +#include "sys/clock.h" +#include "sys/rtimer.h" + +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/netstack.h" + +#include +/*---------------------------------------------------------------------------*/ +#define CHECKSUM_LEN 2 +/*---------------------------------------------------------------------------*/ +#if CC2530_RF_CONF_LEDS +#define CC2530_RF_LEDS CC2530_RF_CONF_LEDS +#else +#define CC2530_RF_LEDS 0 +#endif + +#if CC2530_RF_LEDS +#include "dev/leds.h" +#define RF_RX_LED_ON() leds_on(LEDS_RED); +#define RF_RX_LED_OFF() leds_off(LEDS_RED); +#define RF_TX_LED_ON() leds_on(LEDS_GREEN); +#define RF_TX_LED_OFF() leds_off(LEDS_GREEN); +#else +#define RF_RX_LED_ON() +#define RF_RX_LED_OFF() +#define RF_TX_LED_ON() +#define RF_TX_LED_OFF() +#endif +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#include "debug.h" +#define PUTSTRING(...) putstring(__VA_ARGS__) +#define PUTHEX(...) puthex(__VA_ARGS__) +#else +#define PUTSTRING(...) +#define PUTHEX(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Local RF Flags */ +#define RX_ACTIVE 0x80 +#define WAS_OFF 0x10 +#define RF_ON 0x01 + +/* Bit Masks for the last byte in the RX FIFO */ +#define CRC_BIT_MASK 0x80 +#define LQI_BIT_MASK 0x7F + +/* 192 ms, radio off -> on interval */ +#define ONOFF_TIME RTIMER_ARCH_SECOND / 3125 +/*---------------------------------------------------------------------------*/ +#if CC2530_RF_CONF_HEXDUMP +#include "uart0.h" +static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */ +#endif +/*---------------------------------------------------------------------------*/ +#ifdef CC2530_RF_CONF_AUTOACK +#define CC2530_RF_AUTOACK CC2530_RF_CONF_AUTOACK +#else +#define CC2530_RF_AUTOACK 1 +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t __data rf_flags; + +static int on(void); /* prepare() needs our prototype */ +static int off(void); /* transmit() needs our prototype */ +static int channel_clear(void); /* transmit() needs our prototype */ +/*---------------------------------------------------------------------------*/ +int8_t +cc2530_rf_channel_set(uint8_t channel) +{ + PUTSTRING("RF: Set Chan\n"); + + if((channel < CC2530_RF_CHANNEL_MIN) || (channel > CC2530_RF_CHANNEL_MAX)) { + return -1; + } + + /* Changes to FREQCTRL take effect after the next recalibration */ + off(); + FREQCTRL = (CC2530_RF_CHANNEL_MIN + + (channel - CC2530_RF_CHANNEL_MIN) * CC2530_RF_CHANNEL_SPACING); + on(); + + return (int8_t) channel; +} +/*---------------------------------------------------------------------------*/ +uint8_t +cc2530_rf_power_set(uint8_t new_power) +{ + PUTSTRING("RF: Set Power\n"); + /* off() */ + TXPOWER = new_power; + /* on() */ + + return TXPOWER; +} +/*---------------------------------------------------------------------------*/ +void +cc2530_rf_set_addr(uint16_t pan) +{ + PAN_ID0 = pan & 0xFF; + PAN_ID1 = pan >> 8; + + SHORT_ADDR0 = ((uint8_t *)&X_IEEE_ADDR)[0]; + SHORT_ADDR1 = ((uint8_t *)&X_IEEE_ADDR)[1]; + + memcpy(&EXT_ADDR0, &X_IEEE_ADDR, 8); +} +/*---------------------------------------------------------------------------*/ +/* Netstack API radio driver functions */ +/*---------------------------------------------------------------------------*/ +static int +init(void) +{ + PUTSTRING("RF: Init\n"); + + if(rf_flags & RF_ON) { + return 0; + } + +#ifdef CC2530_RF_LOW_POWER_RX + /* Reduce RX power consumption current to 20mA at the cost of sensitivity */ + RXCTRL = 0x00; + FSCTRL = 0x50; +#else + RXCTRL = 0x3F; + FSCTRL = 0x55; +#endif /* CC2530_RF_LOW_POWER_RX */ + + CCACTRL0 = CC2530_RF_CCA_THRES; + + /* + * According to the user guide, these registers must be updated from their + * defaults for optimal performance + * + * Table 23-6, Sec. 23.15.1, p. 259 + */ + TXFILTCFG = 0x09; /* TX anti-aliasing filter */ + AGCCTRL1 = 0x15; /* AGC target value */ + FSCAL1 = 0x00; /* Reduce the VCO leakage */ + + /* Auto ACKs and CRC calculation, default RX and TX modes with FIFOs */ + FRMCTRL0 = FRMCTRL0_AUTOCRC; +#if CC2530_RF_AUTOACK + FRMCTRL0 |= FRMCTRL0_AUTOACK; +#endif + + /* Disable source address matching and autopend */ + SRCMATCH = 0; /* investigate */ + + /* MAX FIFOP threshold */ + FIFOPCTRL = CC2530_RF_MAX_PACKET_LEN; + + cc2530_rf_power_set(CC2530_RF_TX_POWER); + cc2530_rf_channel_set(CC2530_RF_CHANNEL); + + RF_TX_LED_OFF(); + RF_RX_LED_OFF(); + + rf_flags |= RF_ON; + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +prepare(const void *payload, unsigned short payload_len) +{ + uint8_t i; + + PUTSTRING("RF: Prepare 0x"); + PUTHEX(payload_len + CHECKSUM_LEN); + PUTSTRING(" bytes\n"); + + /* + * When we transmit in very quick bursts, make sure previous transmission + * is not still in progress before re-writing to the TX FIFO + */ + while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE); + + if((rf_flags & RX_ACTIVE) == 0) { + on(); + } + + CC2530_CSP_ISFLUSHTX(); + + PUTSTRING("RF: data = "); + /* Send the phy length byte first */ + RFD = payload_len + CHECKSUM_LEN; /* Payload plus FCS */ + for(i = 0; i < payload_len; i++) { + RFD = ((unsigned char*) (payload))[i]; + PUTHEX(((unsigned char*)(payload))[i]); + } + PUTSTRING("\n"); + + /* Leave space for the FCS */ + RFD = 0; + RFD = 0; + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +transmit(unsigned short transmit_len) +{ + uint8_t counter; + int ret = RADIO_TX_ERR; + rtimer_clock_t t0; + transmit_len; /* hush the warning */ + + if(!(rf_flags & RX_ACTIVE)) { + t0 = RTIMER_NOW(); + on(); + rf_flags |= WAS_OFF; + while (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME)); + } + + if(channel_clear() == CC2530_RF_CCA_BUSY) { + RIMESTATS_ADD(contentiondrop); + return RADIO_TX_COLLISION; + } + + /* + * prepare() double checked that TX_ACTIVE is low. If SFD is high we are + * receiving. Abort transmission and bail out with RADIO_TX_COLLISION + */ + if(FSMSTAT1 & FSMSTAT1_SFD) { + RIMESTATS_ADD(contentiondrop); + return RADIO_TX_COLLISION; + } + + /* Start the transmission */ + RF_TX_LED_ON(); + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + CC2530_CSP_ISTXON(); + + counter = 0; + while(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE) && (counter++ < 3)) { + clock_delay(10); + } + + if(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE)) { + PUTSTRING("RF: TX never active.\n"); + CC2530_CSP_ISFLUSHTX(); + ret = RADIO_TX_ERR; + } else { + /* Wait for the transmission to finish */ + while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE); + ret = RADIO_TX_OK; + } + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + if(rf_flags & WAS_OFF){ + off(); + } + + RIMESTATS_ADD(lltx); + + RF_TX_LED_OFF(); + + /* OK, sent. We are now ready to send more */ + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +send(void *payload, unsigned short payload_len) +{ + prepare(payload, payload_len); + return transmit(payload_len); +} +/*---------------------------------------------------------------------------*/ +static int +read(void *buf, unsigned short bufsize) +{ + uint8_t i; + uint8_t len; + uint8_t crc_corr; + int8_t rssi; + + PUTSTRING("RF: Read\n"); + + /* Check the length */ + len = RFD; + + /* Check for validity */ + if(len > CC2530_RF_MAX_PACKET_LEN) { + /* Oops, we must be out of sync. */ + PUTSTRING("RF: bad sync\n"); + + RIMESTATS_ADD(badsynch); + CC2530_CSP_ISFLUSHRX(); + return 0; + } + + if(len <= CC2530_RF_MIN_PACKET_LEN) { + PUTSTRING("RF: too short\n"); + + RIMESTATS_ADD(tooshort); + CC2530_CSP_ISFLUSHRX(); + return 0; + } + + if(len - CHECKSUM_LEN > bufsize) { + PUTSTRING("RF: too long\n"); + + RIMESTATS_ADD(toolong); + CC2530_CSP_ISFLUSHRX(); + return 0; + } + +#if CC2530_RF_CONF_HEXDUMP + /* If we reach here, chances are the FIFO is holding a valid frame */ + uart0_writeb(magic[0]); + uart0_writeb(magic[1]); + uart0_writeb(magic[2]); + uart0_writeb(magic[3]); + uart0_writeb(len); +#endif + + RF_RX_LED_ON(); + + PUTSTRING("RF: read (0x"); + PUTHEX(len); + PUTSTRING(" bytes) = "); + len -= CHECKSUM_LEN; + for(i = 0; i < len; ++i) { + ((unsigned char*)(buf))[i] = RFD; +#if CC2530_RF_CONF_HEXDUMP + uart0_writeb(((unsigned char*)(buf))[i]); +#endif + PUTHEX(((unsigned char*)(buf))[i]); + } + PUTSTRING("\n"); + + /* Read the RSSI and CRC/Corr bytes */ + rssi = ((int8_t) RFD) - 45; + crc_corr = RFD; + +#if CC2530_RF_CONF_HEXDUMP + uart0_writeb(rssi); + uart0_writeb(crc_corr); +#endif + + /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */ + if(crc_corr & CRC_BIT_MASK) { + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK); + RIMESTATS_ADD(llrx); + } else { + RIMESTATS_ADD(badcrc); + CC2530_CSP_ISFLUSHRX(); + RF_RX_LED_OFF(); + return 0; + } + + /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */ + if((FSMSTAT1 & (FSMSTAT1_FIFO | FSMSTAT1_FIFOP)) == FSMSTAT1_FIFOP) { + /* + * If we reach here means that there might be more intact packets in the + * FIFO despite the overflow. This can happen with bursts of small packets. + * + * Only flush if the FIFO is actually empty. If not, then next pass we will + * pick up one more packet or flush due to an error. + */ + if(!RXFIFOCNT) { + CC2530_CSP_ISFLUSHRX(); + } + } + + RF_RX_LED_OFF(); + + return (len); +} +/*---------------------------------------------------------------------------*/ +static int +channel_clear(void) +{ + if(FSMSTAT1 & FSMSTAT1_CCA) { + return CC2530_RF_CCA_CLEAR; + } + return CC2530_RF_CCA_BUSY; +} +/*---------------------------------------------------------------------------*/ +static int +receiving_packet(void) +{ + PUTSTRING("RF: Receiving\n"); + + /* + * SFD high while transmitting and receiving. + * TX_ACTIVE high only when transmitting + * + * FSMSTAT1 & (TX_ACTIVE | SFD) == SFD <=> receiving + */ + return (FSMSTAT1 & (FSMSTAT1_TX_ACTIVE | FSMSTAT1_SFD) == FSMSTAT1_SFD); +} +/*---------------------------------------------------------------------------*/ +static int +pending_packet(void) +{ + return (FSMSTAT1 & FSMSTAT1_FIFOP); +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + if(!(rf_flags & RX_ACTIVE)) { + CC2530_CSP_ISFLUSHRX(); + CC2530_CSP_ISRXON(); + + rf_flags |= RX_ACTIVE; + } + + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(void) +{ + CC2530_CSP_ISRFOFF(); + CC2530_CSP_ISFLUSHRX(); + + rf_flags = 0; + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + return 1; +} +/*---------------------------------------------------------------------------*/ +const struct radio_driver cc2530_rf_driver = +{ + init, + prepare, + transmit, + send, + read, + channel_clear, + receiving_packet, + pending_packet, + on, + off, +}; +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc253x/dev/cc2530-rf.h b/cpu/cc253x/dev/cc2530-rf.h new file mode 100644 index 000000000..397b952a3 --- /dev/null +++ b/cpu/cc253x/dev/cc2530-rf.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Implementation of the cc2530 RF driver + * + * \author + * George Oikonomou - + */ +#ifndef __CC2530_RF_H__ +#define __CC2530_RF_H__ + +#include "contiki.h" +#include "dev/radio.h" +#include "cc253x.h" +/*--------------------------------------------------------------------------- + * RF Config + *---------------------------------------------------------------------------*/ +#define CC2530_RF_TX_POWER_RECOMMENDED 0xD5 +#ifdef CC2530_RF_CONF_TX_POWER +#define CC2530_RF_TX_POWER CC2530_RF_CONF_TX_POWER +#else +#define CC2530_RF_TX_POWER CC2530_RF_TX_POWER_RECOMMENDED +#endif /* CC2530_RF_CONF_TX_POWER */ + +#ifdef CC2530_RF_CONF_CCA_THRES +#define CC2530_RF_CCA_THRES CC2530_RF_CONF_CCA_THRES +#else +#define CC2530_RF_CCA_THRES CCA_THRES_USER_GUIDE /* User guide recommendation */ +#endif /* CC2530_RF_CONF_CCA_THRES */ + +#ifdef CC2530_RF_CONF_CHANNEL +#define CC2530_RF_CHANNEL CC2530_RF_CONF_CHANNEL +#else +#define CC2530_RF_CHANNEL 18 +#endif /* CC2530_RF_CONF_CHANNEL */ +#define CC2530_RF_CHANNEL_MIN 11 +#define CC2530_RF_CHANNEL_MAX 26 +#define CC2530_RF_CHANNEL_SPACING 5 + +#ifdef CC2530_RF_CONF_AUTOACK +#define CC2530_RF_AUTOACK CC2530_RF_CONF_AUTOACK +#else +#define CC2530_RF_AUTOACK 1 +#endif /* CC2530_RF_CONF_AUTOACK */ + +#ifdef CC2530_RF_CONF_LOW_POWER_RX +#define CC2530_RF_LOW_POWER_RX CC2530_RF_CONF_LOW_POWER_RX +#else +#define CC2530_RF_LOW_POWER_RX 0 +#endif /* CC2530_RF_CONF_LOW_POWER_RX */ +/*---------------------------------------------------------------------------*/ +#define CCA_THRES_USER_GUIDE 0xF8 +#define CCA_THRES_ALONE 0xFC /* -4-76=-80dBm when CC2530 operated alone or with CC2591 in LGM */ +#define CCA_THR_HGM 0x06 /* 6-76=-70dBm when CC2530 operated with CC2591 in HGM */ +#define CORR_THR 0x14 +/*---------------------------------------------------------------------------*/ +#define CC2530_RF_MAX_PACKET_LEN 127 +#define CC2530_RF_MIN_PACKET_LEN 4 +/*---------------------------------------------------------------------------*/ +#define CC2530_RF_CCA_CLEAR 1 +#define CC2530_RF_CCA_BUSY 0 + +/* Wait for RSSI to be valid. */ +#define CC2530_RF_CCA_VALID_WAIT() while(!(RSSISTAT & RSSIST)) +/*--------------------------------------------------------------------------- + * Command Strobe Processor + *---------------------------------------------------------------------------*/ +/* OPCODES */ +#define CSP_OP_ISRXON 0xE3 +#define CSP_OP_ISTXON 0xE9 +#define CSP_OP_ISTXONCCA 0xEA +#define CSP_OP_ISRFOFF 0xEF +#define CSP_OP_ISFLUSHRX 0xED +#define CSP_OP_ISFLUSHTX 0xEE + +#define CC2530_CSP_ISRXON() do { RFST = CSP_OP_ISRXON; } while(0) +#define CC2530_CSP_ISTXON() do { RFST = CSP_OP_ISTXON; } while(0) +#define CC2530_CSP_ISTXONCCA() do { RFST = CSP_OP_ISTXONCCA; } while(0) +#define CC2530_CSP_ISRFOFF() do { RFST = CSP_OP_ISRFOFF; } while(0) + +/* OP x 2 for flushes */ +#define CC2530_CSP_ISFLUSHRX() do { \ + RFST = CSP_OP_ISFLUSHRX; \ + RFST = CSP_OP_ISFLUSHRX; \ +} while(0) +#define CC2530_CSP_ISFLUSHTX() do { \ + RFST = CSP_OP_ISFLUSHTX; \ + RFST = CSP_OP_ISFLUSHTX; \ +} while(0) +/*---------------------------------------------------------------------------*/ +extern const struct radio_driver cc2530_rf_driver; +/*---------------------------------------------------------------------------*/ +int8_t cc2530_rf_channel_set(uint8_t channel); +uint8_t cc2530_rf_power_set(uint8_t new_power); +void cc2530_rf_set_addr(uint16_t pan); +/*---------------------------------------------------------------------------*/ +#endif /* __CC2530_RF_H__ */ diff --git a/cpu/cc253x/dev/clock-isr.h b/cpu/cc253x/dev/clock-isr.h new file mode 100644 index 000000000..005ac38c6 --- /dev/null +++ b/cpu/cc253x/dev/clock-isr.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Declaration of the Sleep timer ISR, used by the clock module + * \author + * George Oikonomou - + */ +#ifndef __CLOCK_ISR_H__ +#define __CLOCK_ISR_H__ + +#include "contiki-conf.h" +#include "cc253x.h" + +void clock_isr(void) __interrupt(ST_VECTOR); + +#endif /* __CLOCK_ISR_H__ */ diff --git a/cpu/cc253x/dev/clock.c b/cpu/cc253x/dev/clock.c new file mode 100644 index 000000000..6d9a5fdc1 --- /dev/null +++ b/cpu/cc253x/dev/clock.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2009, 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: clock.c,v 1.1 2009/09/08 20:07:35 zdshelby Exp $ + */ + +/** + * \file + * Implementation of the clock functions for the 8051 CPU + * \author + * Zach Shelby (zach@sensinode.com) - original + * George Oikonomou - - cc2530 port + */ +#include "sfr-bits.h" +#include "sys/clock.h" +#include "sys/etimer.h" +#include "cc253x.h" +#include "sys/energest.h" + +/* Sleep timer runs on the 32k RC osc. */ +/* One clock tick is 7.8 ms */ +#define TICK_VAL (32768/128) /* 256 */ + +#define MAX_TICKS (~((clock_time_t)0) / 2) +/*---------------------------------------------------------------------------*/ +/* Do NOT remove the absolute address and do NOT remove the initialiser here */ +__xdata __at(0x0000) static unsigned long timer_value = 0; + +static volatile __data clock_time_t count = 0; /* Uptime in ticks */ +static volatile __data clock_time_t seconds = 0; /* Uptime in secs */ +/*---------------------------------------------------------------------------*/ +/** + * One delay is about 0.6 us, so this function delays for len * 0.6 us + */ +void +clock_delay(unsigned int len) +{ + unsigned int i; + for(i = 0; i< len; i++) { + ASM(nop); + } +} +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of ~8 ms (a tick) + */ +void +clock_wait(int i) +{ + clock_time_t start; + + start = clock_time(); + while(clock_time() - start < (clock_time_t)i); +} +/*---------------------------------------------------------------------------*/ +CCIF clock_time_t +clock_time(void) +{ + return count; +} +/*---------------------------------------------------------------------------*/ +CCIF unsigned long +clock_seconds(void) +{ + return seconds; +} +/*---------------------------------------------------------------------------*/ +/* + * There is some ambiguity between TI cc2530 software examples and information + * in the datasheet. + * + * TI examples appear to be writing to SLEEPCMD, initialising hardware in a + * fashion semi-similar to cc2430 + * + * However, the datasheet claims that those bits in SLEEPCMD are reserved + * + * The code here goes by the datasheet (ignore TI examples) and seems to work. + */ +void +clock_init(void) +{ + /* Make sure we know where we stand */ + CLKCONCMD = CLKCONCMD_OSC32K | CLKCONCMD_OSC; + + /* Stay with 32 KHz RC OSC, Chance System Clock to 32 MHz */ + CLKCONCMD &= ~CLKCONCMD_OSC; + while(CLKCONSTA & CLKCONCMD_OSC); + + /* Tickspeed 500 kHz for timers[1-4] */ + CLKCONCMD |= CLKCONCMD_TICKSPD2 | CLKCONCMD_TICKSPD1; + while(CLKCONSTA != CLKCONCMD); + + /*Initialize tick value*/ + timer_value = ST0; + timer_value += ((unsigned long int) ST1) << 8; + timer_value += ((unsigned long int) ST2) << 16; + timer_value += TICK_VAL; + ST2 = (unsigned char) (timer_value >> 16); + ST1 = (unsigned char) (timer_value >> 8); + ST0 = (unsigned char) timer_value; + + STIE = 1; /* IEN0.STIE interrupt enable */ +} +/*---------------------------------------------------------------------------*/ +void +clock_isr(void) __interrupt(ST_VECTOR) +{ + DISABLE_INTERRUPTS(); + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + /* + * If the Sleep timer throws an interrupt while we are powering down to + * PM1, we need to abort the power down. Clear SLEEP.MODE, this will signal + * main() to abort the PM1 transition + * + * On cc2430 this would be: + * SLEEPCMD &= 0xFC; + */ + + /* + * Read value of the ST0:ST1:ST2, add TICK_VAL and write it back. + * Next interrupt occurs after the current time + TICK_VAL + */ + timer_value = ST0; + timer_value += ((unsigned long int) ST1) << 8; + timer_value += ((unsigned long int) ST2) << 16; + timer_value += TICK_VAL; + ST2 = (unsigned char) (timer_value >> 16); + ST1 = (unsigned char) (timer_value >> 8); + ST0 = (unsigned char) timer_value; + + ++count; + + /* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure + that the modulo operation below becomes a logical and and not + an expensive divide. Algorithm from Wikipedia: + http://en.wikipedia.org/wiki/Power_of_two */ +#if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0 +#error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...). +#error Change CLOCK_CONF_SECOND in contiki-conf.h. +#endif + if(count % CLOCK_CONF_SECOND == 0) { + ++seconds; + } + + if(etimer_pending() + && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { + etimer_request_poll(); + } + + STIF = 0; /* IRCON.STIF */ + ENERGEST_OFF(ENERGEST_TYPE_IRQ); + ENABLE_INTERRUPTS(); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc253x/dev/dma.c b/cpu/cc253x/dev/dma.c new file mode 100644 index 000000000..992c3dd57 --- /dev/null +++ b/cpu/cc253x/dev/dma.c @@ -0,0 +1,69 @@ +/** + * \file + * Driver for the cc2430 DMA controller. Can be assigned to any bank + * + * \author + * Original: Martti Huttunen + * Port: Zach Shelby + * Further Modifications: + * George Oikonomou + * + */ + +#include "contiki.h" +#include "dev/dma.h" +#include "cc253x.h" + +#if DMA_ON +struct dma_config dma_conf[DMA_CHANNEL_COUNT]; /* DMA Descriptors */ +struct process * dma_callback[DMA_CHANNEL_COUNT]; +/*---------------------------------------------------------------------------*/ +void +dma_init(void) +{ + uint16_t tmp_ptr; + + memset(dma_conf, 0, 4 * sizeof(dma_config_t)); + + for(tmp_ptr = 0; tmp_ptr < DMA_CHANNEL_COUNT; tmp_ptr++) { + dma_callback[tmp_ptr] = 0; + } + + /* The address of the descriptor for Channel 0 is configured separately */ + tmp_ptr = (uint16_t) &(dma_conf[0]); + DMA0CFGH = tmp_ptr >> 8; + DMA0CFGL = tmp_ptr; + + /* + * Descriptors for Channels 1-4 must be consecutive in RAM. + * We write the address of the 1st one to the register and the rest are + * derived by the SoC + */ +#if (DMA_CHANNEL_COUNT > 1) + tmp_ptr = (uint16_t) &(dma_conf[1]); + DMA1CFGH = tmp_ptr >> 8; + DMA1CFGL = tmp_ptr; +#endif + + IEN1_DMAIE = 1; /* Enable DMA interrupts */ +} +/*---------------------------------------------------------------------------*/ +/* + * Associate process p with DMA channel c. When a transfer on that channel + * completes, the ISR will poll this process. + */ +void +dma_associate_process(struct process * p, uint8_t c) +{ + if((!c) || (c >= DMA_CHANNEL_COUNT)) { + return; + } + + if(p) { + dma_conf[c].inc_prio |= 8; /* Enable interrupt generation */ + IEN1_DMAIE = 1; /* Make sure DMA interrupts are acknowledged */ + } + dma_callback[c] = p; +} +/*---------------------------------------------------------------------------*/ +#endif diff --git a/cpu/cc253x/dev/dma.h b/cpu/cc253x/dev/dma.h new file mode 100644 index 000000000..83e283a7a --- /dev/null +++ b/cpu/cc253x/dev/dma.h @@ -0,0 +1,148 @@ +/** + * \file + * Header file for the cc2430 DMA controller + * + * \author + * Original: Martti Huttunen + * Port: Zach Shelby + * Further Modifications: + * George Oikonomou + */ + +#ifndef __DMA_H +#define __DMA_H +#include "cc253x.h" + +/* DMA triggers */ +#define DMA_T_NONE 0 /* None, DMAREQ.DMAREQx bits start transfer */ +#define DMA_T_PREV 1 /* completion of previous channel */ +#define DMA_T_T1_CH0 2 /* Timer 1, compare, channel 0 */ +#define DMA_T_T1_CH1 3 /* Timer 1, compare, channel 1 */ +#define DMA_T_T1_CH2 4 /* Timer 1, compare, channel 2 */ +#define DMA_T_T2_COMP 5 /* Timer 2, compare */ +#define DMA_T_T2_OVFL 6 /* Timer 2, overflow */ +#define DMA_T_T3_CH0 7 /* Timer 3, compare, channel 0 */ +#define DMA_T_T3_CH1 8 /* Timer 3, compare, channel 1 */ +#define DMA_T_T4_CH0 9 /* Timer 4, compare, channel 0 */ +#define DMA_T_T4_CH1 10 /* Timer 4, compare, channel 1 */ +#define DMA_T_ST 11 /* Sleep Timer compare */ +#define DMA_T_IOC_0 12 /* Port 0 I/O pin input transition */ +#define DMA_T_IOC_1 13 /* Port 1 I/O pin input transition */ +#define DMA_T_URX0 14 /* USART0 RX complete */ +#define DMA_T_UTX0 15 /* USART0 TX complete */ +#define DMA_T_URX1 16 /* USART1 RX complete */ +#define DMA_T_UTX1 17 /* USART1 TX complete */ +#define DMA_T_FLASH 18 /* Flash data write complete */ +#define DMA_T_RADIO 19 /* RF packet byte received/transmit */ +#define DMA_T_ADC_CHALL 20 /* ADC end of a conversion in a sequence */ +#define DMA_T_ADC_CH11 21 /* ADC end of conversion channel 0 in sequence */ +#define DMA_T_ADC_CH21 22 /* ADC end of conversion channel 1 in sequence */ +#define DMA_T_ADC_CH32 23 /* ADC end of conversion channel 2 in sequence */ +#define DMA_T_ADC_CH42 24 /* ADC end of conversion channel 3 in sequence */ +#define DMA_T_ADC_CH53 25 /* ADC end of conversion channel 4 in sequence */ +#define DMA_T_ADC_CH63 26 /* ADC end of conversion channel 5 in sequence */ +#define DMA_T_ADC_CH74 27 /* ADC end of conversion channel 6 in sequence */ +#define DMA_T_ADC_CH84 28 /* ADC end of conversion channel 7 in sequence */ +#define DMA_T_ENC_DW 29 /* AES processor requests download input data */ +#define DMA_T_ENC_UP 30 /* AES processor requests upload output data */ + +/* variable DMA length modes (VLEN) */ +#define DMA_VLEN_LEN (0 << 5) /* Use LEN for transfer count*/ +/* + * Transfer the number of bytes/words specified by first byte/word + 1 + * (up to a maximum specified by LEN). + * Thus transfer count excludes length byte/word. + */ +#define DMA_VLEN_N1 (1 << 5) + /* + * Transfer the number of bytes/words specified by first byte/word + * (up to a maximum specified by LEN). + * Thus transfer count includes length byte/word. + */ +#define DMA_VLEN_N (2 << 5) + /* + * Transfer the number of bytes/words specified by first byte/word + 2 + * (up to a maximum specified by LEN). + */ +#define DMA_VLEN_N2 (3 << 5) + /* + * Transfer the number of bytes/words specified by first byte/word + 3 + * (up to a maximum specified by LEN). + */ +#define DMA_VLEN_N3 (4 << 5) +#define DMA_VLEN_RES1 (5 << 5) /* reserved */ +#define DMA_VLEN_RES2 (6 << 5) /* reserved */ +#define DMA_VLEN_LEN2 (7 << 5) /* Use LEN for transfer count */ + +/* Transfer Types (Byte 6 [6:5]) */ +#define DMA_SINGLE 0x00 /* Single */ +#define DMA_BLOCK 0x20 /* Block */ +#define DMA_RPT_SINGLE 0x40 /* Repeated single */ +#define DMA_RPT_BLOCK 0x60 /* Repeated block */ + +/* Source Increment Modes (Byte 7 [7:6])*/ +#define DMA_SRC_INC_NO 0x00 /* Source No increment */ +#define DMA_SRC_INC_1 0x40 /* Source Increment 1 */ +#define DMA_SRC_INC_2 0x80 /* Source Increment 2 */ +#define DMA_SRC_DEC 0xC0 /* Source Decrement 1 */ +/* Source Increment Modes (Byte 7 [5:4])*/ +#define DMA_DST_INC_NO 0x00 /* DestinationNo increment */ +#define DMA_DST_INC_1 0x10 /* Destination Increment 1 */ +#define DMA_DST_INC_2 0x20 /* Destination Increment 2 */ +#define DMA_DST_DEC 0x30 /* Destination Decrement 1 */ + +/* Descriptor Byte 7, Bits[3:0] */ +#define DMA_IRQ_MASK_ENABLE 0x08 +#define DMA_MODE_7_BIT 0x04 +#define DMA_PRIO_HIGHEST 0x03 +#define DMA_PRIO_HIGH 0x02 +#define DMA_PRIO_GUARANTEED 0x01 +#define DMA_PRIO_LOW 0x00 + +/** DMA configuration structure */ +typedef struct dma_config { + uint8_t src_h; /* source address high byte*/ + uint8_t src_l; /* source address low byte*/ + uint8_t dst_h; /* dest. address high byte*/ + uint8_t dst_l; /* dest. address low byte*/ + uint8_t len_h; /* [7:5] VLEN, [4:0] length high byte, 5 lowest bits*/ + uint8_t len_l; /* length low byte*/ + uint8_t wtt; /* 7: wordsize, [6:5] transfer mode, [4:0] trigger */ + /* [7:6] src inc, [5:4] dst_inc, 3: IRQ, 2: M8(vlen), [1-0] prio */ + uint8_t inc_prio; +} dma_config_t; + +#ifdef DMA_CONF_ON +#define DMA_ON DMA_CONF_ON +#else +#define DMA_ON 0 +#endif + +/* Number of DMA Channels and their Descriptors */ +#if DMA_ON +#define DMA_CHANNEL_COUNT 2 +extern dma_config_t dma_conf[DMA_CHANNEL_COUNT]; +#endif + +/* DMA-Related Macros */ +#define DMA_ARM(c) (DMAARM |= (1 << c)) /* Arm DMA Channel C */ +#define DMA_TRIGGER(c) (DMAREQ |= (1 << c)) /* Trigger DMA Channel C */ +/* + * Check Channel C for Transfer Status + * 1: Complete, Pending Interrupt, 0: Incomplete + */ +#define DMA_STATUS(c) (DMAIRQ &(1 << c)) +/* Abort Ongoing DMA Transfers on Channel C */ +#define DMA_ABORT(c) (DMAARM = ABORT | (1 << c)) +#define DMA_ABORT_ALL() (DMAARM = 0x9F) /* Abort ALL Ongoing DMA Transfers */ + +/* Functions Declarations */ +void dma_init(void); +void dma_associate_process (struct process * p, uint8_t c); + +/* Only link the ISR when DMA_ON is .... on */ +#if DMA_ON +void dma_isr( void ) __interrupt (DMA_VECTOR); +#endif + +#endif /*__DMA_H*/ diff --git a/cpu/cc253x/dev/dma_intr.c b/cpu/cc253x/dev/dma_intr.c new file mode 100644 index 000000000..9f2336293 --- /dev/null +++ b/cpu/cc253x/dev/dma_intr.c @@ -0,0 +1,68 @@ +/** + * \file + * DMA driver ISRs + * \author + * Original: Martti Huttunen + * Port: Zach Shelby + * + * DMA interrupt routines, must be stored in HOME bank + */ + +#include + +#include "contiki.h" + +#include "dev/dma.h" +#include "cc253x.h" + +#if DMA_ON +extern struct process * dma_callback[DMA_CHANNEL_COUNT]; +#endif + +/*---------------------------------------------------------------------------*/ +#ifdef HAVE_RF_DMA +extern void rf_dma_callback_isr(void); +#endif +#ifdef SPI_DMA_RX +extern void spi_rx_dma_callback(void); +#endif +/*---------------------------------------------------------------------------*/ +/** + * DMA interrupt service routine. + * + * if callback defined a poll is made to that process + */ +void +dma_isr(void) __interrupt (DMA_VECTOR) +{ +#if DMA_ON + uint8_t i; +#endif + EA=0; + DMAIF = 0; +#ifdef HAVE_RF_DMA + if((DMAIRQ & 1) != 0) { + DMAIRQ &= ~1; + DMAARM=0x81; + rf_dma_callback_isr(); + } +#endif +#ifdef SPI_DMA_RX + if((DMAIRQ & 0x08) != 0) { + DMAIRQ &= ~(1 << 3); + spi_rx_dma_callback(); + } +#endif +#if DMA_ON + for(i = 0; i < DMA_CHANNEL_COUNT; i++) { + if((DMAIRQ & (1 << i)) != 0) { + DMAIRQ &= ~(1 << i); + if(dma_callback[i] != 0) { + process_poll(dma_callback[i]); + } + } + } +#endif + EA = 1; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc253x/dev/lpm.h b/cpu/cc253x/dev/lpm.h new file mode 100644 index 000000000..4a8f14710 --- /dev/null +++ b/cpu/cc253x/dev/lpm.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Header file for the cc2430 Low Power Modes (LPM) + * We currently support the following: + * - Set MCU IDLE while in PM0. This is working as intended + * - Drop to PM1. This results in incoming radio packet losses. + * + * \author + * George Oikonomou - + */ +#ifndef __LPM_H__ +#define __LPM_H__ + +#include "contiki-conf.h" + +#define LPM_MODE_NONE 0 /* No LPM - Always on */ +#define LPM_MODE_IDLE 1 /* Set MCU Idle as part of the main loop */ +#define LPM_MODE_PM2 2 /* Drop to PM1 - causes radio packet losses for now */ + +#ifdef LPM_CONF_MODE +#define LPM_MODE LPM_CONF_MODE +#else +#define LPM_MODE LPM_MODE_IDLE +#endif /* LPM_CONF_MODE */ + +#endif /* __LPM_H__ */ diff --git a/cpu/cc253x/dev/port.h b/cpu/cc253x/dev/port.h new file mode 100644 index 000000000..6fc69d10c --- /dev/null +++ b/cpu/cc253x/dev/port.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * + * \author + * George Oikonomou - + */ + + +#ifndef PORT_H_ +#define PORT_H_ + +#include "cc253x.h" +#include "sfr-bits.h" +/*---------------------------------------------------------------------------*/ +/* Use these to configure your platform's hardware */ +#define PORT_FUNC_GPIO(port,pin) PORT_FUNC_GPIO_X(port,pin) +#define PORT_FUNC_PER(port,pin) PORT_FUNC_PER_X(port,pin) +#define PORT0_ANALOG_IO(pin) PORT0_ANALOG_IO_X(pin) +#define PORT0_DIGITAL_IO(pin) PORT0_DIGITAL_IO_X(pin) +#define PORT_SET(port,pin) PORT_SET_X(port,pin) +#define PORT_CLEAR(port,pin) PORT_CLEAR_X(port,pin) PORT_CLEAR_X(port,pin) +#define PORT_TOGGLE(port,pin) PORT_TOGGLE_X(port,pin) PORT_TOGGLE_X(port,pin) +#define PORT_READ(port,pin) PORT_READ_X(port,pin) +#define PORT_WRITE(port,pin,v) PORT_WRITE_X(port,pin,v) +#define PORT_DIR_OUTPUT(port,pin) PORT_DIR_OUTPUT_X(port,pin) +#define PORT_DIR_INPUT(port,pin) PORT_DIR_INPUT_X(port,pin) +#define PORT_IRQ_ENABLE(port,pin) PORT_IRQ_ENABLE_X(port,pin) +#define PORT_IRQ_DISABLE(port,pin) PORT_IRQ_DISABLE_X(port,pin) +#define PORT_IRQ_ENABLED(port,pin) PORT_IRQ_ENABLED_X(port,pin) +#define PORT_IRQ_CHECK(port,pin) PORT_IRQ_CHECK_X(port,pin) +#define PORT_IRQ_EDGE_FALL(port,pin) PORT_IRQ_EDGE_FALL_X(port,pin) +#define PORT_IRQ_EDGE_RISE(port,pin) PORT_IRQ_EDGE_RISE_X(port,pin) +#define PORT_IRQ_FLAG_OFF(port,pin) PORT_IRQ_FLAG_OFF_X(port,pin) +/*---------------------------------------------------------------------------*/ +/* Second Round of Macro Substitutions. Normally, you can stop reading here */ +/*---------------------------------------------------------------------------*/ +#define PORT_FUNC_GPIO_X(port,pin) do { P##port##SEL &= ~(1 << pin); } while(0) +#define PORT_FUNC_PER_X(port,pin) do { P##port##SEL |= 1 << pin; } while(0) +#define PORT0_ANALOG_IO_X(port,pin) do { APCFG |= 1 << pin; } while(0) +#define PORT0_DIGITAL_IO_X(port,pin) do { APCFG &= ~(1 << pin); } while(0) +#define PORT_SET_X(port,pin) do { P##port##_##pin = 1; } while(0) +#define PORT_CLEAR_X(port,pin) do { P##port##_##pin = 0; } while(0) +#define PORT_TOGGLE_X(port,pin) do { P##port##_##pin ^= 1; } while(0) +#define PORT_READ_X(port,pin) (P##port##_##pin) +#define PORT_WRITE_X(port,pin,v) do { P##port##_##pin = v;} while(0) +#define PORT_DIR_OUTPUT_X(port,pin) do { P##port##DIR |= 1 << pin; } while(0) +#define PORT_DIR_INPUT_X(port,pin) do { P##port##DIR &= ~(1 << pin); } while(0) +#define PORT_IRQ_ENABLE_X(port,pin) do { \ + P##port##IEN |= 1 << pin; \ + PORT##port##_IRQ_ENABLE(); \ +} while(0) +#define PORT_IRQ_DISABLE_X(port,pin) do { \ + P##port##IEN &= ~(1 << pin); \ + PORT##port##_IRQ_DISABLE(); \ +} while(0) +#define PORT_IRQ_ENABLED_X(port,pin) (P##port##IEN & (1 << pin)) +#define PORT_IRQ_CHECK_X(port,pin) (P##port##IFG & (1 << pin)) +#define PORT_IRQ_EDGE_FALL_X(port,pin) PORT##port##_IRQ_EDGE_FALL(pin) +#define PORT_IRQ_EDGE_RISE_X(port,pin) PORT##port##_IRQ_EDGE_RISE(pin) +#define PORT_IRQ_FLAG_OFF_X(port,pin) do { \ + P##port##IFG &= ~(1 << pin); \ + P##port##IF = 0; \ +} while(0) +/*---------------------------------------------------------------------------*/ +/* To handle SFR diversities + * - P0IE is in IEN1, which is bit-addressable, + * P1IE and P2IE are in IEN2, which is not bit-addressable + * - Edge detection (rising / falling) config is uniform for all pins in + * P0 and P2. For P1, low and high nibble bits are configured separately + * - Pullup/Pulldown/Tristate is quite different for each port + * + * You won't have to invoke these macros directly + */ +#define PORT0_IRQ_ENABLE() do { P0IE = 1; } while(0) +#define PORT0_IRQ_DISABLE() do { P0IE = 0; } while(0) +#define PORT1_IRQ_ENABLE() PORT_IRQ_EN_X(1) +#define PORT1_IRQ_DISABLE() PORT_IRQ_DIS_X(1) +#define PORT2_IRQ_ENABLE() PORT_IRQ_EN_X(2) +#define PORT2_IRQ_DISABLE() PORT_IRQ_DIS_X(2) + +#define PORT_IRQ_EN_X(port) do { IEN2 |= IEN2_P##port##IE; } while(0) +#define PORT_IRQ_DIS_X(port) do { IEN2 &= ~IEN2_P##port##IE; } while(0) +/*---------------------------------------------------------------------------*/ +#define PORT0_IRQ_EDGE_FALL(pin) PORT_IRQ_EDGE_F_X(0) +#define PORT0_IRQ_EDGE_RISE(pin) PORT_IRQ_EDGE_R_X(0) +#define PORT1_IRQ_EDGE_FALL(pin) PORT1_##pin##_IRQ_EDGE_F_X() +#define PORT1_IRQ_EDGE_RISE(pin) PORT1_##pin##_IRQ_EDGE_R_X() +#define PORT2_IRQ_EDGE_FALL(pin) PORT_IRQ_EDGE_F_X(2) +#define PORT2_IRQ_EDGE_RISE(pin) PORT_IRQ_EDGE_R_X(2) + +/* Ports 0 & 2 */ +#define PORT_IRQ_EDGE_F_X(port) do { PICTL |= PICTL_P##port##ICON; } while(0) +#define PORT_IRQ_EDGE_R_X(port) do { PICTL &= ~PICTL_P##port##ICON; } while(0) +/* Port 1 - High Nibble */ +#define PORT1_7_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONH; } while(0) +#define PORT1_7_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONH; } while(0) +#define PORT1_6_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONH; } while(0) +#define PORT1_6_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONH; } while(0) +#define PORT1_5_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONH; } while(0) +#define PORT1_5_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONH; } while(0) +#define PORT1_4_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONH; } while(0) +#define PORT1_4_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONH; } while(0) +/* Port 1 - Low Nibble */ +#define PORT1_3_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONL; } while(0) +#define PORT1_3_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONL; } while(0) +#define PORT1_2_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONL; } while(0) +#define PORT1_2_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONL; } while(0) +#define PORT1_1_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONL; } while(0) +#define PORT1_1_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONL; } while(0) +#define PORT1_0_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONL; } while(0) +#define PORT1_0_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONL; } while(0) +/*---------------------------------------------------------------------------*/ + +#endif /* __PORT_H__ */ diff --git a/cpu/cc253x/dev/random.c b/cpu/cc253x/dev/random.c new file mode 100644 index 000000000..cc99bbfcf --- /dev/null +++ b/cpu/cc253x/dev/random.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Random number generator routines exploiting the cc2530 hardware + * capabilities. + * + * This file overrides core/lib/random.c. + * + * \author + * George Oikonomou - + */ +#include "cc253x.h" +#include "sfr-bits.h" +#include "dev/cc2530-rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \brief Generates a new random number using the cc253x RNG. + * \return The random number. + */ +unsigned short +random_rand(void) +{ + /* Clock the RNG LSFR once */ + ADCCON1 |= ADCCON1_RCTRL0; + + return (RNDL | (RNDH << 8)); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Seed the cc253x random number generator. + * \param seed Ignored. It's here because the function prototype is in core. + * + * We form a seed for the RNG by sampling IF_ADC as + * discussed in the user guide. + * Seeding with this method should not be done during + * normal radio operation. Thus, use this function before + * initialising the network. + */ +void +random_init(unsigned short seed) +{ + int i; + + /* Make sure the RNG is on */ + ADCCON1 &= ~(ADCCON1_RCTRL1 | ADCCON1_RCTRL0); + + /* Infinite RX */ + FRMCTRL0 = FRMCTRL0_RX_MODE1; + + /* Turn RF on */ + CC2530_CSP_ISRXON(); + + /* Wait until (user guide sec. 23.12, p 239) "the chip has been in RX long + * enough for the transients to have died out. A convenient way to do this is + * to wait for the RSSI-valid signal to go high." */ + while(!(RSSISTAT & RSSISTAT_RSSI_VALID)); + + /* + * Form the seed by concatenating bits from IF_ADC in the RF receive path. + * Keep sampling until we have read at least 16 bits AND the seed is valid + * + * Invalid seeds are 0x0000 and 0x8003 - User Guide (sec. 14.2.2 p. 146): + * "Note that a seed value of 0x0000 or 0x8003 always leads to an unchanged + * value in the LFSR after clocking, as no values are pushed in via in_bit + * (see Figure 14-1); hence, neither of these seed values should not be used + * for random-number generation." + */ + i = 0; + while(i < 16 || (seed == 0x0000 || seed == 0x8003)) { + seed = (seed << 1) | (RFRND & RFRND_IRND); + seed <<= 1; + i++; + } + + /* High byte first */ + RNDL = seed >> 8; + RNDL = seed & 0xFF; + + /* RF Off. NETSTACK_RADIO.init() will sort out normal RF operation */ + CC2530_CSP_ISRFOFF(); +} diff --git a/cpu/cc253x/dev/uart-intr.c b/cpu/cc253x/dev/uart-intr.c new file mode 100644 index 000000000..b70acfb03 --- /dev/null +++ b/cpu/cc253x/dev/uart-intr.c @@ -0,0 +1,70 @@ +/** + * \file + * + * uart write routines + * + * \author + * + * Anthony "Asterisk" Ambuehl + * + * interrupt routines which must be in HOME bank. handles received data from UART. + * + */ +#include "cc253x.h" + +#include "dev/uart0.h" +#include "dev/uart1.h" +#include "sys/energest.h" +#include "dev/leds.h" + +#if UART0_ENABLE +static int (*uart0_input_handler)(unsigned char c); +#endif +#if UART1_ENABLE +static int (*uart1_input_handler)(unsigned char c); +#endif + +#if UART0_ENABLE +/*---------------------------------------------------------------------------*/ +void +uart0_set_input(int (*input)(unsigned char c)) +{ + uart0_input_handler = input; +} +/*---------------------------------------------------------------------------*/ +#if UART0_CONF_WITH_INPUT +void +uart0_rx_isr(void) __interrupt (URX0_VECTOR) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + leds_toggle(LEDS_YELLOW); + URX0IF = 0; + if(uart0_input_handler != NULL) { + uart0_input_handler(U0DBUF); + } + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +#endif +#endif /* UART0_ENABLE */ +#if UART1_ENABLE +/*---------------------------------------------------------------------------*/ +void +uart1_set_input(int (*input)(unsigned char c)) +{ + uart1_input_handler = input; +} +/*---------------------------------------------------------------------------*/ +#if UART_ONE_CONF_WITH_INPUT +void +uart1_rx_isr(void) __interrupt (URX1_VECTOR) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + URX1IF = 0; + if(uart1_input_handler != NULL) { + uart1_input_handler(U1DBUF); + } + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +#endif /* UART_ONE_CONF_WITH_INPUT */ +#endif /* UART1_ENABLE */ diff --git a/cpu/cc253x/dev/uart.h b/cpu/cc253x/dev/uart.h new file mode 100644 index 000000000..1a20fd530 --- /dev/null +++ b/cpu/cc253x/dev/uart.h @@ -0,0 +1,43 @@ +#ifndef UART_H +#define UART_H + +#include "contiki-conf.h" + +#include "cc253x.h" +#include "8051def.h" + +/*---------------------------------------------------------------------------*/ +/* UART BAUD Rates */ +/* + * Macro to set speed of UART N by setting the UnBAUD SFR to M and the + * UnGCR SRF to E. See the cc2530 datasheet for possible values of M and E + */ +#define UART_SET_SPEED(N, M, E) do{ U##N##BAUD = M; U##N##GCR = E; } while(0) + +/* + * Sample Values for M and E in the macro above to achieve some common BAUD + * rates. For more values, see the cc2430 datasheet + */ +/* 2000000 - cc2430 theoretical MAX when using the 32MHz clock */ +#define UART_2K_M 0 +#define UART_2K_E 16 +/* 1000000 - cc2430 theoretical MAX when using the 16MHz clock */ +#define UART_1K_M 0 +#define UART_1K_E 15 +/* 921600 */ +#define UART_921_M 216 +#define UART_921_E 14 +/* 460800 Higher values lead to problems when the node needs to RX */ +#define UART_460_M 216 +#define UART_460_E 13 +/* 115200 */ +#define UART_115_M 216 +#define UART_115_E 11 +/* 38400 */ +#define UART_38_M 59 +#define UART_38_E 10 +/* 9600 */ +#define UART_9_M 59 +#define UART_9_E 8 + +#endif /* UART_H */ diff --git a/cpu/cc253x/dev/uart0.c b/cpu/cc253x/dev/uart0.c new file mode 100644 index 000000000..ba7856e77 --- /dev/null +++ b/cpu/cc253x/dev/uart0.c @@ -0,0 +1,75 @@ +/** + * \file + * + * uart0 write routines + * + * \author + * + * Anthony "Asterisk" Ambuehl + * + */ +#include +#include + +#include "cc253x.h" +#include "sfr-bits.h" +#include "dev/uart0.h" + +#if UART0_ENABLE +/*---------------------------------------------------------------------------*/ +void +uart0_init() +{ +#if UART0_CONF_HIGH_SPEED + UART_SET_SPEED(0, UART_460_M, UART_460_E); +#else + UART_SET_SPEED(0, UART_115_M, UART_115_E); +#endif + +#ifdef UART0_ALTERNATIVE_2 + PERCFG |= PERCFG_U0CFG; / *alternative port 2 = P1.5-2 */ +#ifdef UART0_RTSCTS + P1SEL |= 0x3C; /* peripheral select for TX and RX, RTS, CTS */ +#else + P1SEL |= 0x30; /* peripheral select for TX and RX */ + P1 &= ~0x08; /* RTS down */ +#endif + P1DIR |= 0x28; /* RTS, TX out */ + P1DIR &= ~0x14; /* CTS & RX in */ +#else + PERCFG &= ~PERCFG_U0CFG; /* alternative port 1 = P0.5-2 */ +#ifdef UART0_RTSCTS + P0SEL |= 0x20 | 0x10; /* peripheral select for TX and RX */ +#else + P0SEL |= 0x0C; /* peripheral select for TX and RX */ + P0 &= ~0x20; /* RTS down */ +#endif + P0DIR |= 0x28; /* RTS, TX out */ + P0DIR &= ~0x14; /* CTS, RX in */ +#endif + + +#ifdef UART0_RTSCTS + U0UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/ +#else + U0UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/ +#endif + + U0CSR = UCSR_MODE; /* UART mode */ + U0UCR = 0x80; /* Flush */ + UART0_RX_EN(); + + UART0_RX_INT(1); + U0DBUF = 0; +} +/*---------------------------------------------------------------------------*/ +/* Write one byte over the UART. */ +void +uart0_writeb(uint8_t byte) +{ + UTX0IF = 0; + U0DBUF = byte; + while(!UTX0IF); /* Wait until byte has been transmitted. */ + UTX0IF = 0; +} +#endif diff --git a/cpu/cc253x/dev/uart0.h b/cpu/cc253x/dev/uart0.h new file mode 100644 index 000000000..45839e120 --- /dev/null +++ b/cpu/cc253x/dev/uart0.h @@ -0,0 +1,41 @@ +#ifndef UART_0_H +#define UART_0_H + +#include "contiki-conf.h" + +#include "cc253x.h" +#include "8051def.h" +#include "uart.h" + +/*---------------------------------------------------------------------------*/ +/* UART0 Enable - Disable */ +#ifdef UART0_CONF_ENABLE +#define UART0_ENABLE UART0_CONF_ENABLE +#else +#define UART0_ENABLE 0 +#endif +/*---------------------------------------------------------------------------*/ +/* UART0 Function Declarations */ +#if UART0_ENABLE +void uart0_init(); +void uart0_writeb(uint8_t byte); + +void uart0_set_input(int (*input)(unsigned char c)); + +#if UART0_CONF_WITH_INPUT +void uart0_rx_isr( void ) __interrupt (URX0_VECTOR); +/* Macro to turn on / off UART RX Interrupt */ +#define UART0_RX_INT(v) do { URX0IE = v; } while(0) +#define UART0_RX_EN() do { U0CSR |= UCSR_RE; } while(0) +#else +#define UART0_RX_INT(v) +#define UART0_RX_EN() +#endif /* UART0_CONF_WITH_INPUT */ +#else +#define uart0_init(...) +#define uart0_writeb(...) +#define uart0_set_input(...) +#define UART0_RX_INT(v) +#define UART0_RX_EN() +#endif /* UART0_ENABLE */ +#endif /* UART_0_H */ diff --git a/cpu/cc253x/dev/uart1.c b/cpu/cc253x/dev/uart1.c new file mode 100644 index 000000000..8b3006c99 --- /dev/null +++ b/cpu/cc253x/dev/uart1.c @@ -0,0 +1,74 @@ +/** + * \file + * + * uart1 write routines + * + * \author + * + * Anthony "Asterisk" Ambuehl + * + */ +#include +#include + +#include "cc253x.h" +#include "dev/uart1.h" + +#if UART1_ENABLE +/*---------------------------------------------------------------------------*/ +/* UART1 initialization */ +void +uart1_init() +{ +#ifdef UART1_ALTERNATIVE_1 + PERCFG &= ~PERCFG_U1CFG; /*alternative port 1 = P0.5-2*/ +#ifdef UART1_RTSCTS + P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/ +#else + P0SEL |= 0x30; /*peripheral select for TX and RX*/ + P0 &= ~0x08; /*RTS down*/ +#endif + P0DIR |= 0x18; /*RTS, TX out*/ + P0DIR &= ~0x24; /*CTS, RX in*/ +#else + PERCFG |= PERCFG_U1CFG; /*alternative port 2 = P1.7-4*/ +#ifdef UART1_RTSCTS + P1SEL |= 0xF0; /*peripheral select for TX and RX*/ +#else + P1SEL |= 0xC0; /*peripheral select for TX and RX*/ + P1 &= ~0x20; /*RTS down*/ +#endif + P1DIR |= 0x60; /*RTS, TX out*/ + P1DIR &= ~0x90; /*CTS, RX in*/ +#endif + +#if UART_ONE_CONF_HIGH_SPEED + UART_SET_SPEED(1, UART_460_M, UART_460_E); +#else + UART_SET_SPEED(1, UART_115_M, UART_115_E); +#endif + +#ifdef UART1_RTSCTS + U1UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/ +#else + U1UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/ +#endif + + U1CSR = UCSR_MODE; /* UART mode */ + U1UCR = 0x80; /* Flush */ + + UART1_RX_INT(1); + U0DBUF = 0; +} +/*---------------------------------------------------------------------------*/ +/* Write one byte over the UART. */ +void +uart1_writeb(uint8_t byte) +{ + UTX1IF = 0; + U1DBUF = byte; + while(!UTX1IF); /* Wait until byte has been transmitted. */ + UTX1IF = 0; +} +/*---------------------------------------------------------------------------*/ +#endif diff --git a/cpu/cc253x/dev/uart1.h b/cpu/cc253x/dev/uart1.h new file mode 100644 index 000000000..aea8bec48 --- /dev/null +++ b/cpu/cc253x/dev/uart1.h @@ -0,0 +1,38 @@ +#ifndef UART_1_H +#define UART_1_H + +#include "contiki-conf.h" + +#include "cc253x.h" +#include "8051def.h" +#include "uart.h" + +/*---------------------------------------------------------------------------*/ +/* UART1 Enable - Disable */ +#ifdef UART1_CONF_ENABLE +#define UART1_ENABLE UART1_CONF_ENABLE +#else +#define UART1_ENABLE 0 +#endif +/*---------------------------------------------------------------------------*/ +/* UART1 Function Declarations */ +#if UART1_ENABLE +void uart1_init(); +void uart1_writeb(uint8_t byte); + +void uart1_set_input(int (*input)(unsigned char c)); +#if UART1_CONF_WITH_INPUT +void uart1_rx_isr( void ) __interrupt (URX1_VECTOR); +/* Macro to turn on / off UART RX Interrupt */ +#define UART1_RX_INT(v) do { URX1IE = v; } while(0) +#else +#define UART1_RX_INT(v) +#endif /* UART1_CONF_WITH_INPUT */ +#else +#define uart1_init(...) +#define uart1_writeb(...) +#define uart1_set_input(...) +#define UART1_RX_INT(v) +#endif /* UART1_ENABLE */ + +#endif /* UART_1_H */ diff --git a/cpu/cc253x/dev/watchdog.c b/cpu/cc253x/dev/watchdog.c new file mode 100644 index 000000000..92cf40f16 --- /dev/null +++ b/cpu/cc253x/dev/watchdog.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Hardware-dependent functions for the cc253x watchdog. + * + * This file contains an ISR and must reside in the HOME bank. + * + * \author + * George Oikonomou - + */ + +#include "sys/energest.h" +#include "cc253x.h" +#include "sfr-bits.h" +#include "contiki-conf.h" + +#define WDT_TIMEOUT_MIN (WDCTL_INT1 | WDCTL_INT0) +/*---------------------------------------------------------------------------*/ +void +watchdog_init(void) +{ + WDCTL = 0; /* IDLE, Max Interval */ +} +/*---------------------------------------------------------------------------*/ +void +watchdog_start(void) +{ + WDCTL |= WDCTL_MODE1; /* Start in Watchdog mode */ +} +/*---------------------------------------------------------------------------*/ +void +watchdog_periodic(void) +{ + /* Write the 'clear' sequence while maintaining mode and interval setting */ + WDCTL = (WDCTL & 0x0F) | WDCTL_CLR3 | WDCTL_CLR1; + WDCTL = (WDCTL & 0x0F) | WDCTL_CLR2 | WDCTL_CLR0; +} +/*---------------------------------------------------------------------------*/ +void +watchdog_stop(void) +{ + /* In watchdog mode, stopping is impossible so we just reset the timer */ + watchdog_periodic(); +} +/*---------------------------------------------------------------------------*/ +void +watchdog_reboot(void) +{ + WDCTL = WDT_TIMEOUT_MIN; + /* Dis-acknowledge all interrupts while we wait for the dog to bark */ + DISABLE_INTERRUPTS(); + /* NOP till the dog barks... */ + while(1) { + __asm + nop + __endasm; + } +} diff --git a/cpu/cc253x/mtarch.h b/cpu/cc253x/mtarch.h new file mode 100644 index 000000000..89d7766e2 --- /dev/null +++ b/cpu/cc253x/mtarch.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + */ + + /* + * \file + * Stub header file for multi-threading. It doesn't do anything, it + * just exists so that mt.c can compile cleanly. + * + * This is based on the original mtarch.h for z80 by Takahide Matsutsuka + * + * \author + * George Oikonomou - + */ +#ifndef __MTARCH_H__ +#define __MTARCH_H__ + +struct mtarch_thread { + unsigned char *sp; +}; + +#endif /* __MTARCH_H__ */ + diff --git a/cpu/cc253x/rtimer-arch.c b/cpu/cc253x/rtimer-arch.c new file mode 100644 index 000000000..01512a724 --- /dev/null +++ b/cpu/cc253x/rtimer-arch.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + * + */ + +/** + * \file + * Hardware-dependent functions used to support the + * contiki rtimer module. + * + * clock_init() has set our tick speed prescaler already, so we + * are ticking with 500 kHz freq. + * + * Contiki typedefs rtimer_clock_t as unsigned short (16bit) + * It thus makes sense to use the 16bit timer (Timer 1) + * + * This file contains an ISR and must reside in the HOME bank + * + * \author + * George Oikonomou - + */ + +#include "sys/rtimer.h" +#include "sfr-bits.h" +#include "cc253x.h" +#include "sys/energest.h" + +#include "debug.h" +#include + +#define RT_MODE_COMPARE() do { T1CCTL1 |= T1CCTL_MODE; } while(0) +#define RT_MODE_CAPTURE() do { T1CCTL1 &= ~T1CCTL_MODE; } while(0) +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_init(void) +{ + /* + * - Free running mode + * - Prescale by 32: + * Tick Speed has been prescaled to 500 kHz already in clock_init() + * We further prescale by 32 resulting in 15625 Hz for this timer. + */ + T1CTL = (T1CTL_DIV1 | T1CTL_MODE0); + + T1STAT = 0; + + /* Timer 1, Channel 1. Compare Mode (0x04), Interrupt mask on (0x40) */ + T1CCTL1 = T1CCTL_MODE | T1CCTL_IM; + + /* Interrupt Mask Flags: No interrupt on overflow */ + OVFIM = 0; + + /* Acknowledge Timer 1 Interrupts */ + T1IE = 1; +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + /* Switch to capture mode before writing T1CC1x and + * set the compare mode values so we can get an interrupt after t */ + RT_MODE_CAPTURE(); + T1CC1L = (unsigned char) t; + T1CC1H = (unsigned char) (t >> 8); + RT_MODE_COMPARE(); + + /* Turn on compare mode interrupt */ + T1STAT = 0; + T1CCTL1 |= T1CCTL_IM; +} +/*---------------------------------------------------------------------------*/ +void +rtimer_isr(void) __interrupt(T1_VECTOR) +{ + T1IE = 0; /* Ignore Timer 1 Interrupts */ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + /* No more interrupts from Channel 1 till next rtimer_arch_schedule() call */ + T1STAT &= ~T1STAT_CH1IF; + T1CCTL1 &= ~T1CCTL_IM; + + rtimer_run_next(); + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); + T1IE = 1; /* Acknowledge Timer 1 Interrupts */ +} diff --git a/cpu/cc253x/rtimer-arch.h b/cpu/cc253x/rtimer-arch.h new file mode 100644 index 000000000..d261a95e9 --- /dev/null +++ b/cpu/cc253x/rtimer-arch.h @@ -0,0 +1,61 @@ +/* + * 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: rtimer-arch.h,v 1.1 2009/09/08 20:07:35 zdshelby Exp $ + */ + +/** + * \file + * Hardware-dependent function declarations used to + * support the contiki rtimer module. + * + * \author + * Zach Shelby (Original) + * George Oikonomou - + * (rtimer-arch implementation for cc2430 and then cc253x) + */ + +#ifndef __RTIMER_ARCH_H__ +#define __RTIMER_ARCH_H__ + +#include "contiki-conf.h" +#include "cc253x.h" + +/* + * 32 MHz clock, prescaled down to 500 kHz for all 4 timers in clock_init(). + * Further prescaled factor 32 for T1, thus T1 is 15625 Hz + */ +#define RTIMER_ARCH_SECOND (15625U) + +#define rtimer_arch_now() (T1CNTL + (T1CNTH << 8)) + +void rtimer_isr(void) __interrupt(T1_VECTOR); + +#endif /* __RTIMER_ARCH_H__ */ diff --git a/cpu/cc253x/segment.rules b/cpu/cc253x/segment.rules new file mode 100644 index 000000000..594675d03 --- /dev/null +++ b/cpu/cc253x/segment.rules @@ -0,0 +1,22 @@ +# segment.rules files assign source code modules to specific banks +# These files are only used when we build code with banking (HAVE_BANKING=1) +# The final segment.rules file is constructed from any segment.rules found in +# the search path, defined in the CPU Makefile +# When building bankable code, the bank-alloc.py script automatically allocates +# modules to banks. segment.rules files provide hints, instructing the script +# as to which files are safe to move around and which files to leave alone +# In other words, only specify a rule for a file if you need to +# comments starting with "#" are supported +# The file spec in rules is actually interpreted as a python regex so you can +# write a rule that will match multiple files +# +# general rules -- +# This file is only used when the Makefile defines HAVE_BANKING=1 +# SDCC's standard libraries will always go in CSEG - We don't touch them +# Interrupt code must be in HOME. Specify all files with an ISR here +# All files without an associated rule get allocated to a bank automatically + +# Files with ISRs must be in HOME +HOME intr.c # Match all files ending in intr.c (e.g. uart-intr.c) +HOME rtimer-arch.c +HOME clock.c diff --git a/cpu/cc253x/sfr-bits.h b/cpu/cc253x/sfr-bits.h new file mode 100644 index 000000000..a3a48be95 --- /dev/null +++ b/cpu/cc253x/sfr-bits.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Header file with definitions of bit masks for some cc2530 SFRs + * + * \author + * George Oikonomou - + */ + + +#ifndef SFR_BITS_H_ +#define SFR_BITS_H_ + +/* CLKCON */ +#define CLKCONCMD_OSC32K 0x80 +#define CLKCONCMD_OSC 0x40 +#define CLKCONCMD_TICKSPD2 0x20 +#define CLKCONCMD_TICKSPD1 0x10 +#define CLKCONCMD_TICKSPD0 0x08 +#define CLKCONCMD_CLKSPD2 0x04 +#define CLKCONCMD_CLKSPD1 0x02 +#define CLKCONCMD_CLKSPD0 0x01 + +/* SLEEPCMD and SLEEPSTA */ +#define SLEEP_OSC32K_CALDIS 0x80 +#define SLEEP_XOSC_STB 0x40 +#define SLEEP_HFRC_STB 0x20 +#define SLEEP_RST1 0x10 /* SLEEPSTA only */ +#define SLEEP_RST0 0x08 /* SLEEPSTA only */ +#define SLEEP_OSC_PD 0x04 +#define SLEEP_MODE1 0x02 +#define SLEEP_MODE0 0x01 + +/* PCON */ +#define PCON_IDLE 0x01 + +/* T1CTL */ +#define T1CTL_DIV1 0x08 +#define T1CTL_DIV0 0x04 +#define T1CTL_MODE1 0x02 +#define T1CTL_MODE0 0x01 + +/* T1CCTLx */ +#define T1CCTL_RFIRQ 0x80 +#define T1CCTL_IM 0x40 +#define T1CCTL_CMP2 0x20 +#define T1CCTL_CMP1 0x10 +#define T1CCTL_CMP0 0x08 +#define T1CCTL_MODE 0x04 +#define T1CCTL_CAP1 0x02 +#define T1CCTL_CAP0 0x01 + +/* T1STAT */ +#define T1STAT_OVFIF 0x20 +#define T1STAT_CH4IF 0x10 +#define T1STAT_CH3IF 0x08 +#define T1STAT_CH2IF 0x04 +#define T1STAT_CH1IF 0x02 +#define T1STAT_CH0IF 0x01 + +/* WDCTL */ +#define WDCTL_CLR3 0x80 +#define WDCTL_CLR2 0x40 +#define WDCTL_CLR1 0x20 +#define WDCTL_CLR0 0x10 +#define WDCTL_MODE1 0x04 +#define WDCTL_MODE0 0x04 +#define WDCTL_INT1 0x02 +#define WDCTL_INT0 0x01 + +/* ADCCON1 */ +#define ADCCON1_EOC 0x80 +#define ADCCON1_ST 0x40 +#define ADCCON1_STSEL1 0x20 +#define ADCCON1_STSEL0 0x10 +/* ADCCON1 - RNG bits */ +#define ADCCON1_RCTRL1 0x08 +#define ADCCON1_RCTRL0 0x04 + +/* ADCCON3 */ +#define ADCCON3_EREF1 0x80 +#define ADCCON3_EREF0 0x40 +#define ADCCON3_EDIV1 0x20 +#define ADCCON3_EDIV0 0x10 +#define ADCCON3_ECH3 0x08 +#define ADCCON3_ECH2 0x04 +#define ADCCON3_ECH1 0x02 +#define ADCCON3_ECH0 0x01 + +/* PERCFG */ +#define PERCFG_T1CFG 0x40 +#define PERCFG_T3CFG 0x20 +#define PERCFG_T4CFG 0x10 +#define PERCFG_U1CFG 0x02 +#define PERCFG_U0CFG 0x01 + +/* UxCSR */ +#define UCSR_MODE 0x80 +#define UCSR_RE 0x40 +#define UCSR_SLAVE 0x20 +#define UCSR_FE 0x10 +#define UCSR_ERR 0x08 +#define UCSR_RX_BYTE 0x04 +#define UCSR_TX_BYTE 0x02 +#define UCSR_ACTIVE 0x01 + +/* IEN2 */ +#define IEN2_WDTIE 0x20 +#define IEN2_P1IE 0x10 +#define IEN2_UTX1IE 0x08 +#define IEN2_UTX0IE 0x04 +#define IEN2_P2IE 0x02 +#define IEN2_RFIE 0x01 + +/* PICTL */ +#define PICTL_PADSC 0x40 +#define PICTL_P2ICON 0x08 +#define PICTL_P1ICONH 0x04 +#define PICTL_P1ICONL 0x02 +#define PICTL_P0ICON 0x01 +/*--------------------------------------------------------------------------- + * XREG bits, excluding RF and USB + *---------------------------------------------------------------------------*/ +/* FCTL */ +#define FCTL_BUSY 0x80 +#define FCTL_FULL 0x40 +#define FCTL_ABORT 0x20 +#define FCTL_CM1 0x08 +#define FCTL_CM0 0x04 +#define FCTL_WRITE 0x02 +#define FCTL_ERASE 0x01 +/*--------------------------------------------------------------------------- + * Radio Register Bits + *---------------------------------------------------------------------------*/ +/* FRMCTRL0 */ +#define FRMCTRL0_APPEND_DATA_MODE 0x80 +#define FRMCTRL0_AUTOCRC 0x40 +#define FRMCTRL0_AUTOACK 0x20 +#define FRMCTRL0_ENERGY_SCAN 0x10 +#define FRMCTRL0_RX_MODE1 0x08 +#define FRMCTRL0_RX_MODE0 0x04 +#define FRMCTRL0_TX_MODE1 0x02 +#define FRMCTRL0_TX_MODE0 0x01 + +/* FRMCTRL1 */ +#define FRMCTRL1_PENDING_OR 0x04 +#define FRMCTRL1_IGNORE_TX_UNDERF 0x02 +#define FRMCTRL1_SET_RXENMASK_ON_TX 0x01 + +/* FSMSTAT1 */ +#define FSMSTAT1_FIFO 0x80 +#define FSMSTAT1_FIFOP 0x40 +#define FSMSTAT1_SFD 0x20 +#define FSMSTAT1_CCA 0x10 +#define FSMSTAT1_TX_ACTIVE 0x02 +#define FSMSTAT1_RX_ACTIVE 0x01 + +/* RSSISTAT */ +#define RSSISTAT_RSSI_VALID 0x01 + +/* RFRND */ +#define RFRND_QRND 0x02 +#define RFRND_IRND 0x01 + +#endif /* SFR_BITS_H_ */ diff --git a/cpu/cc253x/soc.c b/cpu/cc253x/soc.c new file mode 100644 index 000000000..36d9531e4 --- /dev/null +++ b/cpu/cc253x/soc.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Init routine for the cc2530 SoC + * + * Bankable + * + * \author + * George Oikonomou - + */ +#include "cc253x.h" +#include "8051def.h" +#include "sfr-bits.h" + +void +soc_init() +{ + /* Flash: Cache with Pre-fetch */ + FCTL = FCTL_CM0; + + /* Enable Global Interrupt */ + ENABLE_INTERRUPTS(); +} + diff --git a/cpu/cc253x/soc.h b/cpu/cc253x/soc.h new file mode 100644 index 000000000..81888e2ab --- /dev/null +++ b/cpu/cc253x/soc.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Header file for cc253x SoC hardware init routines + * + * \author + * George Oikonomou - + */ + + +#ifndef __SOC_H__ +#define __SOC_H__ + +void soc_init(); + +#endif /* __SOC_H__ */ diff --git a/examples/cc2530dk/Makefile b/examples/cc2530dk/Makefile new file mode 100644 index 000000000..acffeada8 --- /dev/null +++ b/examples/cc2530dk/Makefile @@ -0,0 +1,6 @@ +CONTIKI_PROJECT = hello-world blink-hello timer-test sensors-demo + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/cc2530dk/Makefile.target b/examples/cc2530dk/Makefile.target new file mode 100644 index 000000000..70609bbdb --- /dev/null +++ b/examples/cc2530dk/Makefile.target @@ -0,0 +1 @@ +TARGET = cc2530dk diff --git a/examples/cc2530dk/blink-hello.c b/examples/cc2530dk/blink-hello.c new file mode 100644 index 000000000..98ed76b10 --- /dev/null +++ b/examples/cc2530dk/blink-hello.c @@ -0,0 +1,62 @@ +/* This is a very simple hello_world program. + * It aims to demonstrate the co-existence of two processes: + * One of them prints a hello world message and the other blinks the LEDs + * + * It is largely based on hello_world in $(CONTIKI)/examples/sensinode + * + * Author: George Oikonomou - + */ + +#include "contiki.h" +#include "dev/leds.h" + +#include /* For printf() */ +/*---------------------------------------------------------------------------*/ +static struct etimer et_hello; +static struct etimer et_blink; +static uint16_t count; +static uint8_t blinks; +/*---------------------------------------------------------------------------*/ +PROCESS(hello_world_process, "Hello world process"); +PROCESS(blink_process, "LED blink process"); +AUTOSTART_PROCESSES(&hello_world_process, &blink_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(hello_world_process, ev, data) +{ + PROCESS_BEGIN(); + + etimer_set(&et_hello, CLOCK_SECOND * 4); + count = 0; + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == PROCESS_EVENT_TIMER) { + printf("Sensor says #%u\n", count); + count ++; + + etimer_reset(&et_hello); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + etimer_set(&et_blink, CLOCK_SECOND); + + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); + + blinks = leds_get(); + leds_off(LEDS_ALL); + leds_on((blinks + 1) & LEDS_ALL); + printf("Blink... (state %0.2X)\n", leds_get()); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/border-router/Makefile b/examples/cc2530dk/border-router/Makefile new file mode 100644 index 000000000..eb8b69c2b --- /dev/null +++ b/examples/cc2530dk/border-router/Makefile @@ -0,0 +1,15 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +# We need uIPv6, therefore we also need banking +HAVE_BANKING=1 +UIP_CONF_IPV6=1 + +PROJECT_SOURCEFILES += slip-bridge.c + +CONTIKI_PROJECT = border-router + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. + +include $(CONTIKI)/Makefile.include diff --git a/examples/cc2530dk/border-router/Makefile.target b/examples/cc2530dk/border-router/Makefile.target new file mode 100644 index 000000000..70609bbdb --- /dev/null +++ b/examples/cc2530dk/border-router/Makefile.target @@ -0,0 +1 @@ +TARGET = cc2530dk diff --git a/examples/cc2530dk/border-router/README b/examples/cc2530dk/border-router/README new file mode 100644 index 000000000..3df598278 --- /dev/null +++ b/examples/cc2530dk/border-router/README @@ -0,0 +1,16 @@ +border-router example for the TI SmartRF05EB with a cc2530EM. + +This example is meant to be used with tunslip6 in tools/ + +- Build the code and load it onto your node +- Connect your node to your PC +- run: + sudo ./tunslip6 -s /dev/ttyUSBx
/ + + This will setup tun0 on your PC over device /dev/ttyUSBx. The address + argument should contain the v6 address that you want to assign to tun0 + The node will use this address to obtain the network prefix + + for example: + sudo ./tunslip6 aaaa::1/64 + This will use aaaa:: / 64 as the prefix for the 15.4 network. diff --git a/examples/cc2530dk/border-router/border-router.c b/examples/cc2530dk/border-router/border-router.c new file mode 100644 index 000000000..50de6462a --- /dev/null +++ b/examples/cc2530dk/border-router/border-router.c @@ -0,0 +1,131 @@ +/* + * 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 "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + +#include + +#define DEBUG DEBUG_PRINT +#include "net/uip-debug.h" +#include "net/rpl/rpl.h" +#include "dev/watchdog.h" +#include "dev/slip.h" +#include "dev/leds.h" +#include "cc253x.h" + +static uint8_t prefix_set; +/*---------------------------------------------------------------------------*/ +PROCESS(border_router_process, "Border Router process"); +AUTOSTART_PROCESSES(&border_router_process); +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Router's IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state + == ADDR_PREFERRED)) { + PRINTF(" "); + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + if (state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} +/*---------------------------------------------------------------------------*/ +void +request_prefix(void) { + /* mess up uip_buf with a dirty request... */ + uip_buf[0] = '?'; + uip_buf[1] = 'P'; + uip_len = 2; + slip_send(); + uip_len = 0; +} +/*---------------------------------------------------------------------------*/ +/* Set our prefix when we receive one over SLIP */ +void +set_prefix_64(uip_ipaddr_t *prefix_64) { + rpl_dag_t *dag; + uip_ipaddr_t ipaddr; + memcpy(&ipaddr, prefix_64, 16); + prefix_set = 1; + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + /* Become root of a new DODAG with ID our global v6 address */ + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); + if(dag != NULL) { + rpl_set_prefix(dag, &ipaddr, 64); + PRINTF("Created a new RPL dag with ID: "); + PRINT6ADDR(&dag->dag_id); + PRINTF("\n"); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + PRINTF("Border Router started\n"); + prefix_set = 0; + + leds_on(LEDS_RED); + + /* Request prefix until it has been received */ + while(!prefix_set) { + leds_on(LEDS_GREEN); + PRINTF("Prefix request.\n"); + etimer_set(&et, CLOCK_SECOND); + request_prefix(); + leds_off(LEDS_GREEN); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + } + + /* We have created a new DODAG when we reach here */ + PRINTF("On Channel %u\n", (uint8_t)((FREQCTRL + 44) / 5)); + + print_local_addresses(); + + leds_off(LEDS_RED); + + PROCESS_EXIT(); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/border-router/project-conf.h b/examples/cc2530dk/border-router/project-conf.h new file mode 100644 index 000000000..7f4c6aab1 --- /dev/null +++ b/examples/cc2530dk/border-router/project-conf.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Project specific configuration defines for the border router / + * slip bridge example for cc253x. + * + * \author + * George Oikonomou - + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define VIZTOOL_MAX_PAYLOAD_LEN 120 +#define SLIP_ARCH_CONF_ENABLE 1 +#define LPM_CONF_MODE 0 + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/cc2530dk/border-router/slip-bridge.c b/examples/cc2530dk/border-router/slip-bridge.c new file mode 100644 index 000000000..dc8db1ab9 --- /dev/null +++ b/examples/cc2530dk/border-router/slip-bridge.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2010, 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. + * + * $Id: slip-bridge.c,v 1.3 2010/06/08 19:53:49 nifi Exp $ + */ + +/** + * \file + * Slip fallback interface + * \author + * Niclas Finne + * Joakim Eriksson + * Joel Hoglund + * Nicolas Tsiftes + */ + +#include "net/uip.h" +#include "net/uip-ds6.h" +#include "net/rpl/rpl.h" +#include "dev/slip.h" +#include + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" + +void set_prefix_64(uip_ipaddr_t *); + +static uip_ipaddr_t last_sender; +/*---------------------------------------------------------------------------*/ +static void +slip_input_callback(void) +{ + PRINTF("SIN: %u\n", uip_len); + if((char) uip_buf[0] == '!') { + PRINTF("Got configuration message of type %c\n", uip_buf[1]); + uip_len = 0; + if((char)uip_buf[1] == 'P') { + uip_ipaddr_t prefix; + /* Here we set a prefix !!! */ + memset(&prefix, 0, 16); + memcpy(&prefix, &uip_buf[2], 8); + PRINTF("Setting prefix "); + PRINT6ADDR(&prefix); + PRINTF("\n"); + set_prefix_64(&prefix); + } + } + /* Save the last sender received over SLIP to avoid bouncing the + packet back if no route is found */ + uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); +} +#include "debug.h" + +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + process_start(&slip_process, NULL); + slip_set_input_callback(slip_input_callback); +} +/*---------------------------------------------------------------------------*/ +static void +output(void) +{ + if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { + /* Do not bounce packets back over SLIP if the packet was received + over SLIP */ + PRINTF("slip-bridge: Destination off-link but no route\n"); + } else { + PRINTF("SUT: %u\n", uip_len); + slip_send(); + } +} +/*---------------------------------------------------------------------------*/ +struct uip_fallback_interface slip_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/hello-world.c b/examples/cc2530dk/hello-world.c new file mode 100644 index 000000000..ec3d2c3d6 --- /dev/null +++ b/examples/cc2530dk/hello-world.c @@ -0,0 +1,23 @@ +/** + * \file + * Basic hello world example + * \author + * Zach Shelby + */ + +#include "contiki.h" +#include /* For printf() */ +/*---------------------------------------------------------------------------*/ +PROCESS(hello_world_process, "Hello world process"); +AUTOSTART_PROCESSES(&hello_world_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(hello_world_process, ev, data) +{ + + PROCESS_BEGIN(); + + printf("Hello World!\n"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/sensors-demo.c b/examples/cc2530dk/sensors-demo.c new file mode 100644 index 000000000..5707fc96b --- /dev/null +++ b/examples/cc2530dk/sensors-demo.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Example to demonstrate-test cc2530 sensor functionality + * + * B1 turns LED_GREEN on and off. + * + * The node takes readings from the various sensors every x seconds and + * prints out the results. + * + * We use floats here to translate the AD conversion results to + * meaningful values. However, our printf does not have %f support so + * we use an ugly hack to print out the value by extracting the integral + * part and then the fractional part. Don't try this at home. + * + * Temperature: + * Math is correct, the sensor needs calibration per device. + * I currently use default values for the math which may result in + * very incorrect values in degrees C. + * See TI Design Note DN102 about the offset calibration. + * + * Supply Voltage (VDD): + * For VDD, math is correct, conversion is correct. + * See DN101 for details. + * + * Make sure you enable/disable things in contiki-conf.h + * + * \author + * George Oikonomou - + */ + +#include "contiki.h" +#include "contiki-conf.h" +#include "dev/leds.h" + +#include "dev/button-sensor.h" +#include "dev/adc-sensor.h" + +#define DEBUG 1 + +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else /* DEBUG */ +/* We overwrite (read as annihilate) all output functions here */ +#define PRINTF(...) +#endif /* DEBUG */ +/*---------------------------------------------------------------------------*/ +PROCESS(sensors_test_process, "Sensor Test Process"); +#if BUTTON_SENSOR_ON +PROCESS(buttons_test_process, "Button Test Process"); +AUTOSTART_PROCESSES(&sensors_test_process, &buttons_test_process); +#else +AUTOSTART_PROCESSES(&sensors_test_process); +#endif +/*---------------------------------------------------------------------------*/ +#if BUTTON_SENSOR_ON +PROCESS_THREAD(buttons_test_process, ev, data) +{ + struct sensors_sensor *sensor; + + PROCESS_BEGIN(); + + while (1) { + + PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event); + + /* If we woke up after a sensor event, inform what happened */ + sensor = (struct sensors_sensor *)data; + if(sensor == &button_sensor) { + PRINTF("Button Press\n"); + leds_toggle(LEDS_GREEN); + } + } + + PROCESS_END(); +} +#endif +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sensors_test_process, ev, data) +{ + static struct etimer et; + + /* Sensor Values */ + static int rv; + static struct sensors_sensor * sensor; + static float sane = 0; + static int dec; + static float frac; + + PROCESS_BEGIN(); + + PRINTF("========================\n"); + PRINTF("Starting Sensor Example.\n"); + PRINTF("========================\n"); + + /* Set an etimer. We take sensor readings when it expires and reset it. */ + etimer_set(&et, CLOCK_SECOND * 2); + + while (1) { + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* + * Request some ADC conversions + * Return value -1 means sensor not available or turned off in conf + */ + sensor = sensors_find(ADC_SENSOR); + if (sensor) { + PRINTF("------------------\n"); + leds_on(LEDS_RED); + /* + * Temperature: + * Using 1.25V ref. voltage (1250mV). + * Typical AD Output at 25°C: 1480 + * Typical Co-efficient : 4.5 mV/°C + * + * Thus, at 12bit decimation (and ignoring the VDD co-efficient as well + * as offsets due to lack of calibration): + * + * AD - 1480 + * T = 25 + --------- + * 4.5 + */ + rv = sensor->value(ADC_SENSOR_TYPE_TEMP); + if(rv != -1) { + sane = 25 + ((rv - 1480) / 4.5); + dec = sane; + frac = sane - dec; + PRINTF(" Temp=%d.%02u C (%d)\n", dec, (unsigned int)(frac*100), rv); + } + /* + * Power Supply Voltage. + * Using 1.25V ref. voltage. + * AD Conversion on VDD/3 + * + * Thus, at 12bit resolution: + * + * ADC x 1.25 x 3 + * Supply = -------------- V + * 2047 + */ + rv = sensor->value(ADC_SENSOR_TYPE_VDD); + if(rv != -1) { + sane = rv * 3.75 / 2047; + dec = sane; + frac = sane - dec; + PRINTF("Supply=%d.%02u V (%d)\n", dec, (unsigned int)(frac*100), rv); + /* Store rv temporarily in dec so we can use it for the battery */ + dec = rv; + } + /* + * Battery Voltage - ToDo + * rv = sensor->value(ADC_SENSOR_TYPE_BATTERY); + */ + + leds_off(LEDS_RED); + } + etimer_reset(&et); + } + PROCESS_END(); + } +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/sniffer/Makefile b/examples/cc2530dk/sniffer/Makefile new file mode 100644 index 000000000..d9491a92c --- /dev/null +++ b/examples/cc2530dk/sniffer/Makefile @@ -0,0 +1,10 @@ +DEFINES+=PROJECT_CONF_H +PROJECT_SOURCEFILES += stub-rdc.c + +CONTIKI_PROJECT = sniffer + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. + +include $(CONTIKI)/Makefile.include diff --git a/examples/cc2530dk/sniffer/Makefile.target b/examples/cc2530dk/sniffer/Makefile.target new file mode 100644 index 000000000..70609bbdb --- /dev/null +++ b/examples/cc2530dk/sniffer/Makefile.target @@ -0,0 +1 @@ +TARGET = cc2530dk diff --git a/examples/cc2530dk/sniffer/netstack.c b/examples/cc2530dk/sniffer/netstack.c new file mode 100644 index 000000000..2551f82fe --- /dev/null +++ b/examples/cc2530dk/sniffer/netstack.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Stub file overriding core/net/netstack.c. What we want to achieve + * here is call netstack_init from main without initialising the RDC, + * MAC and Network layers. It will just turn on the radio instead. + * + * \author + * George Oikonomou - + */ + +#include "netstack.h" +/*---------------------------------------------------------------------------*/ +void +netstack_init(void) +{ + NETSTACK_RADIO.init(); +} +/*---------------------------------------------------------------------------*/ + diff --git a/examples/cc2530dk/sniffer/project-conf.h b/examples/cc2530dk/sniffer/project-conf.h new file mode 100644 index 000000000..564f4d760 --- /dev/null +++ b/examples/cc2530dk/sniffer/project-conf.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Project specific configuration defines for the sniffer example. + * + * \author + * George Oikonomou - + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define CC2530_RF_CONF_HEXDUMP 1 +#define CC2530_RF_CONF_AUTOACK 0 +#define NETSTACK_CONF_RDC stub_rdc_driver +#define ADC_SENSOR_CONF_ON 0 +#define LPM_CONF_MODE 0 +#define UART0_CONF_HIGH_SPEED 1 + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/cc2530dk/sniffer/sniffer.c b/examples/cc2530dk/sniffer/sniffer.c new file mode 100644 index 000000000..2183f88d7 --- /dev/null +++ b/examples/cc2530dk/sniffer/sniffer.c @@ -0,0 +1,54 @@ +/* + * 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 "contiki.h" +#include "cc253x.h" + +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" + +/*---------------------------------------------------------------------------*/ +PROCESS(sniffer_process, "Sniffer process"); +AUTOSTART_PROCESSES(&sniffer_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sniffer_process, ev, data) +{ + + PROCESS_BEGIN(); + + PRINTF("Sniffer started\n"); + + /* Turn off RF Address Recognition - We need to accept all frames */ + FRMFILT0 &= ~0x01; + + PROCESS_EXIT(); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/sniffer/stub-rdc.c b/examples/cc2530dk/sniffer/stub-rdc.c new file mode 100644 index 000000000..603552c97 --- /dev/null +++ b/examples/cc2530dk/sniffer/stub-rdc.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Definition of a fake RDC driver to be used with passive + * examples. The sniffer will never send packets and it will never + * push incoming packets up the stack. We do this by defining this + * driver as our RDC. We then drop everything + * + * \author + * George Oikonomou - + */ + +#include "net/mac/mac.h" +#include "net/mac/rdc.h" +/*---------------------------------------------------------------------------*/ +static void +send(mac_callback_t sent, void *ptr) +{ + if(sent) { + sent(ptr, MAC_TX_OK, 1); + } +} +/*---------------------------------------------------------------------------*/ +static void +input(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(int keep_radio_on) +{ + return keep_radio_on; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +cca(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +const struct rdc_driver stub_rdc_driver = { + "stub-rdc", + init, + send, + input, + on, + off, + cca, +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/timer-test.c b/examples/cc2530dk/timer-test.c new file mode 100644 index 000000000..6843e4df3 --- /dev/null +++ b/examples/cc2530dk/timer-test.c @@ -0,0 +1,139 @@ +/** + * \file + * Tests related to clocks and timers + * + * This is clock_test.c plus a small addition by George Oikonomou + * (Loughborough University) in order to test the rtimer + * + * \author + * Zach Shelby (Original) + * George Oikonomou - (rtimer code) + * + */ + +#include "contiki.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "dev/leds.h" + +#include + +/*---------------------------------------------------------------------------*/ +#define TEST_CLOCK_DELAY 1 +#define TEST_RTIMER 1 +#define TEST_ETIMER 1 +#define TEST_CLOCK_SECONDS 1 +/*---------------------------------------------------------------------------*/ +static struct etimer et; + +#if TEST_CLOCK_DELAY +static clock_time_t start_count, end_count, diff; +#endif + +#if TEST_CLOCK_SECONDS +static unsigned long sec; +#endif + +#if TEST_ETIMER +static clock_time_t count; +#endif + +#if TEST_RTIMER +static struct rtimer rt; +rtimer_clock_t rt_now, rt_for; +static clock_time_t ct; +#endif + +static uint8_t i; +/*---------------------------------------------------------------------------*/ +PROCESS(clock_test_process, "Clock test process"); +AUTOSTART_PROCESSES(&clock_test_process); +/*---------------------------------------------------------------------------*/ +#if TEST_RTIMER +void +rt_callback(struct rtimer *t, void *ptr) { + rt_now = RTIMER_NOW(); + ct = clock_time(); + printf("Task called at %u (clock = %u)\n", rt_now, ct); +} +#endif +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(clock_test_process, ev, data) +{ + + PROCESS_BEGIN(); + + etimer_set(&et, 2 * CLOCK_SECOND); + + PROCESS_YIELD(); + +#if TEST_CLOCK_DELAY + printf("Clock delay test, (10,000 x i) cycles:\n"); + i = 1; + while(i < 6) { + start_count = clock_time(); + clock_delay(10000 * i); + end_count = clock_time(); + diff = end_count - start_count; + printf("Delayed %u = %u ticks = ~%u ms\n", 10000 * i, diff, diff * 8); + i++; + } +#endif + +#if TEST_RTIMER + printf("Rtimer Test, 1 sec (%u rtimer ticks):\n", RTIMER_SECOND); + i = 0; + while(i < 5) { + etimer_set(&et, 2*CLOCK_SECOND); + printf("=======================\n"); + ct = clock_time(); + rt_now = RTIMER_NOW(); + rt_for = rt_now + RTIMER_SECOND; + printf("Now=%u (clock = %u) - For=%u\n", rt_now, ct, rt_for); + if (rtimer_set(&rt, rt_for, 1, + (void (*)(struct rtimer *, void *))rt_callback, NULL) != RTIMER_OK) { + printf("Error setting\n"); + } + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + i++; + } +#endif + +#if TEST_ETIMER + printf("Clock tick and etimer test, 1 sec (%u clock ticks):\n", CLOCK_SECOND); + i = 0; + while(i < 10) { + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + + count = clock_time(); + printf("%u ticks\n", count); + + leds_toggle(LEDS_RED); + i++; + } +#endif + +#if TEST_CLOCK_SECONDS + printf("Clock seconds test (5s):\n"); + i = 0; + while(i < 10) { + etimer_set(&et, 5 * CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + + sec = clock_seconds(); + printf("%lu seconds\n", sec); + + leds_toggle(LEDS_GREEN); + i++; + } +#endif + + printf("Done!\n"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/udp-ipv6/Makefile b/examples/cc2530dk/udp-ipv6/Makefile new file mode 100644 index 000000000..f21c02ca2 --- /dev/null +++ b/examples/cc2530dk/udp-ipv6/Makefile @@ -0,0 +1,14 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +HAVE_BANKING=1 +UIP_CONF_IPV6=1 + +PROJECT_SOURCEFILES += ping6.c + +CONTIKI_PROJECT = client server + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. + +include $(CONTIKI)/Makefile.include diff --git a/examples/cc2530dk/udp-ipv6/Makefile.target b/examples/cc2530dk/udp-ipv6/Makefile.target new file mode 100644 index 000000000..70609bbdb --- /dev/null +++ b/examples/cc2530dk/udp-ipv6/Makefile.target @@ -0,0 +1 @@ +TARGET = cc2530dk diff --git a/examples/cc2530dk/udp-ipv6/client.c b/examples/cc2530dk/udp-ipv6/client.c new file mode 100644 index 000000000..224a775af --- /dev/null +++ b/examples/cc2530dk/udp-ipv6/client.c @@ -0,0 +1,159 @@ +/* + * 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 "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + +#include +#include "dev/leds.h" +#include "dev/button-sensor.h" +#include "debug.h" + +#define DEBUG DEBUG_PRINT +#include "net/uip-debug.h" + +#define SEND_INTERVAL 2 * CLOCK_SECOND +#define MAX_PAYLOAD_LEN 40 + +static char buf[MAX_PAYLOAD_LEN]; + +/* Our destinations and udp conns. One link-local and one global */ +#define LOCAL_CONN_PORT 3001 +static struct uip_udp_conn *l_conn; +#if UIP_CONF_ROUTER +#define GLOBAL_CONN_PORT 3002 +static struct uip_udp_conn *g_conn; +#endif + +/*---------------------------------------------------------------------------*/ +PROCESS(udp_client_process, "UDP client process"); +#if BUTTON_SENSOR_ON +PROCESS_NAME(ping6_process); +AUTOSTART_PROCESSES(&udp_client_process, &ping6_process); +#else +AUTOSTART_PROCESSES(&udp_client_process); +#endif +/*---------------------------------------------------------------------------*/ +static void +tcpip_handler(void) +{ + leds_on(LEDS_GREEN); + if(uip_newdata()) { + putstring("0x"); + puthex(uip_datalen()); + putstring(" bytes response=0x"); + puthex((*(uint16_t *) uip_appdata) >> 8); + puthex((*(uint16_t *) uip_appdata) & 0xFF); + putchar('\n'); + } + leds_off(LEDS_GREEN); + return; +} +/*---------------------------------------------------------------------------*/ +static void +timeout_handler(void) +{ + static int seq_id; + struct uip_udp_conn * this_conn; + + leds_on(LEDS_RED); + memset(buf, 0, MAX_PAYLOAD_LEN); + seq_id++; + + /* evens / odds */ + if(seq_id & 0x01) { + this_conn = l_conn; + } else { + this_conn = g_conn; + if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) { + return; + } + } + + PRINTF("Client to: "); + PRINT6ADDR(&this_conn->ripaddr); + + memcpy(buf, &seq_id, sizeof(seq_id)); + + PRINTF(" Remote Port %u,", UIP_HTONS(this_conn->rport)); + PRINTF(" (msg=0x%04x), %u bytes\n", *(uint16_t *) buf, sizeof(seq_id)); + + uip_udp_packet_send(this_conn, buf, sizeof(seq_id)); + leds_off(LEDS_RED); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(udp_client_process, ev, data) +{ + static struct etimer et; + uip_ipaddr_t ipaddr; + + PROCESS_BEGIN(); + PRINTF("UDP client process started\n"); + + uip_ip6addr(&ipaddr,0xfe80,0,0,0,0x0215,0x2000,0x0002,0x2145); + /* new connection with remote host */ + l_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); + if(!l_conn) { + PRINTF("udp_new l_conn error.\n"); + } + udp_bind(l_conn, UIP_HTONS(LOCAL_CONN_PORT)); + + PRINTF("Link-Local connection with "); + PRINT6ADDR(&l_conn->ripaddr); + PRINTF(" local/remote port %u/%u\n", + UIP_HTONS(l_conn->lport), UIP_HTONS(l_conn->rport)); + + uip_ip6addr(&ipaddr,0xaaaa,0,0,0,0x0215,0x2000,0x0002,0x2145); + g_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); + if(!g_conn) { + PRINTF("udp_new g_conn error.\n"); + } + udp_bind(g_conn, UIP_HTONS(GLOBAL_CONN_PORT)); + + PRINTF("Global connection with "); + PRINT6ADDR(&g_conn->ripaddr); + PRINTF(" local/remote port %u/%u\n", + UIP_HTONS(g_conn->lport), UIP_HTONS(g_conn->rport)); + + etimer_set(&et, SEND_INTERVAL); + + while(1) { + PROCESS_YIELD(); + if(etimer_expired(&et)) { + timeout_handler(); + etimer_restart(&et); + } else if(ev == tcpip_event) { + tcpip_handler(); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/udp-ipv6/ping6.c b/examples/cc2530dk/udp-ipv6/ping6.c new file mode 100644 index 000000000..f4cc073ab --- /dev/null +++ b/examples/cc2530dk/udp-ipv6/ping6.c @@ -0,0 +1,139 @@ +/* + * 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 "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#include +#include + +#include "dev/button-sensor.h" +#include "debug.h" + +#define DEBUG 1 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",lladdr->addr[0], lladdr->addr[1], lladdr->addr[2], lladdr->addr[3],lladdr->addr[4], lladdr->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#endif + +#define PING6_NB 5 +#define PING6_DATALEN 16 + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) + +static struct etimer ping6_periodic_timer; +static u8_t count = 0; +static u16_t addr[8]; +static uip_ipaddr_t dest_addr; + +PROCESS(ping6_process, "PING6 process"); +/*---------------------------------------------------------------------------*/ +static void +ping6handler() +{ + if(count < PING6_NB) { + UIP_IP_BUF->vtc = 0x60; + UIP_IP_BUF->tcflow = 1; + UIP_IP_BUF->flow = 0; + UIP_IP_BUF->proto = UIP_PROTO_ICMP6; + UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &dest_addr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + + UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST; + UIP_ICMP_BUF->icode = 0; + /* set identifier and sequence number to 0 */ + memset((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4); + /* put one byte of data */ + memset((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN, + count, PING6_DATALEN); + + + uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN + PING6_DATALEN; + UIP_IP_BUF->len[0] = (u8_t)((uip_len - 40) >> 8); + UIP_IP_BUF->len[1] = (u8_t)((uip_len - 40) & 0x00FF); + + UIP_ICMP_BUF->icmpchksum = 0; + UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); + + + PRINTF("Echo Request to"); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("from"); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("\n"); + UIP_STAT(++uip_stat.icmp.sent); + + tcpip_ipv6_output(); + + count++; + etimer_set(&ping6_periodic_timer, 3 * CLOCK_SECOND); + } else { + count = 0; + } +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ping6_process, ev, data) +{ + + PROCESS_BEGIN(); + PRINTF("ping6 running.\n"); + PRINTF("Button 1: 5 pings 16 byte payload.\n"); + + uip_ip6addr(&dest_addr,0xaaaa,0,0,0,0x0215,0x2000,0x0002,0x2145); + count = 0; + + icmp6_new(NULL); + + while(1) { + PROCESS_YIELD(); + +#if BUTTON_SENSOR_ON + if(ev == sensors_event && data == &button_sensor && count == 0) { + ping6handler(); + } +#endif + if(ev == PROCESS_EVENT_TIMER && etimer_expired(&ping6_periodic_timer)) { + ping6handler(); + } + if(ev == tcpip_icmp6_event && *(uint8_t *)data == ICMP6_ECHO_REPLY) { + PRINTF("Echo Reply\n"); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/udp-ipv6/project-conf.h b/examples/cc2530dk/udp-ipv6/project-conf.h new file mode 100644 index 000000000..990a02082 --- /dev/null +++ b/examples/cc2530dk/udp-ipv6/project-conf.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, Loughborough University - 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$ + */ + +/** + * \file + * Project specific configuration defines for the UDP client/server + * example. + * + * \author + * George Oikonomou - + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define BUTTON_SENSOR_CONF_ON 1 +#define UIP_CONF_ICMP6 1 + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/cc2530dk/udp-ipv6/server.c b/examples/cc2530dk/udp-ipv6/server.c new file mode 100644 index 000000000..2d9ff70b7 --- /dev/null +++ b/examples/cc2530dk/udp-ipv6/server.c @@ -0,0 +1,174 @@ +/* + * 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 "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + +#include + +#define DEBUG DEBUG_PRINT +#include "net/uip-debug.h" +#include "dev/watchdog.h" +#include "dev/leds.h" +#include "net/rpl/rpl.h" +#include "dev/button-sensor.h" +#include "debug.h" + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) + +#define MAX_PAYLOAD_LEN 120 + +static struct uip_udp_conn *server_conn; +static char buf[MAX_PAYLOAD_LEN]; +static uint16_t len; + +#if UIP_CONF_ROUTER +static uip_ipaddr_t ipaddr; +#endif + +#define SERVER_REPLY 1 + +/* Should we act as RPL root? */ +#define SERVER_RPL_ROOT 1 +/*---------------------------------------------------------------------------*/ +PROCESS(udp_server_process, "UDP server process"); +AUTOSTART_PROCESSES(&udp_server_process); +/*---------------------------------------------------------------------------*/ +static void +tcpip_handler(void) +{ + memset(buf, 0, MAX_PAYLOAD_LEN); + if(uip_newdata()) { + leds_on(LEDS_RED); + len = uip_datalen(); + memcpy(buf, uip_appdata, len); + PRINTF("%u bytes from [", len, *(uint16_t *)buf); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport)); +#if SERVER_REPLY + uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); + server_conn->rport = UIP_UDP_BUF->srcport; + + uip_udp_packet_send(server_conn, buf, len); + /* Restore server connection to allow data from any node */ + uip_create_unspecified(&server_conn->ripaddr); + server_conn->rport = 0; +#endif + } + leds_off(LEDS_RED); + return; +} +/*---------------------------------------------------------------------------*/ +#if (BUTTON_SENSOR_ON && (DEBUG==DEBUG_PRINT)) +static void +print_stats() +{ + PRINTF("tl=%lu, ts=%lu, bs=%lu, bc=%lu\n", + rimestats.toolong, rimestats.tooshort, rimestats.badsynch, rimestats.badcrc); + PRINTF("llrx=%lu, lltx=%lu, rx=%lu, tx=%lu\n", + rimestats.llrx, rimestats.lltx, rimestats.rx, rimestats.tx); +} +#else +#define print_stats() +#endif +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state + == ADDR_PREFERRED)) { + PRINTF(" "); + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + if (state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(udp_server_process, ev, data) +{ +#if BUTTON_SENSOR_ON + static struct sensors_sensor *b1; +#endif +#if SERVER_RPL_ROOT + rpl_dag_t *dag; +#endif + PROCESS_BEGIN(); + putstring("Starting UDP server\n"); + +#if BUTTON_SENSOR_ON + putstring("Button 1: Print RIME stats\n"); +#endif + +#if SERVER_RPL_ROOT + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + print_local_addresses(); + + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &uip_ds6_get_global(ADDR_PREFERRED)->ipaddr); + if(dag != NULL) { + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_set_prefix(dag, &ipaddr, 64); + PRINTF("Created a new RPL dag with ID: "); + PRINT6ADDR(&dag->dag_id); + PRINTF("\n"); + } +#endif /* SERVER_RPL_ROOT */ + + server_conn = udp_new(NULL, UIP_HTONS(0), NULL); + udp_bind(server_conn, UIP_HTONS(3000)); + + PRINTF("Listen port: 3000, TTL=%u\n", server_conn->ttl); + + while(1) { + PROCESS_YIELD(); + if(ev == tcpip_event) { + tcpip_handler(); +#if BUTTON_SENSOR_ON + } else if(ev == sensors_event && data == &button_sensor) { + print_stats(); +#endif /* (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) */ + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/cc2530dk/Makefile.cc2530dk b/platform/cc2530dk/Makefile.cc2530dk new file mode 100644 index 000000000..12001350f --- /dev/null +++ b/platform/cc2530dk/Makefile.cc2530dk @@ -0,0 +1,52 @@ +# cc2530dk platform makefile + +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +CONTIKI_TARGET_DIRS = . dev +CONTIKI_TARGET_MAIN = $(addprefix $(OBJECTDIR)/,contiki-main.rel) + +CONTIKI_TARGET_SOURCEFILES = contiki-main.c +CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c +CONTIKI_TARGET_SOURCEFILES += sensors.c smartrf-sensors.c +CONTIKI_TARGET_SOURCEFILES += button-sensor.c adc-sensor.c smartrf-sensors.c +CONTIKI_TARGET_SOURCEFILES += serial-line.c slip-arch.c slip.c #serial-flash.c +CONTIKI_TARGET_SOURCEFILES += putchar.c debug.c + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +CLEAN += *.cc2530dk + +ifdef UIP_CONF_IPV6 + CONTIKI_TARGET_SOURCEFILES += viztool.c +endif + +FORCE: + +# .sensinode target so we can behave similar to other targets +%.$(TARGET): %.hex FORCE + cp $< $(<:.hex=.$(TARGET)) + @echo "\nReport" + @echo "===============" + @echo 'Code footprint:' + @echo 'Area Addr Size' \ + ' Decimal' + @echo '---------------------------------- -------- --------' \ + ' --------' + @echo -n 'HOME,CSEG,CONST,XINIT,GS* $(HOME_START) ' + @egrep ',CODE\)' $(<:.hex=.map) | egrep -v '(^BANK[1-9][^=])' | uniq | \ + awk '{ SUM += $$5 } END { printf "%08X = %8d", SUM, SUM }' + @echo '. bytes (REL,CON,CODE)' + @egrep '(^BANK[1-9][^=])' $(<:.hex=.map) | uniq | sort + @egrep -A 5 'Other memory' $(<:.hex=.mem) + +%.upload: %.hex + $(PROG) -P $< + +sensinode.serialdump: + $(SERIALDUMP) + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/cc253x +include $(CONTIKI_CPU)/Makefile.cc253x diff --git a/platform/cc2530dk/contiki-conf.h b/platform/cc2530dk/contiki-conf.h new file mode 100644 index 000000000..4eae96016 --- /dev/null +++ b/platform/cc2530dk/contiki-conf.h @@ -0,0 +1,225 @@ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#include "8051def.h" +#include "sys/cc.h" +#include + +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include "project-conf.h" +#endif /* PROJECT_CONF_H */ + +/* Time type. */ +typedef unsigned short clock_time_t; + +/* Defines tick counts for a second. */ +#define CLOCK_CONF_SECOND 128 + +/* Energest Module */ +#ifndef ENERGEST_CONF_ON +#define ENERGEST_CONF_ON 0 +#endif + +/* Verbose Startup? Turning this off saves plenty of bytes of CODE in HOME */ +#define STARTUP_CONF_VERBOSE 0 + +/* More CODE space savings by turning off process names */ +#define PROCESS_CONF_NO_PROCESS_NAMES 1 + +/* + * USARTs: + * SmartRF RS232 -> USART0 / Alternative 1 (UART) + * SmartRF LCD -> USART1 / Alternative 2 (SPI) + */ +#define UART_ON_USART 0 + +#define UART1_CONF_ENABLE 0 + +#ifndef UART0_CONF_ENABLE +#define UART0_CONF_ENABLE 1 +#endif +#ifndef UART0_CONF_WITH_INPUT +#define UART0_CONF_WITH_INPUT 0 +#endif + +#ifndef UART0_CONF_HIGH_SPEED +#define UART0_CONF_HIGH_SPEED 0 +#endif + +/* Are we a SLIP bridge? */ +#if SLIP_ARCH_CONF_ENABLE +/* Make sure the UART is enabled, with interrupts */ +#undef UART0_CONF_ENABLE +#undef UART0_CONF_WITH_INPUT +#define UART0_CONF_ENABLE 1 +#define UART0_CONF_WITH_INPUT 1 +#define UIP_FALLBACK_INTERFACE slip_interface +#endif + +/* Output all captured frames over the UART in hexdump format */ +#ifndef CC2530_RF_CONF_HEXDUMP +#define CC2530_RF_CONF_HEXDUMP 0 +#endif + +#if CC2530_RF_CONF_HEXDUMP +/* We need UART1 output */ +#undef UART_ZERO_CONF_ENABLE +#define UART_ZERO_CONF_ENABLE 1 +#endif + +/* Code Shortcuts */ +/* + * When set, the RF driver is no longer a contiki process and the RX ISR is + * disabled. Instead of polling the radio process when data arrives, we + * periodically check for data by directly invoking the driver from main() + + * When set, this directive also configures the following bypasses: + * - process_post_synch() in tcpip_input() (we call packet_input()) + * - process_post_synch() in tcpip_uipcall (we call the relevant pthread) + * - mac_call_sent_callback() is replaced with sent() in various places + * + * These are good things to do, we reduce stack usage, RAM size and code size + */ +#define SHORTCUTS_CONF_NETSTACK 1 + +/* + * Sensors + * It is harmless to #define XYZ 1 + * even if the sensor is not present on our device + */ +#ifndef BUTTON_SENSOR_CONF_ON +#define BUTTON_SENSOR_CONF_ON 1 /* Buttons */ +#endif +/* ADC - Turning this off will disable everything below */ +#ifndef ADC_SENSOR_CONF_ON +#define ADC_SENSOR_CONF_ON 1 +#endif +#define TEMP_SENSOR_CONF_ON 1 /* Temperature */ +#define VDD_SENSOR_CONF_ON 1 /* Supply Voltage */ +#define BATTERY_SENSOR_CONF_ON 0 /* Battery */ + +/* Low Power Modes - We only support PM0/Idle and PM1 */ +#ifndef LPM_CONF_MODE +#define LPM_CONF_MODE 0 /* 0: no LPM, 1: MCU IDLE, 2: Drop to PM1 */ +#endif + +/* Some files include leds.h before us */ +#undef LEDS_YELLOW +#undef LEDS_RED +#define LEDS_YELLOW 4 +#define LEDS_RED 2 + +/* DMA Configuration */ +#ifndef DMA_CONF_ON +#define DMA_CONF_ON 0 +#endif + +/* Viztool on by default for IPv6 builds */ +#if UIP_CONF_IPV6 +#ifndef VIZTOOL_CONF_ON +#define VIZTOOL_CONF_ON 1 +#endif /* VIZTOOL_CONF_ON */ +#endif /* UIP_CONF_IPV6 */ + +/* Network Stack */ +#if UIP_CONF_IPV6 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#else +#define NETSTACK_CONF_NETWORK rime_driver +#endif + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver +#define NULLRDC_802154_AUTOACK 1 +#define NULLRDC_802154_AUTOACK_HW 1 +#endif + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_RADIO cc2530_rf_driver + +/* RF Config */ +#define IEEE802154_CONF_PANID 0x5449 /* TI */ + +#ifndef CC2530_RF_CONF_CHANNEL +#define CC2530_RF_CONF_CHANNEL 25 +#endif /* CC2530_RF_CONF_CHANNEL */ + +#ifndef CC2530_RF_CONF_AUTOACK +#define CC2530_RF_CONF_AUTOACK 1 +#endif /* CC2530_CONF_AUTOACK */ + +#if UIP_CONF_IPV6 +/* Addresses, Sizes and Interfaces */ +/* 8-byte addresses here, 2 otherwise */ +#define RIMEADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 + +/* TCP, UDP, ICMP */ +#define UIP_CONF_TCP 0 +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 + +/* ND and Routing */ +#define UIP_CONF_ROUTER 1 +#define UIP_CONF_IPV6_RPL 1 +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_IP_FORWARD 0 +#define RPL_CONF_STATS 0 +#define RPL_CONF_MAX_DAG_ENTRIES 1 +#ifndef RPL_CONF_OF +#define RPL_CONF_OF rpl_of_etx +#endif + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef UIP_CONF_DS6_NBR_NBU +#define UIP_CONF_DS6_NBR_NBU 4 /* Handle n Neighbors */ +#endif +#ifndef UIP_CONF_DS6_ROUTE_NBU +#define UIP_CONF_DS6_ROUTE_NBU 4 /* Handle n Routes */ +#endif + +/* uIP */ +#define UIP_CONF_BUFFER_SIZE 240 +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 + +/* 6lowpan */ +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 0 /* About 2KB of CODE if 1 */ +#endif +#define SICSLOWPAN_CONF_MAXAGE 8 + +/* Define our IPv6 prefixes/contexts here */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { \ + addr_contexts[0].prefix[0] = 0xaa; \ + addr_contexts[0].prefix[1] = 0xaa; \ +} + +#define MAC_CONF_CHANNEL_CHECK_RATE 8 +#define QUEUEBUF_CONF_NUM 6 + +#else /* UIP_CONF_IPV6 */ +/* Network setup for non-IPv6 (rime). */ +#define UIP_CONF_IP_FORWARD 1 +#define UIP_CONF_BUFFER_SIZE 108 +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 +#define QUEUEBUF_CONF_NUM 8 +#endif /* UIP_CONF_IPV6 */ + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/cc2530dk/contiki-main.c b/platform/cc2530dk/contiki-main.c new file mode 100644 index 000000000..e5b89a682 --- /dev/null +++ b/platform/cc2530dk/contiki-main.c @@ -0,0 +1,333 @@ +#include "contiki.h" +#include "soc.h" +#include "sys/clock.h" +#include "sys/autostart.h" +#include "dev/serial-line.h" +#include "dev/slip.h" +#include "dev/leds.h" +#include "dev/uart0.h" +#include "dev/dma.h" +#include "dev/cc2530-rf.h" +#include "dev/watchdog.h" +#include "dev/clock-isr.h" +#include "dev/lpm.h" +#include "dev/button-sensor.h" +#include "dev/adc-sensor.h" +#include "dev/leds-arch.h" +#include "net/rime.h" +#include "net/netstack.h" +#include "net/mac/frame802154.h" +#include "debug.h" +#include "cc253x.h" +#include "sfr-bits.h" +#include "contiki-lib.h" +#include "contiki-net.h" +/*---------------------------------------------------------------------------*/ +#if VIZTOOL_CONF_ON +PROCESS_NAME(viztool_process); +#endif +/*---------------------------------------------------------------------------*/ +#ifdef STARTUP_CONF_VERBOSE +#define STARTUP_VERBOSE STARTUP_CONF_VERBOSE +#else +#define STARTUP_VERBOSE 0 +#endif + +#if STARTUP_VERBOSE +#define PUTSTRING(...) putstring(__VA_ARGS__) +#define PUTHEX(...) puthex(__VA_ARGS__) +#define PUTBIN(...) putbin(__VA_ARGS__) +#define PUTCHAR(...) putchar(__VA_ARGS__) +#else +#define PUTSTRING(...) do {} while(0) +#define PUTHEX(...) do {} while(0) +#define PUTBIN(...) do {} while(0) +#define PUTCHAR(...) do {} while(0) +#endif +/*---------------------------------------------------------------------------*/ +extern rimeaddr_t rimeaddr_node_addr; +static __data int r; +static __data int len; +/*---------------------------------------------------------------------------*/ +#if ENERGEST_CONF_ON +static unsigned long irq_energest = 0; +#define ENERGEST_IRQ_SAVE(a) do { \ + a = energest_type_time(ENERGEST_TYPE_IRQ); } while(0) +#define ENERGEST_IRQ_RESTORE(a) do { \ + energest_type_set(ENERGEST_TYPE_IRQ, a); } while(0) +#else +#define ENERGEST_IRQ_SAVE(a) do {} while(0) +#define ENERGEST_IRQ_RESTORE(a) do {} while(0) +#endif +/*---------------------------------------------------------------------------*/ +static void +fade(int l) +{ + volatile int i, a; + int k, j; + for(k = 0; k < 400; ++k) { + j = k > 200? 400 - k: k; + + leds_on(l); + for(i = 0; i < j; ++i) { + a = i; + } + leds_off(l); + for(i = 0; i < 200 - j; ++i) { + a = i; + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_rime_addr(void) +{ + uint8_t *addr_long = NULL; + uint16_t addr_short = 0; + char i; + + __xdata unsigned char * macp = &X_IEEE_ADDR; + + PUTSTRING("Rime is 0x"); + PUTHEX(sizeof(rimeaddr_t)); + PUTSTRING(" bytes long\n"); + + PUTSTRING("Reading MAC from Info Page\n"); + + for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) { + rimeaddr_node_addr.u8[i] = *macp; + macp++; + } + + /* Now the address is stored MSB first */ +#if STARTUP_VERBOSE + PUTSTRING("Rime configured with address "); + for(i = 0; i < RIMEADDR_SIZE - 1; i++) { + PUTHEX(rimeaddr_node_addr.u8[i]); + PUTCHAR(':'); + } + PUTHEX(rimeaddr_node_addr.u8[i]); + PUTCHAR('\n'); +#endif + + cc2530_rf_set_addr(IEEE802154_PANID); +} +/*---------------------------------------------------------------------------*/ +int +main(void) +{ + /* Hardware initialization */ + clock_init(); + soc_init(); + rtimer_init(); + + /* Init LEDs here */ + leds_init(); + leds_off(LEDS_ALL); + fade(LEDS_GREEN); + + /* initialize process manager. */ + process_init(); + + /* Init UART */ + uart0_init(); + +#if DMA_ON + dma_init(); +#endif + +#if SLIP_ARCH_CONF_ENABLE + slip_arch_init(0); +#else + uart0_set_input(serial_line_input_byte); + serial_line_init(); +#endif + fade(LEDS_RED); + + PUTSTRING("##########################################\n"); + putstring(CONTIKI_VERSION_STRING "\n"); + putstring("TI SmartRF05 EB\n"); + switch(CHIPID) { + case 0xA5: + putstring("cc2530"); + break; + case 0xB5: + putstring("cc2531"); + break; + case 0x95: + putstring("cc2533"); + break; + case 0x8D: + putstring("cc2540"); + break; + } + + putstring("-F"); + switch(CHIPINFO0 & 0x70) { + case 0x40: + putstring("256, "); + break; + case 0x30: + putstring("128, "); + break; + case 0x20: + putstring("64, "); + break; + case 0x10: + putstring("32, "); + break; + } + puthex(CHIPINFO1 + 1); + putstring("KB SRAM\n"); + + PUTSTRING("\nSDCC Build:\n"); +#if STARTUP_VERBOSE +#ifdef HAVE_SDCC_BANKING + PUTSTRING(" With Banking.\n"); +#endif /* HAVE_SDCC_BANKING */ +#ifdef SDCC_MODEL_LARGE + PUTSTRING(" --model-large\n"); +#endif /* SDCC_MODEL_LARGE */ +#ifdef SDCC_MODEL_HUGE + PUTSTRING(" --model-huge\n"); +#endif /* SDCC_MODEL_HUGE */ +#ifdef SDCC_STACK_AUTO + PUTSTRING(" --stack-auto\n"); +#endif /* SDCC_STACK_AUTO */ + + PUTCHAR('\n'); + + PUTSTRING(" Net: "); + PUTSTRING(NETSTACK_NETWORK.name); + PUTCHAR('\n'); + PUTSTRING(" MAC: "); + PUTSTRING(NETSTACK_MAC.name); + PUTCHAR('\n'); + PUTSTRING(" RDC: "); + PUTSTRING(NETSTACK_RDC.name); + PUTCHAR('\n'); + + PUTSTRING("##########################################\n"); +#endif + + watchdog_init(); + + /* Initialise the H/W RNG engine. */ + random_init(0); + + /* start services */ + process_start(&etimer_process, NULL); + ctimer_init(); + + /* initialize the netstack */ + netstack_init(); + set_rime_addr(); + +#if BUTTON_SENSOR_ON || ADC_SENSOR_ON + process_start(&sensors_process, NULL); + BUTTON_SENSOR_ACTIVATE(); + ADC_SENSOR_ACTIVATE(); +#endif + +#if UIP_CONF_IPV6 + memcpy(&uip_lladdr.addr, &rimeaddr_node_addr, sizeof(uip_lladdr.addr)); + queuebuf_init(); + process_start(&tcpip_process, NULL); +#endif /* UIP_CONF_IPV6 */ + +#if VIZTOOL_CONF_ON + process_start(&viztool_process, NULL); +#endif + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + autostart_start(autostart_processes); + + watchdog_start(); + + fade(LEDS_YELLOW); + + while(1) { + do { + /* Reset watchdog and handle polls and events */ + watchdog_periodic(); + r = process_run(); + } while(r > 0); +#if SHORTCUTS_CONF_NETSTACK + len = NETSTACK_RADIO.pending_packet(); + if(len) { + packetbuf_clear(); + len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); + if(len > 0) { + packetbuf_set_datalen(len); + NETSTACK_RDC.input(); + } + } +#endif + +#if LPM_MODE +#if (LPM_MODE==LPM_MODE_PM2) + SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ + while(!(SLEEP & HFRC_STB)); /* Wait for RCOSC to be stable */ + CLKCON |= OSC; /* Switch to the RCOSC */ + while(!(CLKCON & OSC)); /* Wait till it's happened */ + SLEEP |= OSC_PD; /* Turn the other one off */ +#endif /* LPM_MODE==LPM_MODE_PM2 */ + + /* + * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM + * Sleep Timer will wake us up in no more than 7.8ms (max idle interval) + */ + SLEEPCMD = (SLEEPCMD & 0xFC) | (LPM_MODE - 1); + +#if (LPM_MODE==LPM_MODE_PM2) + /* + * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or + * no interrupt occurred and we can safely power down + */ + __asm + nop + nop + nop + __endasm; + + if(SLEEPCMD & SLEEP_MODE0) { +#endif /* LPM_MODE==LPM_MODE_PM2 */ + + ENERGEST_OFF(ENERGEST_TYPE_CPU); + ENERGEST_ON(ENERGEST_TYPE_LPM); + + /* We are only interested in IRQ energest while idle or in LPM */ + ENERGEST_IRQ_RESTORE(irq_energest); + + /* Go IDLE or Enter PM1 */ + PCON |= PCON_IDLE; + + /* First instruction upon exiting PM1 must be a NOP */ + __asm + nop + __endasm; + + /* Remember energest IRQ for next pass */ + ENERGEST_IRQ_SAVE(irq_energest); + + ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_OFF(ENERGEST_TYPE_LPM); + +#if (LPM_MODE==LPM_MODE_PM2) + SLEEPCMD &= ~SLEEP_OSC_PD; /* Make sure both HS OSCs are on */ + while(!(SLEEPCMD & SLEEP_XOSC_STB)); /* Wait for XOSC to be stable */ + CLKCONCMD &= ~CLKCONCMD_OSC; /* Switch to the XOSC */ + /* + * On occasion the XOSC is reported stable when in reality it's not. + * We need to wait for a safeguard of 64us or more before selecting it + */ + clock_delay(10); + while(CLKCONCMD & CLKCONCMD_OSC); /* Wait till it's happened */ + } +#endif /* LPM_MODE==LPM_MODE_PM2 */ +#endif /* LPM_MODE */ + } +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/cc2530dk/debug.c b/platform/cc2530dk/debug.c new file mode 100644 index 000000000..29efccf06 --- /dev/null +++ b/platform/cc2530dk/debug.c @@ -0,0 +1,42 @@ +/** + * \file + * + * Definition of some debugging functions. + * + * putstring() and puthex() are from msp430/watchdog.c + * + * \author + * George Oikonomou - + */ + +#include "8051def.h" +#include "debug.h" + +static const char hexconv[] = "0123456789abcdef"; +static const char binconv[] = "01"; +/*---------------------------------------------------------------------------*/ +void +putstring(char *s) +{ + while(*s) { + putchar(*s++); + } +} +/*---------------------------------------------------------------------------*/ +void +puthex(uint8_t c) +{ + putchar(hexconv[c >> 4]); + putchar(hexconv[c & 0x0f]); +} +/*---------------------------------------------------------------------------*/ +void +putbin(uint8_t c) +{ + unsigned char i = 0x80; + while(i) { + putchar(binconv[(c & i) != 0]); + i >>= 1; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/cc2530dk/debug.h b/platform/cc2530dk/debug.h new file mode 100644 index 000000000..a3c5cb01a --- /dev/null +++ b/platform/cc2530dk/debug.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005, 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. + * + */ + +/** + * \file + * Header file for debugging functions used by the sensinode port. + * + * putstring() and puthex() are from msp430/watchdog.c + * + * \author + * George Oikonomou - + */ + +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#include "8051def.h" +#include "dev/uart1.h" + +void putchar(char c); +void putstring(char *s); +void puthex(uint8_t c); +void putbin(uint8_t c); + +#endif /* __DEBUG_H__ */ diff --git a/platform/cc2530dk/dev/adc-sensor.c b/platform/cc2530dk/dev/adc-sensor.c new file mode 100644 index 000000000..005852d96 --- /dev/null +++ b/platform/cc2530dk/dev/adc-sensor.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * ADC sensor module for TI SmartRF05EB devices. + * + * \author + * George Oikonomou - + */ +#include "sfr-bits.h" +#include "cc253x.h" +#include "adc-sensor.h" + +#if ADC_SENSOR_ON +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint16_t reading; + /* + * For single-shot AD conversions, we may only write to ADCCON3[3:0] once + * (This write triggers the conversion). We thus use the variable 'command' + * to store intermediate steps (reference, decimation rate, input channel) + */ + uint8_t command; + + /* 1.25V ref, max decimation rate */ + command = ADCCON3_EDIV1 | ADCCON3_EDIV0; + + /* Clear the Interrupt Flag */ + ADCIF = 0; + + /* Depending on the desired reading, append the input bits to 'command' and + * enable the corresponding input channel in ADCCFG if necessary */ + switch(type) { +#if TEMP_SENSOR_ON + case ADC_SENSOR_TYPE_TEMP: + command |= ADCCON3_ECH3 | ADCCON3_ECH2 | ADCCON3_ECH1; + break; +#endif +#if VDD_SENSOR_ON + case ADC_SENSOR_TYPE_VDD: + command |= ADCCON3_ECH3 | ADCCON3_ECH2 | ADCCON3_ECH1 | ADCCON3_ECH0; + break; +#endif + default: + /* If the sensor is not present or disabled in conf, return -1 */ + return -1; + } + + /* Writing in bits 3:0 of ADCCON3 will trigger a single conversion */ + ADCCON3 = command; + + /* + * When the conversion is complete, the ADC interrupt flag is set. We don't + * use an ISR here, we just wait on the flag and clear it afterwards. + */ + while(!ADCIF); + + /* Clear the Interrupt Flag */ + ADCIF = 0; + + reading = ADCL; + reading |= (((uint8_t) ADCH) << 8); + /* 12-bit decimation rate: 4 LS bits are noise */ + reading >>= 4; + + return reading; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: +#if TEMP_SENSOR_ON + /* Connect temperature sensor to the SoC */ + ATEST = 1; + TR0 = 1; +#endif + APCFG = 0; /* Disables Input Channels */ + break; + } + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_sensor, ADC_SENSOR, value, configure, status); +#endif /* ADC_SENSOR_ON */ diff --git a/platform/cc2530dk/dev/adc-sensor.h b/platform/cc2530dk/dev/adc-sensor.h new file mode 100644 index 000000000..45b0a9985 --- /dev/null +++ b/platform/cc2530dk/dev/adc-sensor.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Header file for ADC sensors on the SmartRF05EB. + * + * Sensors will be off by default, unless turned on explicitly + * in contiki-conf.h + * + * \author + * George Oikonomou - + */ + +#ifndef __ADC_SENSOR_H__ +#define __ADC_SENSOR_H__ + +#include "cc253x.h" +#include "contiki-conf.h" +#include "lib/sensors.h" + +/* ADC Sensor Types */ +#define ADC_SENSOR "ADC" + +#define ADC_SENSOR_TYPE_TEMP 0 +#define ADC_SENSOR_TYPE_VDD 4 + +#ifdef ADC_SENSOR_CONF_ON +#define ADC_SENSOR_ON ADC_SENSOR_CONF_ON +#endif /* ADC_SENSOR_CONF_ON */ + +#if ADC_SENSOR_ON +extern const struct sensors_sensor adc_sensor; +#define ADC_SENSOR_ACTIVATE() adc_sensor.configure(SENSORS_ACTIVE, 1) +#else +#define ADC_SENSOR_ACTIVATE() +#endif /* ADC_SENSOR_ON */ + +/* Battery - SmartRF stuff */ +#ifdef BATTERY_SENSOR_CONF_ON +#define BATTERY_SENSOR_ON BATTERY_SENSOR_CONF_ON +#endif /* BATTERY_SENSOR_CONF_ON */ + +/* Temperature - Available on all devices */ +#ifdef TEMP_SENSOR_CONF_ON +#define TEMP_SENSOR_ON TEMP_SENSOR_CONF_ON +#endif /* TEMP_SENSOR_CONF_ON */ + +/* Supply Voltage (VDD / 3) - Available on all devices*/ +#ifdef VDD_SENSOR_CONF_ON +#define VDD_SENSOR_ON VDD_SENSOR_CONF_ON +#endif /* VDD_SENSOR_CONF_ON */ + +#endif /* __ADC_SENSOR_H__ */ diff --git a/platform/cc2530dk/dev/button-sensor.c b/platform/cc2530dk/dev/button-sensor.c new file mode 100644 index 000000000..d2d9856d2 --- /dev/null +++ b/platform/cc2530dk/dev/button-sensor.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2005, 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. + */ + +/* + * This file contains ISRs: Keep it in the HOME bank. + */ +#include "dev/port.h" +#include "dev/button-sensor.h" +/*---------------------------------------------------------------------------*/ +#if BUTTON_SENSOR_ON +static __data struct timer debouncetimer; +/*---------------------------------------------------------------------------*/ +static +int value(int type) +{ + return BUTTON_READ() || !timer_expired(&debouncetimer); +} +/*---------------------------------------------------------------------------*/ +static +int status(int type) +{ + switch (type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return BUTTON_IRQ_ENABLED(); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static +int configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + P0INP |= 2; /* Tri-state */ + BUTTON_IRQ_ON_PRESS(); + BUTTON_FUNC_GPIO(); + BUTTON_DIR_INPUT(); + return 1; + case SENSORS_ACTIVE: + if(value) { + if(!BUTTON_IRQ_ENABLED()) { + timer_set(&debouncetimer, 0); + BUTTON_IRQ_FLAG_OFF(); + BUTTON_IRQ_ENABLE(); + } + } else { + BUTTON_IRQ_DISABLE(); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +port_0_isr(void) __interrupt(P0INT_VECTOR) +{ + EA = 0; + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + /* This ISR is for the entire port. Check if the interrupt was caused by our + * button's pin. */ + if(BUTTON_IRQ_CHECK()) { + if(timer_expired(&debouncetimer)) { + timer_set(&debouncetimer, CLOCK_SECOND / 8); + sensors_changed(&button_sensor); + } + } + + BUTTON_IRQ_FLAG_OFF(); + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); + EA = 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, configure, status); +#endif /* BUTTON_SENSOR_ON */ diff --git a/platform/cc2530dk/dev/button-sensor.h b/platform/cc2530dk/dev/button-sensor.h new file mode 100644 index 000000000..9eb13b89e --- /dev/null +++ b/platform/cc2530dk/dev/button-sensor.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Override core/dev/button-sensor.h + * + * \author + * George Oikonomou - + */ + +#ifndef __BUTTON_SENSOR_H__ +#define __BUTTON_SENSOR_H__ + +#include "contiki-conf.h" +#include "lib/sensors.h" + +#define BUTTON_PORT 0 +#define BUTTON_PIN 1 + +#define BUTTON_SENSOR "Button" + +/* + * SmartRF Buttons + * B1: P0_1, B2: Not Connected + */ +#ifdef BUTTON_SENSOR_CONF_ON +#define BUTTON_SENSOR_ON BUTTON_SENSOR_CONF_ON +#endif /* BUTTON_SENSOR_CONF_ON */ + +#if BUTTON_SENSOR_ON +extern const struct sensors_sensor button_sensor; +/* Button 1: P0_1 - Port 0 ISR needed */ +void port_0_isr(void) __interrupt(P0INT_VECTOR); +#define BUTTON_SENSOR_ACTIVATE() button_sensor.configure(SENSORS_ACTIVE, 1) +#else +#define BUTTON_SENSOR_ACTIVATE() +#endif /* BUTTON_SENSOR_ON */ + +/* Define macros for button 1 */ +#define BUTTON_READ() PORT_READ(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_FUNC_GPIO() PORT_FUNC_GPIO(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_DIR_INPUT() PORT_DIR_INPUT(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_IRQ_ENABLED() PORT_IRQ_ENABLED(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_IRQ_CHECK() PORT_IRQ_CHECK(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_IRQ_ENABLE() PORT_IRQ_ENABLE(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_IRQ_DISABLE() PORT_IRQ_DISABLE(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_IRQ_FLAG_OFF() PORT_IRQ_FLAG_OFF(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_IRQ_ON_PRESS() PORT_IRQ_EDGE_RISE(BUTTON_PORT, BUTTON_PIN) +#define BUTTON_IRQ_ON_RELEASE() PORT_IRQ_EDGE_FALL(BUTTON_PORT, BUTTON_PIN) + +#endif /* __BUTTON_SENSOR_H__ */ diff --git a/platform/cc2530dk/dev/leds-arch.c b/platform/cc2530dk/dev/leds-arch.c new file mode 100644 index 000000000..fb583a5c2 --- /dev/null +++ b/platform/cc2530dk/dev/leds-arch.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Platform-specific led driver for the TI SmartRF05 Eval. Board. + * + * \author + * George Oikonomou - + */ +#include "contiki-conf.h" +#include "dev/leds.h" +#include "dev/leds-arch.h" +#include "cc253x.h" + +/* + * LEDS + * 1: P1_0 + * 2: P1_1 + * 3: P1_4 + * 4: P0_1 (LED4 shares port/pin with B1 and is currently unused) + */ + +/* H/W Connections */ +#define LED1_PIN P1_0 +#define LED2_PIN P1_1 +#define LED3_PIN P1_4 + +/* P0DIR and P0SEL masks */ +#define LED1_MASK 0x01 +#define LED2_MASK 0x02 +#define LED3_MASK 0x10 +#define LED4_MASK 0x02 +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + P1SEL &= ~(LED1_MASK | LED2_MASK | LED3_MASK); + P1DIR |= (LED1_MASK | LED2_MASK | LED3_MASK); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + unsigned char v; + + v = (unsigned char) (LED1_PIN | (LED2_PIN << 1) | (LED3_PIN << 2)); + + return v; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + LED1_PIN = leds & 0x01; + LED2_PIN = (leds & 0x02) >> 1; + LED3_PIN = (leds & 0x04) >> 2; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/cc2530dk/dev/leds-arch.h b/platform/cc2530dk/dev/leds-arch.h new file mode 100644 index 000000000..b19d5cf9d --- /dev/null +++ b/platform/cc2530dk/dev/leds-arch.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Header file for platform-specific led functionality + * + * \author + * George Oikonomou - + */ + + +#ifndef __LEDS_ARCH_H__ +#define __LEDS_ARCH_H__ + +#include "dev/port.h" + +/* Led 4 on the SmartRF05EB is multiplexed with Button 1 on P0_1 */ +#define LED4_READ() PORT_READ(LED4_PORT, LED4_PIN) +#define LED4_WRITE(v) PORT_WRITE(LED4_PORT, LED4_PIN, v) +#define LED4_FUNC_GPIO() PORT_FUNC_GPIO(LED4_PORT, LED4_PIN) +#define LED4_DIR_INPUT() PORT_DIR_INPUT(LED4_PORT, LED4_PIN) +#define LED4_DIR_OUTPUT() PORT_DIR_OUTPUT(LED4_PORT, LED4_PIN) + +#endif /* __LEDS_ARCH_H__ */ diff --git a/platform/cc2530dk/dev/slip-arch.c b/platform/cc2530dk/dev/slip-arch.c new file mode 100644 index 000000000..1b0437494 --- /dev/null +++ b/platform/cc2530dk/dev/slip-arch.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2006, 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. + * + * @(#)$Id: slip_uart1.c,v 1.8 2008/02/03 20:59:35 adamdunkels Exp $ + */ + +/* + * Machine dependent cc2530eb SLIP routines for UART1. + */ + +#include "dev/slip.h" +#include "dev/uart0.h" +/*---------------------------------------------------------------------------*/ +void +slip_arch_writeb(unsigned char c) +{ + uart0_writeb(c); +} +/*---------------------------------------------------------------------------*/ +void +slip_arch_init(unsigned long ubr) +{ + uart0_set_input(slip_input_byte); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/cc2530dk/dev/smartrf-sensors.c b/platform/cc2530dk/dev/smartrf-sensors.c new file mode 100644 index 000000000..c40cf101b --- /dev/null +++ b/platform/cc2530dk/dev/smartrf-sensors.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011, George Oikonomou - + * 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 + * Data structures for SmartRF05EB sensing elements + * + * \author + * George Oikonomou - + */ + +#include "dev/button-sensor.h" +#include "dev/adc-sensor.h" +#include "sys/energest.h" + +const struct sensors_sensor *sensors[] = { +#if ADC_SENSOR_ON + &adc_sensor, +#endif +#if BUTTON_SENSOR_ON + &button_sensor, +#endif + 0 +}; + +unsigned char sensors_flags[(sizeof(sensors) / sizeof(struct sensors_sensor *))]; diff --git a/platform/cc2530dk/putchar.c b/platform/cc2530dk/putchar.c new file mode 100644 index 000000000..18c4b04a1 --- /dev/null +++ b/platform/cc2530dk/putchar.c @@ -0,0 +1,38 @@ +/** + * \file + * hardware-specific putchar() routine for TI SmartRF05EB + * + * \author + * George Oikonomou - + */ + +#include "contiki-conf.h" +#include "dev/uart0.h" +/*---------------------------------------------------------------------------*/ +void +putchar(char c) +{ +#if SLIP_ARCH_CONF_ENABLE +#define SLIP_END 0300 + static char debug_frame = 0; + + if(!debug_frame) { /* Start of debug output */ + uart0_writeb(SLIP_END); + uart0_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } +#endif + + uart0_writeb((char)c); + +#if SLIP_ARCH_CONF_ENABLE + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if(c == '\n') { + uart0_writeb(SLIP_END); + debug_frame = 0; + } +#endif +} diff --git a/platform/cc2530dk/segment.rules b/platform/cc2530dk/segment.rules new file mode 100644 index 000000000..4810b5129 --- /dev/null +++ b/platform/cc2530dk/segment.rules @@ -0,0 +1,13 @@ +# segment.rules - platform + +# segment.rules file for platform code +# Please see cpu/cc2430/segment.rules for more info on code segments +# and for rules of thumb on what to do and what not to do + +# Keep main() in HOME +HOME contiki-main.c + +# Files with ISRs must be in HOME +HOME button-sensor.c + +# segment.rules - platform - end diff --git a/platform/cc2530dk/viztool.c b/platform/cc2530dk/viztool.c new file mode 100644 index 000000000..777ffc855 --- /dev/null +++ b/platform/cc2530dk/viztool.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Small UDP app used to retrieve neighbor cache and routing table + * entries and send them to an external endpoint + * + * \author + * George Oikonomou - + */ + +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + +#include + +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) + +#ifndef VIZTOOL_MAX_PAYLOAD_LEN +#define VIZTOOL_MAX_PAYLOAD_LEN 60 +#endif + +static struct uip_udp_conn *server_conn; +static unsigned char buf[VIZTOOL_MAX_PAYLOAD_LEN]; +static int8_t len; + +#define VIZTOOL_UDP_PORT 60001 + +/* Request Bits */ +#define REQUEST_TYPE_ND 1 +#define REQUEST_TYPE_RT 2 +#define REQUEST_TYPE_DRT 3 +#define REQUEST_TYPE_ADDR 4 +#define REQUEST_TYPE_TOTALS 0xFF + +extern uip_ds6_netif_t uip_ds6_if; +extern uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; +extern uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB]; +extern uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; +extern u16_t uip_len; +/*---------------------------------------------------------------------------*/ +static uint8_t +process_request() +{ + uint8_t len; + uint8_t count; /* How many did we pack? */ + uint8_t i; + uint8_t left; + uint8_t entry_size; + + left = VIZTOOL_MAX_PAYLOAD_LEN - 1; + len = 2; /* start filling the buffer from position [2] */ + count = 0; + if(buf[0] == REQUEST_TYPE_ND) { + /* Neighbors */ + PRINTF("Neighbors\n"); + for(i = buf[1]; i < UIP_DS6_NBR_NB; i++) { + if(uip_ds6_nbr_cache[i].isused) { + entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t) + + sizeof(uip_ds6_nbr_cache[i].state); + PRINTF("%02u: ", i); + PRINT6ADDR(&uip_ds6_nbr_cache[i].ipaddr); + PRINTF(" - "); + PRINTLLADDR(&uip_ds6_nbr_cache[i].lladdr); + PRINTF(" - %u\n", uip_ds6_nbr_cache[i].state); + + memcpy(buf + len, &i, sizeof(i)); + len += sizeof(i); + memcpy(buf + len, &uip_ds6_nbr_cache[i].ipaddr, sizeof(uip_ipaddr_t)); + len += sizeof(uip_ipaddr_t); + memcpy(buf + len, &uip_ds6_nbr_cache[i].lladdr, sizeof(uip_lladdr_t)); + len += sizeof(uip_lladdr_t); + memcpy(buf + len, &uip_ds6_nbr_cache[i].state, + sizeof(uip_ds6_nbr_cache[i].state)); + len += sizeof(uip_ds6_nbr_cache[i].state); + + count++; + left -= entry_size; + + if(left < entry_size) { + break; + } + } + } + } else if(buf[0] == REQUEST_TYPE_RT) { + uint32_t flip = 0; + PRINTF("Routing table\n"); + for(i = buf[1]; i < UIP_DS6_ROUTE_NB; i++) { + if(uip_ds6_routing_table[i].isused) { + entry_size = sizeof(i) + sizeof(uip_ds6_routing_table[i].ipaddr) + + sizeof(uip_ds6_routing_table[i].length) + + sizeof(uip_ds6_routing_table[i].metric) + + sizeof(uip_ds6_routing_table[i].nexthop) + + sizeof(uip_ds6_routing_table[i].state.lifetime) + + sizeof(uip_ds6_routing_table[i].state.learned_from); + + memcpy(buf + len, &i, sizeof(i)); + len += sizeof(i); + memcpy(buf + len, &uip_ds6_routing_table[i].ipaddr, + sizeof(uip_ds6_routing_table[i].ipaddr)); + len += sizeof(uip_ds6_routing_table[i].ipaddr); + memcpy(buf + len, &uip_ds6_routing_table[i].length, + sizeof(uip_ds6_routing_table[i].length)); + len += sizeof(uip_ds6_routing_table[i].length); + memcpy(buf + len, &uip_ds6_routing_table[i].metric, + sizeof(uip_ds6_routing_table[i].metric)); + len += sizeof(uip_ds6_routing_table[i].metric); + memcpy(buf + len, &uip_ds6_routing_table[i].nexthop, + sizeof(uip_ds6_routing_table[i].nexthop)); + len += sizeof(uip_ds6_routing_table[i].nexthop); + + PRINT6ADDR(&uip_ds6_routing_table[i].ipaddr); + PRINTF(" - %02x", uip_ds6_routing_table[i].length); + PRINTF(" - %02x", uip_ds6_routing_table[i].metric); + PRINTF(" - "); + PRINT6ADDR(&uip_ds6_routing_table[i].nexthop); + + flip = uip_htonl(uip_ds6_routing_table[i].state.lifetime); + memcpy(buf + len, &flip, sizeof(flip)); + len += sizeof(flip); + PRINTF(" - %08lx", uip_ds6_routing_table[i].state.lifetime); + + memcpy(buf + len, &uip_ds6_routing_table[i].state.learned_from, + sizeof(uip_ds6_routing_table[i].state.learned_from)); + len += sizeof(uip_ds6_routing_table[i].state.learned_from); + + PRINTF(" - %02x [%u]\n", uip_ds6_routing_table[i].state.learned_from, + entry_size); + + count++; + left -= entry_size; + + if(left < entry_size) { + break; + } + } + } + } else if (buf[0] == REQUEST_TYPE_DRT) { + uint32_t flip = 0; + PRINTF("Default Routes\n"); + for(i = buf[1]; i < UIP_DS6_DEFRT_NB; i++) { + if(uip_ds6_defrt_list[i].isused) { + entry_size = sizeof(i) + sizeof(uip_ds6_defrt_list[i].ipaddr) + + sizeof(uip_ds6_defrt_list[i].isinfinite); + + memcpy(buf + len, &i, sizeof(i)); + len += sizeof(i); + memcpy(buf + len, &uip_ds6_defrt_list[i].ipaddr, + sizeof(uip_ds6_defrt_list[i].ipaddr)); + len += sizeof(uip_ds6_defrt_list[i].ipaddr); + memcpy(buf + len, &uip_ds6_defrt_list[i].isinfinite, + sizeof(uip_ds6_defrt_list[i].isinfinite)); + len += sizeof(uip_ds6_defrt_list[i].isinfinite); + + PRINT6ADDR(&uip_ds6_defrt_list[i].ipaddr); + PRINTF(" - %u\n", uip_ds6_defrt_list[i].isinfinite); + count++; + left -= entry_size; + + if(left < entry_size) { + break; + } + } + } + } else if (buf[0] == REQUEST_TYPE_ADDR) { + PRINTF("Unicast Addresses\n"); + for(i = buf[1]; i < UIP_DS6_ADDR_NB; i++) { + if(uip_ds6_if.addr_list[i].isused) { + entry_size = sizeof(i) + sizeof(uip_ds6_if.addr_list[i].ipaddr); + + memcpy(buf + len, &i, sizeof(i)); + len += sizeof(i); + memcpy(buf + len, &uip_ds6_if.addr_list[i].ipaddr, + sizeof(uip_ds6_if.addr_list[i].ipaddr)); + len += sizeof(uip_ds6_if.addr_list[i].ipaddr); + + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + count++; + left -= entry_size; + + if(left < entry_size) { + break; + } + } + } + } else if (buf[0] == REQUEST_TYPE_TOTALS) { + memset(&buf[2], 0, 4); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + if(uip_ds6_if.addr_list[i].isused) { + buf[2]++; + } + } + for(i = 0; i < UIP_DS6_NBR_NB; i++) { + if(uip_ds6_nbr_cache[i].isused) { + buf[3]++; + } + } + for(i = 0; i < UIP_DS6_ROUTE_NB; i++) { + if(uip_ds6_routing_table[i].isused) { + buf[4]++; + } + } + for(i = 0; i < UIP_DS6_DEFRT_NB; i++) { + if(uip_ds6_defrt_list[i].isused) { + buf[5]++; + } + } + len += 4; + count = 4; + } else { + return 0; + } + buf[1] = count; + return len; +} +/*---------------------------------------------------------------------------*/ +PROCESS(viztool_process, "Network Visualization Tool Process"); +/*---------------------------------------------------------------------------*/ +static void +tcpip_handler(void) +{ + if(uip_newdata()) { + memset(buf, 0, VIZTOOL_MAX_PAYLOAD_LEN); + + PRINTF("%u bytes from [", uip_datalen()); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport)); + + memcpy(buf, uip_appdata, uip_datalen()); + + len = process_request(); + if(len) { + server_conn->rport = UIP_UDP_BUF->srcport; + uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); + uip_udp_packet_send(server_conn, buf, len); + PRINTF("Sent %u bytes\n", len); + } + + /* Restore server connection to allow data from any node */ + uip_create_unspecified(&server_conn->ripaddr); + server_conn->rport = 0; + } + return; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(viztool_process, ev, data) +{ + + PROCESS_BEGIN(); + + server_conn = udp_new(NULL, UIP_HTONS(0), NULL); + udp_bind(server_conn, UIP_HTONS(VIZTOOL_UDP_PORT)); + + while(1) { + PROCESS_YIELD(); + if(ev == tcpip_event) { + tcpip_handler(); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/