Merge branch 'master' of ssh://contiki.git.sourceforge.net/gitroot/contiki/contiki

This commit is contained in:
nvt 2012-03-26 20:52:09 +02:00
commit ad1d614cea
201 changed files with 18390 additions and 4770 deletions

View file

@ -4,12 +4,34 @@
* Modified from z80 port for cc2430 port. * Modified from z80 port for cc2430 port.
* *
* \author * \author
* Takahide Matsutsuka <markn@markn.org> * Takahide Matsutsuka <markn@markn.org> (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net>
* (recent updates for the sensinode/cc2430 port)
*/ */
#ifndef __8051_DEF_H__ #ifndef __8051_DEF_H__
#define __8051_DEF_H__ #define __8051_DEF_H__
#include <stdint.h>
/*
* 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_FUNCTION_POINTER_ARGS 1
#define CC_CONF_FASTCALL #define CC_CONF_FASTCALL
#define CC_CONF_VA_ARGS 1 #define CC_CONF_VA_ARGS 1
@ -18,30 +40,24 @@
#define CC_CONF_FUNCTION_POINTER_KEYWORD __reentrant #define CC_CONF_FUNCTION_POINTER_KEYWORD __reentrant
/* Generic types. */ /* Generic types. */
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef unsigned char u8_t; /* 8 bit type */ typedef unsigned char u8_t; /* 8 bit type */
typedef unsigned short u16_t; /* 16 bit type */ typedef unsigned short u16_t; /* 16 bit type */
typedef unsigned long u32_t; /* 32 bit type */ typedef unsigned long u32_t; /* 32 bit type */
typedef signed long s32_t; /* 32 bit type */ typedef signed long s32_t; /* 32 bit type */
typedef unsigned short uip_stats_t; typedef unsigned short uip_stats_t;
typedef signed long int32_t; /* 32 bit type */
#ifndef _SIZE_T_DEFINED
#define _SIZE_T_DEFINED /* Time type. */
typedef unsigned int size_t; typedef unsigned short clock_time_t;
#endif #define MAX_TICKS (~((clock_time_t)0) / 2)
/* Compiler configurations */ /* Compiler configurations */
#define CCIF #define CCIF
#define CLIF #define CLIF
#define CC_CONF_CONST_FUNCTION_BUG
/* Critical section management */ /* Critical section management */
#define DISABLE_INTERRUPTS() EA = 0; #define DISABLE_INTERRUPTS() do {EA = 0;} while(0)
#define ENABLE_INTERRUPTS() EA = 1; #define ENABLE_INTERRUPTS() do {EA = 1;} while(0)
#define ENTER_CRITICAL() \ #define ENTER_CRITICAL() \
{ \ { \
@ -64,20 +80,12 @@ typedef unsigned int size_t;
__endasm; \ __endasm; \
} }
/* /* Macro for a soft reset. In many respects better than H/W reboot via W/D */
* Enable architecture-depend checksum calculation #define SOFT_RESET() {((void (__code *) (void)) 0x0000) ();}
* for uIP configuration.
* @see uip_arch.h
* @see uip_arch-asm.S
*/
/*
* DO NOT USE UIP_ARCH flags!
* uip_arch code was copied from z80 directory but NOT ported
*/
/* We don't provide architecture-specific checksum calculations */
#define UIP_ARCH_ADD32 0 #define UIP_ARCH_ADD32 0
#define UIP_ARCH_CHKSUM 0 #define UIP_ARCH_CHKSUM 0
#define UIP_ARCH_IPCHKSUM
#define CC_CONF_ASSIGN_AGGREGATE(dest, src) \ #define CC_CONF_ASSIGN_AGGREGATE(dest, src) \
memcpy(dest, src, sizeof(*dest)) memcpy(dest, src, sizeof(*dest))

View file

@ -2,120 +2,176 @@
CC = sdcc CC = sdcc
LD = sdcc LD = sdcc
AS = sdcc AS = sdcc
AR = sdcclib AR = sdcclib
OBJCOPY = objcopy OBJCOPY = objcopy
STRIP = strip STRIP = strip
PACKIHX = packihx
BANK_ALLOC = $(CONTIKI)/cpu/cc2430/bank-alloc.py
SEGMENT_RULES = $(OBJECTDIR)/segment.rules
CFLAGS += --model-$(MEMORY_MODEL) --stack-auto -DSDCC_CC2430 --std-c99
LDFLAGS += --model-$(MEMORY_MODEL) --stack-auto -DSDCC_CC2430 --out-fmt-ihx
LDFLAGS += --xram-loc 0xE000 --xram-size 0x1F00
LDFLAGS += --code-loc $(START_ADDR) --code-size $(CODE_SIZE)
CFLAGS += --std-c99 --model-large --stack-auto -DSDCC_CC2430
ASFLAGS += -plosgff ASFLAGS += -plosgff
LDFLAGS += --model-large --stack-auto -DSDCC_CC2430 --out-fmt-ihx
LDFLAGS += --xram-loc 57344 --xram-size 8192
##LDFLAGS += -L /home/user/local/share/sdcc/lib/large-stack-auto
##LDFLAGS += --verbose
##LDFLAGS += -V
AROPTS = -a
##HAVE_BANKING=1
ifeq ($(HAVE_BANKING),1)
#banking
LDFLAGS += --code-size 0x20000
LDFLAGS += -Wl-bCSEG=0x000000
LDFLAGS += -Wl-bBANK1=0x018000
LDFLAGS += -Wl-bBANK2=0x028000
LDFLAGS += -Wl-bBANK3=0x038000
#relocated code (for bank switching )
LDFLAGS += -Wl-r
CFLAGS += -DHAVE_SDCC_BANKING
#use this in $(call code_segment,$<) to get segment for a source file.
code_segment = --codeseg $(word 1,$(shell cat ${OBJECTDIR}/segment.rules | perl ${CONTIKI_CPU}/segment.rules.pl $1 ) CSEG )
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:
### Examples outside examples/sensinode 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, turn Disco on
ifeq ($(OFFSET_FIRMWARE),1)
START_ADDR = 0x01000
HOME_START = 00001000
ifeq ($(HAVE_BANKING),1)
CODE_SIZE = 0x1F000
else
CODE_SIZE = 0x0F000
endif
else else
#no banking START_ADDR = 0x00000
LDFLAGS += --code-loc 0000 --code-size 65500 HOME_START = 00000000
code_segment = ifeq ($(HAVE_BANKING),1)
CODE_SIZE = 0x20000
else
CODE_SIZE = 0x10000
endif
endif
### Are we building with BANKing supoprt?
ifeq ($(HAVE_BANKING),1)
## Yes
MEMORY_MODEL=huge
LDFLAGS += -Wl-bBANK1=0x018000
LD_POST_FLAGS += -Wl-bBANK2=0x028000
LD_POST_FLAGS += -Wl-bBANK3=0x038000
LDFLAGS += -Wl-r
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 endif
### CPU-dependent cleanup files ### CPU-dependent cleanup files
CLEAN += *.lnk *.sym *.lib *.ihx *.rel *.mem *.rst *.asm *_linear.hex CLEAN += *.lnk *.lk *.sym *.lib *.ihx *.rel *.mem *.rst *.asm *.hex *.sensinode
CLEAN += *.omf *.cdb *.banks
CLEAN += symbols.c symbols.h
### CPU-dependent directories ### CPU-dependent directories
CONTIKI_CPU_DIRS = . dev CONTIKI_CPU_DIRS = . dev
### CPU-dependent source files ### CPU-dependent source files
CONTIKI_SOURCEFILES += bus.c clock.c uart.c cc2430_rf.c dma.c CONTIKI_SOURCEFILES += bus.c clock.c uart0.c uart1.c cc2430_rf.c dma.c
CONTIKI_SOURCEFILES += uart_init.c uart_intr.c cc2430_rf_intr.c dma_intr.c adc.c CONTIKI_SOURCEFILES += uart_intr.c cc2430_rf_intr.c dma_intr.c
CONTIKI_SOURCEFILES += watchdog-cc2430.c rtimer-arch.c
CONTIKI_ASMFILES += CONTIKI_ASMFILES +=
CONTIKI_ASMOBJECTFILES = ${addprefix $(OBJECTDIR)/,$(CONTIKI_ASMFILES:.S=.o)} CONTIKI_ASMOBJECTFILES = $(addprefix $(OBJECTDIR)/,$(CONTIKI_ASMFILES:.S=.rel))
CONTIKI_CASMOBJECTFILES = ${addprefix $(OBJECTDIR)/,$(CONTIKI_CASMFILES:.cS=.o)} CONTIKI_CASMOBJECTFILES = $(addprefix $(OBJECTDIR)/, \
$(CONTIKI_CASMFILES:.cS=.rel))
CONTIKI_PLATFORM_DIRS = $(PLATFORM_APPDIRS) \ CONTIKI_PLATFORM_DIRS = $(PLATFORM_APPDIRS) \
${addprefix $(CONTIKI)/platform/$(TARGET)/, $(CONTIKI_TARGET_DIRS)} $(addprefix $(CONTIKI)/platform/$(TARGET)/, $(CONTIKI_TARGET_DIRS))
CONTIKI_CPU_DIRS_LIST = ${addprefix $(CONTIKI_CPU)/, \ CONTIKI_CPU_DIRS_LIST = $(addprefix $(CONTIKI_CPU)/, \
$(CONTIKI_CPU_DIRS)} $(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 ### Compilation rules
SEGMENT_RULE_FILES = $(foreach dir, . $(CONTIKI_PLATFORM_DIRS) \
$(CONTIKI_CPU_DIRS_LIST), $(wildcard $(dir)/segment.rules) )
SEGMENT_RULE_FILES = ${foreach dir, ${CONTIKI_PLATFORM_DIRS} ${CONTIKI_CPU_DIRS_LIST}, ${wildcard $(dir)/segment.rules} } $(SEGMENT_RULES): $(SEGMENT_RULE_FILES)
${OBJECTDIR}/segment.rules: ${SEGMENT_RULE_FILES} cat $(SEGMENT_RULE_FILES) | \
echo ${SEGMENT_RULE_FILES} sed -e 's/#.*$$//' -e 's/^\s*//' -e '/^$$/d' > $@
cat ${SEGMENT_RULE_FILES} > $@
CUSTOM_RULE_LINK=1
CUSTOM_RULE_C_TO_OBJECTDIR_O=1 CUSTOM_RULE_C_TO_OBJECTDIR_O=1
CUSTOM_RULE_ALLOBJS_TO_TARGETLIB=1 CUSTOM_RULE_ALLOBJS_TO_TARGETLIB=1
ifdef CUSTOM_RULE_C_TO_OBJECTDIR_O $(OBJECTDIR)/%.rel: %.c $(SEGMENT_RULES)
ifeq ($(HAVE_BANKING),1) $(CC) $(call c_seg,$<,$@) $(CFLAGS) -c $< -o $@ -Wp,-MMD,$(@:.rel=.d),-MQ,$@
$(OBJECTDIR)/%.o: %.c ${OBJECTDIR}/segment.rules @$(FINALIZE_SDCC_DEPENDENCY)
@echo "Compile:"$<" to segment " $(call code_segment,$<)
$(CC) $(CFLAGS) -MM -c $< > $(@:.o=.d)
$(CC) $(call code_segment,$<) $(CFLAGS) -c $< -o $@
@$(FINALIZE_DEPENDENCY)
else
$(OBJECTDIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(CC) $(CFLAGS) -MM -c $< > $(@:.o=.d)
@$(FINALIZE_DEPENDENCY)
endif
endif
$(OBJECTDIR)/%.rel: $(OBJECTDIR)/%.o $(OBJECTDIR)/%.rel: %.cS
cp $< $@
ifdef CUSTOM_RULE_CS_TO_OBJECTDIR_O
$(OBJECTDIR)/%.o: %.cS
cp $< $(OBJECTDIR)/$*.c cp $< $(OBJECTDIR)/$*.c
$(CC) $(CFLAGS) -E $(OBJECTDIR)/$*.c > $(OBJECTDIR)/tmp $(CC) $(CFLAGS) -E $(OBJECTDIR)/$*.c > $(OBJECTDIR)/tmp
perl -pe "s/^#(.*)/;$$1/" $(OBJECTDIR)/tmp > $(OBJECTDIR)/$*.S perl -pe "s/^#(.*)/;$$1/" $(OBJECTDIR)/tmp > $(OBJECTDIR)/$*.S
$(AS) $(ASFLAGS) -o $@ $(OBJECTDIR)/$*.S $(AS) $(ASFLAGS) -o $@ $(OBJECTDIR)/$*.S
rm -f $(OBJECTDIR)/tmp rm -f $(OBJECTDIR)/tmp
endif
#CUSTOM_RULE_ALLOBJS_TO_TARGETLIB contiki-$(TARGET).lib: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) \
contiki-$(TARGET).lib: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) $(CONTIKI_ASMOBJECTFILES) $(CONTIKI_CASMOBJECTFILES) $(CONTIKI_ASMOBJECTFILES) $(CONTIKI_CASMOBJECTFILES)
rm -f $@ rm -f $@
for target in $^; do echo $$target >> $@; done for target in $^; do echo $$target >> $@; done
%.$(TARGET): %.ihx %_linear.hex .PRECIOUS: %.$(TARGET) %.hex
# .rel is the object file default suffix under sdcc # build app/example local object files. We need a separate rule so that we can
%.rel: %.co # pass -DAUTOSTART_ENABLE for those files only
mv $< $@ $(OBJECTDIR)/%.app.rel: %.c $(SEGMENT_RULES)
$(CC) $(call c_seg,$<,$@) -DAUTOSTART_ENABLE $(CFLAGS) -c $< -o $@
# .ihx is the sdcc binary output file # .ihx is the sdcc binary output file
.PRECIOUS: %.ihx %.rel %_linear.hex %.ihx: $(OBJECTDIR)/%.app.rel $(CONTIKI_TARGET_MAIN) contiki-$(TARGET).lib
# Automatic bank relocation when building banked code
ifeq ($(HAVE_BANKING),1)
@echo "\nFirst Link"
@echo "==============="
$(CC) $(LDFLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib > /dev/null
@echo "\nBank Allocation"
@echo "==============="
python $(BANK_ALLOC) $(basename $(@F)) $(SEGMENT_RULES) $(OFFSET_FIRMWARE)
@echo "\nFinal Link"
@echo "==============="
endif
$(CC) $(LDFLAGS) $(LD_POST_FLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib > /dev/null
# .ihx is the sdcc binary output file # Pack the hex file for programmers which dislike SDCC output hex format
%.ihx: %.rel $(CONTIKI_TARGET_MAIN:.o=.rel) contiki-$(TARGET).lib %.hex: %.ihx
$(CC) $(LDFLAGS) -o $@ $(CONTIKI_TARGET_MAIN:.o=.rel) $*.rel -llibsdcc.lib -lcontiki-$(TARGET).lib @echo "\nPack hex file"
@echo "==============="
%_linear.hex: %.ihx ifeq ($(HAVE_BANKING),1)
$(CONTIKI)/cpu/cc2430/converter/converter -f $< $@ srec_cat -disable_sequence_warnings $< -intel -crop 0x10000 0x1FFFF -offset -0x10000 -o bank1.hex -intel
srec_cat -disable_sequence_warnings $< -intel -crop 0x20000 0x2FFFF -offset -0x18000 -o bank2.hex -intel
# Force the compilation of %.$(TARGET) to compile the %.ihx file. srec_cat -disable_sequence_warnings $< -intel -crop 0x30000 0x3FFFF -offset -0x20000 -o bank3.hex -intel
%.$(TARGET): %.ihx %_linear.hex srec_cat -disable_sequence_warnings $< -intel -crop 0x00000 0x0FFFF -o home.ihx -intel
@ srec_cat home.ihx -intel bank1.hex -intel bank2.hex -intel bank3.hex -intel -o $@ -intel
rm -f home.ihx bank1.hex bank2.hex bank3.hex
else
$(PACKIHX) $< > $@
endif

228
cpu/cc2430/bank-alloc.py Normal file
View file

@ -0,0 +1,228 @@
#!/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 - <oikonomou@users.sourceforge.net>
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_sensinode[^ ]+\.')
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 ['BANK1', 'BANK2', 'BANK3', 'HOME']:
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 == 'HOME':
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]
bins = {
'HOME': [0, 32768],
'BANK1': [0, 32768],
'BANK2': [0, 32768],
'BANK3': [0, 30720]
}
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]) + \
', BANK1=' + str(bins['BANK1'][0]) + ', BANK2=' + str(bins['BANK2'][0]) + \
', BANK3=' + str(bins['BANK3'][0])
# 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']:
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])

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -13,7 +13,7 @@ void usage(char *prg_name)
{ {
printf("\nUsage: %s -f ihex file\n", prg_name); printf("\nUsage: %s -f ihex file\n", prg_name);
printf("General options:\n"); printf("General options:\n");
printf(" -V/--version Get converter version\n"); printf(" -v/--version Get converter version\n");
} }
conf_opts_t conf_opts; conf_opts_t conf_opts;
@ -22,11 +22,11 @@ static int option_index = 0;
int do_exit = 0; int do_exit = 0;
#define OPTIONS_STRING "Vhf:" #define OPTIONS_STRING "vhf:"
/* long option list */ /* long option list */
static struct option long_options[] = static struct option long_options[] =
{ {
{"version", 0, NULL, 'V'}, {"version", 0, NULL, 'v'},
{"file", 1, NULL, 'f'}, {"file", 1, NULL, 'f'},
{"help", 0, NULL, 'h'}, {"help", 0, NULL, 'h'},
{0, 0, 0, 0} {0, 0, 0, 0}
@ -43,7 +43,7 @@ int parse_opts(int count, char* param[])
{ {
switch(opt) switch(opt)
{ {
case 'V': case 'v':
conf_opts.target_type = VERSION; conf_opts.target_type = VERSION;
break; break;
@ -73,6 +73,7 @@ int main(int argc, char *argv[])
conf_opts.target_type = 0; conf_opts.target_type = 0;
printf("Sensinode hex file converter "CONVERTER_VERSION "\n");
if ( (argc < 1) || (error = parse_opts(argc, argv)) ) if ( (argc < 1) || (error = parse_opts(argc, argv)) )
{ {
usage(argv[0]); usage(argv[0]);
@ -133,14 +134,14 @@ int main(int argc, char *argv[])
} }
else if (memcmp(&buffer[7], "01", 2) == 0) else if (memcmp(&buffer[7], "01", 2) == 0)
{ /*end file*/ { /*end file*/
printf("\nFile read complete.\n"); printf("File read complete.\n");
break; break;
} }
else if (memcmp(&buffer[7], "04", 2) == 0) else if (memcmp(&buffer[7], "04", 2) == 0)
{ {
sscanf((char *)&(buffer[3]),"%4hx", &addr); sscanf((char *)&(buffer[3]),"%4hx", &addr);
sscanf((char *)&(buffer[9]),"%4lx", &ext_addr); sscanf((char *)&(buffer[9]),"%4lx", &ext_addr);
printf("\rExtended page address: 0x%8.8lX\r", ext_addr*0x8000 ); /*printf("Extended page address: 0x%8.8lX\n", ext_addr*0x8000 );*/
if (ext_addr >= 0x0002) sdcc_file = 1; if (ext_addr >= 0x0002) sdcc_file = 1;
@ -166,7 +167,7 @@ int main(int argc, char *argv[])
*ptr = 0; *ptr = 0;
} }
} }
strcat(conf_opts.ihex_file, "_linear.hex"); strcat(conf_opts.ihex_file, ".hex");
printf("Output file: %s.\n", conf_opts.ihex_file); printf("Output file: %s.\n", conf_opts.ihex_file);
ihex = fopen(conf_opts.ihex_file, "wb"); ihex = fopen(conf_opts.ihex_file, "wb");
ext_addr=0; ext_addr=0;
@ -180,7 +181,7 @@ int main(int argc, char *argv[])
addr = (i & 0x1F) * 2048; addr = (i & 0x1F) * 2048;
if ( ((i / 32) * 0x10000) != ext_addr) if ( ((i / 32) * 0x10000) != ext_addr)
{ /*write out ext addr*/ { /*write out ext addr*/
printf("Ext: %4.4X\n", ((i / 32) * 0x10000)); /*printf("Ext: %4.4X\n", ((i / 32) * 0x10000));*/
ext_addr = (i / 32) * 0x10000; ext_addr = (i / 32) * 0x10000;
fprintf(ihex, ":02000004%4.4X%2.2X\r\n", fprintf(ihex, ":02000004%4.4X%2.2X\r\n",
(int)(ext_addr>>16), (int)(0xFA-(ext_addr>>16))); (int)(ext_addr>>16), (int)(0xFA-(ext_addr>>16)));
@ -188,7 +189,7 @@ int main(int argc, char *argv[])
if (page_table[i] != 0) if (page_table[i] != 0)
{ {
printf("%4.4X", addr & 0xF800); /*printf("%4.4X", addr & 0xF800);*/
for (j=0; j<2048; j++) for (j=0; j<2048; j++)
{ {
addr =(i & 0x1F) * 2048 + j; addr =(i & 0x1F) * 2048 + j;
@ -208,8 +209,10 @@ int main(int argc, char *argv[])
} }
} }
} }
/*
if ((i & 0x07) == 0x07) printf("\n"); if ((i & 0x07) == 0x07) printf("\n");
else printf(" "); else printf(" ");
*/
} }
fprintf(ihex, ":00000001FF\r\n"); fprintf(ihex, ":00000001FF\r\n");
printf("Write complete.\n"); printf("Write complete.\n");
@ -220,9 +223,5 @@ int main(int argc, char *argv[])
{ {
usage(argv[0]); usage(argv[0]);
} }
else
{
printf("\nSensinode hex file converter "CONVERTER_VERSION "\n");
}
return error; return error;
} }

View file

@ -1,7 +1,7 @@
#ifndef CONVERTER_H #ifndef CONVERTER_H
#define CONVERTER_H #define CONVERTER_H
#define CONVERTER_VERSION "v1.3" #define CONVERTER_VERSION "v1.4"
typedef struct { typedef struct {
int target_type; int target_type;

Binary file not shown.

Binary file not shown.

View file

@ -1,70 +0,0 @@
/**
* \file
* ADC functions
* \author
* Anthony "Asterisk" Ambuehl
*
* ADC initialization routine, trigger and result conversion routines.
*
*/
#include <stdio.h>
#include "banked.h"
#include "contiki.h"
#include "sys/clock.h"
#include "cc2430_sfr.h"
#include "dev/adc.h"
#include "dev/dma.h"
#ifdef HAVE_DMA
xDMAHandle adc_dma=0xff;
unsigned int *adc_dma_dest;
#endif
/*---------------------------------------------------------------------------*/
void adc_init(void) __banked
{
unsigned char jj;
while (!SLEEP&(HFRC_STB)) {}
/* power both 32MHz crystal and 15MHz RC */
SLEEP &= ~(OSC_PD);
/* printf("SLEEP 1 %x\n",SLEEP); */
/* then wait for it to stabilize */
while (!SLEEP&(XOSC_STB)) {}
/* printf("SLEEP 2 %x\n",SLEEP); */
/* then wait 64uS more */
clock_delay(150);
/* switch to 32MHz clock */
/* printf("switch to 32MHz %x\n",CLKCON); */
CLKCON &= ~(OSC);
/* printf("switched to 32MHz %x\n",CLKCON); */
/* power down 15MHz RC clock */
SLEEP |= OSC_PD;
/* printf("pwr down hfrc\n",SLEEP); */
#ifdef HAVE_DMA
/* preconfigure adc_dma before calling adc_init if a different dma type is desired. */
if (adc_dma==0xff) {
dma_init();
/* config DMA channel to copy results to single location */
adc_dma=dma_config2(ADC_DMA_CONFIG_CHANNEL, &ADC_SHADOW, DMA_NOINC, adc_dma_dest, DMA_NOINC, 1, 1, DMA_VLEN_LEN, DMA_RPT, DMA_T_ADC_CHALL, 0);
}
#endif
}
/* single sample trigger */
void adc_single_shot(void) __banked
{
ADCCON1 |= 0x73;
}
/* convert adc results */
int16_t adc_convert_result(int16_t data) __banked {
data = (0xfffc&data)>>2;
return data;
}
/* read/convert last conversion result */
int16_t adc_get_last_conv() __banked {
int16_t result;
result = (ADCH<<8)|(ADCL);
result = (0xfffc&result)>>2;
return result;
}

View file

@ -1,41 +0,0 @@
/**
* \file
* Header file for ADC.
* \author
* Anthony "Asterisk" Ambuehl
*
*/
#ifndef __ADC_H
#define __ADC_H
#define ADC_DMA_CONFIG_CHANNEL 1
#define ADC_CHANNELS 8
#include "cc2430_sfr.h"
#include "dma.h"
#include "banked.h"
typedef struct adc_result
{
uint16_t adc:14;
uint16_t unused:2;
} adc_result_t;
typedef enum adc_stsel_t
{
EXT = 0, /* externally triggered by P2_0 */
CONTINUOUS = 1, /* continuous full speed conversion */
TIMER1 = 2, /* Timer 1 channel 0 compare event */
ST = 3 /* ADCCON1.ST = 1 */
} adc_stsel_t;
extern void adc_init(void) __banked;
extern void adc_single_shot(void) __banked;
extern int16_t adc_convert_result(int16_t ptr) __banked;
extern int16_t adc_get_last_conv() __banked;
extern void adc_dma_callback(void) __banked;
#ifdef HAVE_DMA
extern xDMAHandle adc_dma;
extern unsigned int *adc_dma_dest;
#endif
#endif /*__ADC_H*/

View file

@ -1,40 +0,0 @@
/**
* \file
*
* SDCC bank switching macro define file
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
* SDCC (small device cross compiler) has built-in support for bank switching using predefined macros __banked.
* To avoid compilation issues on other compilers include this file which will replace __banked with the empty string on unsupported compilers.
*
* In addition, the file can add the codeseg pragma to place code into specific banks, if specific macro is set.
* However the same result can be achieved by using the segment.rules file.
*
*/
#ifndef __BANKED_H
#ifdef SDCC
#ifndef HAVE_SDCC_BANKING
#define __banked
#else
#ifdef BANKED_IN_HOME
#pragma codeseg HOME
#endif
#ifdef BANKED_IN_BANK1
#pragma codeseg BANK1
#endif
#ifdef BANKED_IN_BANK2
#pragma codeseg BANK2
#endif
#ifdef BANKED_IN_BANK3
#pragma codeseg BANK3
#endif
#endif
#else
#define __banked
#endif
#endif /*__BANKED_H*/

View file

@ -38,14 +38,14 @@
* Adam Dunkels <adam@sics.se> * Adam Dunkels <adam@sics.se>
*/ */
#include "banked.h"
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
#include "dev/bus.h" #include "dev/bus.h"
#include "sys/clock.h" #include "sys/clock.h"
#include "contiki-conf.h"
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
bus_init (void) __banked bus_init (void)
{ {
CLKCON = (0x00 | OSC32K); /* 32k internal */ CLKCON = (0x00 | OSC32K); /* 32k internal */
while(CLKCON != (0x00 | OSC32K)); while(CLKCON != (0x00 | OSC32K));
@ -65,8 +65,9 @@ bus_init (void) __banked
* \param buffer buffer to store data * \param buffer buffer to store data
* \param size number of bytes to read * \param size number of bytes to read
*/ */
#if !SHORTCUTS_CONF_FLASH_READ
void void
flash_read (uint8_t *buf, uint32_t address, uint8_t size) __banked flash_read(uint8_t *buf, uint32_t address, uint8_t size)
{ {
buf; /*dptr0*/ buf; /*dptr0*/
address; /*stack-6*/ address; /*stack-6*/
@ -130,4 +131,5 @@ lp1:
ENABLE_INTERRUPTS(); ENABLE_INTERRUPTS();
DPL1 = *buf++; DPL1 = *buf++;
} }
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -44,11 +44,14 @@
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
#include "8051def.h" #include "8051def.h"
#include "contiki-conf.h"
#define inline #define inline
void bus_init(void) __banked; void bus_init(void);
void flash_read(uint8_t *buf, uint32_t address, uint8_t size) __banked; #if !SHORTCUTS_CONF_FLASH_READ
void cc2430_clock_ISR( void ) __interrupt (ST_VECTOR); void flash_read(uint8_t *buf, uint32_t address, uint8_t size);
#endif
void clock_ISR( void ) __interrupt (ST_VECTOR);
#endif /* __BUS_H__ */ #endif /* __BUS_H__ */

File diff suppressed because it is too large Load diff

View file

@ -8,11 +8,12 @@
#ifndef __CC2430_RF_H__ #ifndef __CC2430_RF_H__
#define __CC2430_RF_H__ #define __CC2430_RF_H__
#include "banked.h"
#include "contiki.h" #include "contiki.h"
#include "dev/radio.h" #include "dev/radio.h"
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
#if HAVE_RF_DMA
#include "dev/dma.h" #include "dev/dma.h"
#endif
/* Constants */ /* Constants */
typedef enum rf_address_mode_t typedef enum rf_address_mode_t
@ -26,20 +27,20 @@ typedef enum rf_address_mode_t
}rf_address_mode_t; }rf_address_mode_t;
/*CSP command set*/ /*CSP command set*/
#define SSTOP 0xDF #define SSTOP 0xDF
/*this is not a real command but a way of having rf_command /*this is not a real command but a way of having rf_command
wait until the script is done*/ wait until the script is done*/
#define SSTART 0xDE #define SSTART 0xDE
#define SNOP 0xC0 #define SNOP 0xC0
#define STXCALN 0xC1 #define STXCALN 0xC1
#define SRXON 0xC2 #define SRXON 0xC2
#define STXON 0xC3 #define STXON 0xC3
#define STXONCCA 0xC4 #define STXONCCA 0xC4
#define SRFOFF 0xC5 #define SRFOFF 0xC5
#define SFLUSHRX 0xC6 #define SFLUSHRX 0xC6
#define SFLUSHTX 0xC7 #define SFLUSHTX 0xC7
#define SACK 0xC8 #define SACK 0xC8
#define SACKPEND 0xC9 #define SACKPEND 0xC9
#define ISTXCALN 0xE1 #define ISTXCALN 0xE1
@ -49,7 +50,7 @@ typedef enum rf_address_mode_t
#define ISRFOFF 0xE5 #define ISRFOFF 0xE5
#define ISFLUSHRX 0xE6 #define ISFLUSHRX 0xE6
#define ISFLUSHTX 0xE7 #define ISFLUSHTX 0xE7
#define ISACK 0xE8 #define ISACK 0xE8
#define ISACKPEND 0xE9 #define ISACKPEND 0xE9
#define ISSTOP 0xFF #define ISSTOP 0xFF
@ -60,39 +61,31 @@ typedef enum rf_address_mode_t
#define CC2430_MAX_PACKET_LEN 127 #define CC2430_MAX_PACKET_LEN 127
#define CC2430_MIN_PACKET_LEN 4 #define CC2430_MIN_PACKET_LEN 4
#define CC2430_CCA_CLEAR 1
#define CC2430_CCA_BUSY 0
#ifdef CC2430_CONF_RFERR_INTERRUPT
#define CC2430_RFERR_INTERRUPT CC2430_CONF_RFERR_INTERRUPT
#else
#define CC2430_RFERR_INTERRUPT 0
#endif
extern const struct radio_driver cc2430_rf_driver; extern const struct radio_driver cc2430_rf_driver;
/* radio_driver functions */ void cc2430_rf_command(uint8_t command);
void cc2430_rf_set_receiver(void (* recv)(const struct radio_driver *));
int cc2430_rf_on(void);
int cc2430_rf_off(void);
int cc2430_rf_read(void *buf, unsigned short bufsize);
int cc2430_rf_read_banked (void *buf, unsigned short bufsize) __banked;
int cc2430_rf_send(void *data, unsigned short len);
int cc2430_rf_send_b (void *data, unsigned short len) __banked;
extern unsigned short cc2430_rf_payload_len;
extern void *cc2430_rf_payload;
/* RF driver functions */
void cc2430_rf_init(void) __banked;
void cc2430_rf_command(uint8_t command) __banked;
int8_t cc2430_rf_channel_set(uint8_t channel); int8_t cc2430_rf_channel_set(uint8_t channel);
int8_t cc2430_rf_power_set(uint8_t new_power); uint8_t cc2430_rf_power_set(uint8_t new_power);
int8_t cc2430_rf_rx_enable(void) __banked;
int8_t cc2430_rf_rx_disable(void) __banked;
int8_t cc2430_rf_tx_enable(void);
int8_t cc2430_rf_address_decoder_mode(rf_address_mode_t mode);
int8_t cc2430_rf_analyze_rssi(void);
int8_t cc2430_rf_cca_check(uint8_t backoff_count, uint8_t slotted);
void cc2430_rf_send_ack(uint8_t pending);
void cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr); void cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr);
#if !SHORTCUTS_CONF_NETSTACK
extern void cc2430_rf_ISR( void ) __interrupt (RF_VECTOR); extern void cc2430_rf_ISR( void ) __interrupt (RF_VECTOR);
#endif
#if CC2430_RFERR_INTERRUPT
extern void cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR); extern void cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR);
#endif
#ifdef HAVE_RF_DMA #ifdef HAVE_RF_DMA
void rf_dma_callback_isr(void); void rf_dma_callback_isr(void);
#endif #endif
#endif /* __CC2430_RF_H__ */ #endif /* __CC2430_RF_H__ */

View file

@ -2,11 +2,12 @@
* \file * \file
* CC2430 RF driver * CC2430 RF driver
* \author * \author
* Zach Shelby <zach@sensinode.com> * Zach Shelby <zach@sensinode.com> (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net>
* (recent updates for the contiki cc2430 port)
* *
* Non-bankable code for cc2430 rf driver. * Non-bankable code for cc2430 rf driver.
* Interrupt routine and code called through function pointers * Interrupt routines must be placed into the HOME bank.
* must be placed into the HOME bank.
* *
*/ */
@ -23,6 +24,7 @@
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include "net/rime/rimestats.h" #include "net/rime/rimestats.h"
#include "net/netstack.h"
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
#define PRINTF(...) printf(__VA_ARGS__) #define PRINTF(...) printf(__VA_ARGS__)
@ -46,10 +48,9 @@
uint8_t rf_error = 0; uint8_t rf_error = 0;
#endif #endif
PROCESS_NAME(cc2430_rf_process);
/*---------------------------------------------------------------------------*/ #if !SHORTCUTS_CONF_NETSTACK
PROCESS(cc2430_rf_process, "CC2430 RF driver");
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /**
* RF interrupt service routine. * RF interrupt service routine.
@ -59,29 +60,27 @@ void
cc2430_rf_ISR( void ) __interrupt (RF_VECTOR) cc2430_rf_ISR( void ) __interrupt (RF_VECTOR)
{ {
EA = 0; EA = 0;
if(RFIF & IRQ_TXDONE) { ENERGEST_ON(ENERGEST_TYPE_IRQ);
RF_TX_LED_OFF(); /*
RFIF &= ~IRQ_TXDONE; * We only vector here if RFSTATUS.FIFOP goes high.
cc2430_rf_command(ISFLUSHTX); * Just double check the flag.
} */
if(RFIF & IRQ_FIFOP) { if(RFIF & IRQ_FIFOP) {
if(RFSTATUS & FIFO) {
RF_RX_LED_ON(); RF_RX_LED_ON();
/* Poll the RF process which calls cc2430_rf_read() */ /* Poll the RF process which calls cc2430_rf_read() */
process_poll(&cc2430_rf_process); process_poll(&cc2430_rf_process);
} else {
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
RFIF &= ~IRQ_FIFOP;
}
} }
S1CON &= ~(RFIF_0 | RFIF_1); S1CON &= ~(RFIF_0 | RFIF_1);
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
EA = 1; EA = 1;
} }
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if CC2430_RFERR_INTERRUPT
/** /**
* RF error interrupt service routine. * RF error interrupt service routine.
* * Turned off by default, can be turned on in contiki-conf.h
*/ */
void void
cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR) cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR)
@ -99,57 +98,5 @@ cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR)
RF_TX_LED_OFF(); RF_TX_LED_OFF();
EA = 1; EA = 1;
} }
#endif
void (* receiver_callback)(const struct radio_driver *);
void
cc2430_rf_set_receiver(void (* recv)(const struct radio_driver *))
{
receiver_callback = recv;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/*
* non-banked functions called through function pointers then call banked code
*/
int
cc2430_rf_off(void)
{
return cc2430_rf_rx_disable();
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_on(void)
{
return cc2430_rf_rx_enable();
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_send(void *payload, unsigned short payload_len)
{
return cc2430_rf_send_b(payload, payload_len);
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_read(void *buf, unsigned short bufsize)
{
return cc2430_rf_read_banked(buf, bufsize);
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(cc2430_rf_process, ev, data)
{
PROCESS_BEGIN();
while(1) {
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
if(receiver_callback != NULL) {
PRINTF("cc2430_rf_process: calling receiver callback\n");
receiver_callback(&cc2430_rf_driver);
} else {
PRINTF("cc2430_rf_process: no receiver callback\n");
cc2430_rf_command(ISFLUSHRX);
}
}
PROCESS_END();
}

View file

@ -46,20 +46,24 @@
#include "sys/clock.h" #include "sys/clock.h"
#include "sys/etimer.h" #include "sys/etimer.h"
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
#include "sys/energest.h"
/*Sleep timer runs on the 32k RC osc. */ /*Sleep timer runs on the 32k RC osc. */
/* One clock tick is 7.8 ms */ /* One clock tick is 7.8 ms */
#define TICK_VAL (32768/128) #define TICK_VAL (32768/128) /* 256 */
#define MAX_TICKS (~((clock_time_t)0) / 2)
/* Used in sleep timer interrupt for calculating the next interrupt time */ /* Used in sleep timer interrupt for calculating the next interrupt time */
static unsigned long timer_value; static unsigned long timer_value;
/*starts calculating the ticks right after reset*/ /*starts calculating the ticks right after reset*/
static volatile clock_time_t count = 0; #if CLOCK_CONF_ACCURATE
static volatile __data clock_time_t count = 0;
#else
volatile __data clock_time_t count = 0;
/* accurate clock is stack hungry */
volatile __bit sleep_flag;
#endif
/*calculates seconds*/ /*calculates seconds*/
static volatile clock_time_t seconds = 0; static volatile __data clock_time_t seconds = 0;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /**
@ -103,7 +107,7 @@ clock_seconds(void)
void void
clock_init(void) clock_init(void)
{ {
CLKCON = OSC32K | TICKSPD2|TICKSPD1|TICKSPD0; /*tickspeed 250 kHz*/ CLKCON = OSC32K | TICKSPD2|TICKSPD1; /*tickspeed 500 kHz for timers[1-4]*/
/*Initialize tick value*/ /*Initialize tick value*/
timer_value = ST0; /*sleep timer 0. low bits [7:0]*/ timer_value = ST0; /*sleep timer 0. low bits [7:0]*/
@ -118,9 +122,18 @@ clock_init(void)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
cc2430_clock_ISR( void ) __interrupt (ST_VECTOR) clock_ISR( void ) __interrupt (ST_VECTOR)
{ {
IEN0_EA = 0; /*interrupt disable*/ IEN0_EA = 0; /*interrupt disable*/
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
*/
SLEEP &= 0xFC;
/* When using the cooperative scheduler the timer 2 ISR is only /* When using the cooperative scheduler the timer 2 ISR is only
required to increment the RTOS tick count. */ required to increment the RTOS tick count. */
@ -148,12 +161,17 @@ cc2430_clock_ISR( void ) __interrupt (ST_VECTOR)
++seconds; ++seconds;
} }
#if CLOCK_CONF_ACCURATE
if(etimer_pending() && if(etimer_pending() &&
(etimer_next_expiration_time() - count - 1) > MAX_TICKS) { /*core/sys/etimer.c*/ (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { /*core/sys/etimer.c*/
etimer_request_poll(); etimer_request_poll();
} }
#else
sleep_flag = 1;
#endif
IRCON &= ~STIF; /*IRCON.STIF=Sleep timer interrupt flag. This flag called this interrupt func, now reset it*/ IRCON &= ~STIF; /*IRCON.STIF=Sleep timer interrupt flag. This flag called this interrupt func, now reset it*/
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
IEN0_EA = 1; /*interrupt enable*/ IEN0_EA = 1; /*interrupt enable*/
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -1,216 +1,69 @@
/** /**
* \file * \file
* DMA driver * Driver for the cc2430 DMA controller. Can be assigned to any bank
*
* \author * \author
* Original: Martti Huttunen <martti@sensinode.com> * Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com> * Port: Zach Shelby <zach@sensinode.com>
* Further Modifications:
* George Oikonomou <oikonomou@users.sourceforge.net>
* *
* bankable DMA functions
*/ */
#include <stdio.h>
#include "contiki.h" #include "contiki.h"
#include "banked.h"
#include "dev/dma.h" #include "dev/dma.h"
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
dma_config_t dma_conf[4]; #if DMA_ON
struct process * dma_callback[4]; struct dma_config dma_conf[DMA_CHANNEL_COUNT]; /* DMA Descriptors */
struct process * dma_callback[DMA_CHANNEL_COUNT];
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
dma_init(void) __banked dma_init(void)
{ {
uint16_t tmp_ptr; uint16_t tmp_ptr;
memset(dma_conf, 0, 4*sizeof(dma_config_t));
for(tmp_ptr = 0; tmp_ptr < 4; 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; dma_callback[tmp_ptr] = 0;
} }
tmp_ptr = (uint16_t) &(dma_conf[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; DMA1CFGH = tmp_ptr >> 8;
DMA1CFGL = tmp_ptr; DMA1CFGL = tmp_ptr;
IEN1_DMAIE = 1; /*enable DMA interrupts*/ #endif
}
/*---------------------------------------------------------------------------*/
#ifdef HAVE_DMA
/**
* Configure a DMA channel except word mode.
*
* \param channel channel ID;
* \param src source address;
* \param src_inc source increment mode;
* \param dst dest address;
* \param dst_inc dest increment mode;
* \param length maximum length;
* \param vlen_mode variable length mode;
* \param t_mode DMA transfer mode;
* \param trigger DMA trigger;
* \param proc process that is upon interrupt;
*
* \return Handle to DMA channel
* \return 0 invalid channel
*/
/* IMPLEMENTED dma_config as macro to reduce stack/code space
xDMAHandle
dma_config(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
uint16_t length, dma_vlen_t vlen_mode, dma_type_t t_mode, dma_trigger_t trigger,
struct process * proc) __banked
{
return dma_config2(channel,src,src_inc, dst, dst_inc, length, 0, vlen_mode, t_mode, trigger, proc);
}
*/
/*---------------------------------------------------------------------------*/
/**
* Configure a DMA channel.
*
* \param channel channel ID;
* \param src source address;
* \param src_inc source increment mode;
* \param dst dest address;
* \param dst_inc dest increment mode;
* \param length maximum length;
* \param word_mode set to 1 for 16-bits per transfer;
* \param vlen_mode variable length mode;
* \param t_mode DMA transfer mode;
* \param trigger DMA trigger;
* \param proc process that is upon interrupt;
*
* \return Handle to DMA channel
* \return 0 invalid channel
*/
xDMAHandle
dma_config2(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
uint16_t length, uint8_t word_mode, dma_vlen_t vlen_mode, dma_type_t t_mode, dma_trigger_t trigger,
struct process * proc) __banked
{
unsigned char jj;
if((!channel) || (channel > 4)) {
return 0;
}
DMAIRQ &= ~(1 << channel); IEN1_DMAIE = 1; /* Enable DMA interrupts */
channel--;
dma_conf[channel].src_h = ((uint16_t) src) >> 8;
dma_conf[channel].src_l = ((uint16_t) src);
dma_conf[channel].dst_h = ((uint16_t) dst) >> 8;
dma_conf[channel].dst_l = ((uint16_t) dst);
dma_conf[channel].len_h = vlen_mode + (length >> 8);
dma_conf[channel].len_l = length;
dma_conf[channel].t_mode = ((word_mode&0x1)<<7) | (t_mode << 5) | trigger;
dma_conf[channel].addr_mode = (src_inc << 6) + (dst_inc << 4) + 2; /*DMA has priority*/
/*Callback is defined*/
if(proc) {
dma_conf[channel].addr_mode |= 8; /*set IRQMASK*/
IEN1_DMAIE = 1; /*enable DMA interrupts*/
}
dma_callback[channel] = proc;
return (xDMAHandle)channel + 1;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /*
* Arm a DMA channel. * Associate process p with DMA channel c. When a transfer on that channel
* * completes, the ISR will poll this process.
* \param channel channel handle;
*
* \return pdTRUE
* \return pdFALSE semaphore creation failed
*/ */
uint8_t
dma_arm(xDMAHandle channel) __banked
{
uint8_t ch_id = ((uint8_t)channel);
if(!ch_id || (ch_id > 4)) {
return 0;
}
DMAARM |= (1 << ch_id);
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* Stop a DMA channel.
*
* \param channel channel handle;
*
* \return pdTRUE
* \return pdFALSE semaphore creation failed
*/
uint8_t
dma_abort(xDMAHandle channel) __banked
{
uint8_t ch_id = ((uint8_t) channel);
if(!ch_id || (ch_id > 4)) {
return 0;
}
DMAARM = 0x80 + (1 << ch_id); /*ABORT + channel bit*/
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* Trigger a DMA channel.
*
* \param channel channel handle;
*
* \return pdTRUE
* \return pdFALSE semaphore creation failed
*/
uint8_t
dma_trigger(xDMAHandle channel) __banked
{
uint8_t ch_id = ((uint8_t) channel);
if(!ch_id || (ch_id > 4)) {
return 0;
}
DMAREQ |= (1 << ch_id);
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* Get DMA state.
*
* \param channel channel handle;
*
* \return pdTRUE active
* \return pdFALSE not active
*/
uint8_t
dma_state(xDMAHandle channel) __banked
{
uint8_t ch_id = ((uint8_t)channel);
if(!ch_id || (ch_id > 4)) {
return 0;
}
if((DMAIRQ &(1 << ch_id)) == 0) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
void void
dma_config_print(xDMAHandle channel) __banked dma_associate_process(struct process * p, uint8_t c)
{ {
uint8_t ch_id = channel - 1; if((!c) || (c >= DMA_CHANNEL_COUNT)) {
if(ch_id > 4) {
return; return;
} }
printf("DMA channel %d @ %x %x ", ch_id, (uint16_t) &(dma_conf[ch_id]) >> 8, (uint16_t) &(dma_conf[ch_id]) & 0xFF); if(p) {
{ dma_conf[c].inc_prio |= 8; /* Enable interrupt generation */
uint8_t i; IEN1_DMAIE = 1; /* Make sure DMA interrupts are acknowledged */
uint8_t *ptr = (uint8_t *)&(dma_conf[ch_id]);
for(i = 0; i< 8; i++) {
if(i != 0) {
printf(":%02x", *ptr++);
}
}
printf("\n");
} }
dma_callback[c] = p;
} }
/*---------------------------------------------------------------------------*/
#endif #endif

View file

@ -1,122 +1,148 @@
/** /**
* \file * \file
* DMA driver header * Header file for the cc2430 DMA controller
*
* \author * \author
* Original: Martti Huttunen <martti@sensinode.com> * Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com> * Port: Zach Shelby <zach@sensinode.com>
* Further Modifications:
* George Oikonomou <oikonomou@users.sourceforge.net>
*/ */
#ifndef __DMA_H #ifndef __DMA_H
#define __DMA_H #define __DMA_H
#include "banked.h"
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
/** DMA triggers */ /* DMA triggers */
typedef enum dma_trigger_t #define DMA_T_NONE 0 /* None, DMAREQ.DMAREQx bits start transfer */
{ #define DMA_T_PREV 1 /* completion of previous channel */
DMA_T_NONE=0, /*!<DMA No trigger, setting DMAREQ.DMAREQx bit starts transfer*/ #define DMA_T_T1_CH0 2 /* Timer 1, compare, channel 0 */
DMA_T_PREV=1, /*!<DMA DMA channel is triggered by completion of previous channel*/ #define DMA_T_T1_CH1 3 /* Timer 1, compare, channel 1 */
DMA_T_T1_CH0=2, /*!<Timer 1 Timer 1, compare, channel 0*/ #define DMA_T_T1_CH2 4 /* Timer 1, compare, channel 2 */
DMA_T_T1_CH1=3, /*!<Timer 1 Timer 1, compare, channel 1*/ #define DMA_T_T2_COMP 5 /* Timer 2, compare */
DMA_T_T1_CH2=4, /*!<Timer 1 Timer 1, compare, channel 2*/ #define DMA_T_T2_OVFL 6 /* Timer 2, overflow */
DMA_T_T2_COMP=5, /*!<Timer 2 Timer 2, compare*/ #define DMA_T_T3_CH0 7 /* Timer 3, compare, channel 0 */
DMA_T_T2_OVFL=6, /*!<Timer 2 Timer 2, overflow*/ #define DMA_T_T3_CH1 8 /* Timer 3, compare, channel 1 */
DMA_T_T3_CH0=7, /*!<Timer 3 Timer 3, compare, channel 0*/ #define DMA_T_T4_CH0 9 /* Timer 4, compare, channel 0 */
DMA_T_T3_CH1=8, /*!<Timer 3 Timer 3, compare, channel 1*/ #define DMA_T_T4_CH1 10 /* Timer 4, compare, channel 1 */
DMA_T_T4_CH0=9, /*!<Timer 4 Timer 4, compare, channel 0*/ #define DMA_T_ST 11 /* Sleep Timer compare */
DMA_T_T4_CH1=10, /*!<Timer 4 Timer 4, compare, channel 1*/ #define DMA_T_IOC_0 12 /* Port 0 I/O pin input transition */
DMA_T_ST=11, /*!<Sleep Timer Sleep Timer compare*/ #define DMA_T_IOC_1 13 /* Port 1 I/O pin input transition */
DMA_T_IOC_0=12, /*!<IO Controller Port 0 I/O pin input transition*/ #define DMA_T_URX0 14 /* USART0 RX complete */
DMA_T_IOC_1=13, /*!<IO Controller Port 1 I/O pin input transition*/ #define DMA_T_UTX0 15 /* USART0 TX complete */
DMA_T_URX0=14, /*!<USART0 USART0 RX complete*/ #define DMA_T_URX1 16 /* USART1 RX complete */
DMA_T_UTX0=15, /*!<USART0 USART0 TX complete*/ #define DMA_T_UTX1 17 /* USART1 TX complete */
DMA_T_URX1=16, /*!<USART1 USART1 RX complete*/ #define DMA_T_FLASH 18 /* Flash data write complete */
DMA_T_UTX1=17, /*!<USART1 USART1 TX complete*/ #define DMA_T_RADIO 19 /* RF packet byte received/transmit */
DMA_T_FLASH=18, /*!<Flash controller Flash data write complete*/ #define DMA_T_ADC_CHALL 20 /* ADC end of a conversion in a sequence */
DMA_T_RADIO=19, /*!<Radio RF packet byte received/transmit*/ #define DMA_T_ADC_CH11 21 /* ADC end of conversion channel 0 in sequence */
DMA_T_ADC_CHALL=20, /*!<ADC ADC end of a conversion in a sequence, sample ready*/ #define DMA_T_ADC_CH21 22 /* ADC end of conversion channel 1 in sequence */
DMA_T_ADC_CH11=21, /*!<ADC ADC end of conversion channel 0 in sequence, sample ready*/ #define DMA_T_ADC_CH32 23 /* ADC end of conversion channel 2 in sequence */
DMA_T_ADC_CH21=22, /*!<ADC ADC end of conversion channel 1 in sequence, sample ready*/ #define DMA_T_ADC_CH42 24 /* ADC end of conversion channel 3 in sequence */
DMA_T_ADC_CH32=23, /*!<ADC ADC end of conversion channel 2 in sequence, sample ready*/ #define DMA_T_ADC_CH53 25 /* ADC end of conversion channel 4 in sequence */
DMA_T_ADC_CH42=24, /*!<ADC ADC end of conversion channel 3 in sequence, sample ready*/ #define DMA_T_ADC_CH63 26 /* ADC end of conversion channel 5 in sequence */
DMA_T_ADC_CH53=25, /*!<ADC ADC end of conversion channel 4 in sequence, sample ready*/ #define DMA_T_ADC_CH74 27 /* ADC end of conversion channel 6 in sequence */
DMA_T_ADC_CH63=26, /*!<ADC ADC end of conversion channel 5 in sequence, sample ready*/ #define DMA_T_ADC_CH84 28 /* ADC end of conversion channel 7 in sequence */
DMA_T_ADC_CH74=27, /*!<ADC ADC end of conversion channel 6 in sequence, sample ready*/ #define DMA_T_ENC_DW 29 /* AES processor requests download input data */
DMA_T_ADC_CH84=28, /*!<ADC ADC end of conversion channel 7 in sequence, sample ready*/ #define DMA_T_ENC_UP 30 /* AES processor requests upload output data */
DMA_T_ENC_DW=29, /*!<AES AES encryption processor requests download input data*/
DMA_T_ENC_UP=30, /*!<AES AES encryption processor requests upload output data*/
DMA_T_RES=31
}dma_trigger_t;
/** variable DMA length modes */ /* variable DMA length modes (VLEN) */
typedef enum dma_vlen_t #define DMA_VLEN_LEN (0 << 5) /* Use LEN for transfer count*/
{ /*
DMA_VLEN_LEN = (0 << 5),/*!<Use LEN for transfer count*/ * Transfer the number of bytes/words specified by first byte/word + 1
DMA_VLEN_N1 = (1 << 5),/*!<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.*/ * (up to a maximum specified by LEN).
DMA_VLEN_N = (2 << 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.*/ * Thus transfer count excludes length byte/word.
DMA_VLEN_N2 = (3 << 5),/*!<Transfer the number of bytes/words specified by first byte/word + 2 (up to a maximum specified by LEN).*/ */
DMA_VLEN_N3 = (4 << 5),/*!<Transfer the number of bytes/words specified by first byte/word + 3 (up to a maximum specified by LEN).*/ #define DMA_VLEN_N1 (1 << 5)
DMA_VLEN_RES1 = (5 << 5),/*!<reserved*/ /*
DMA_VLEN_RES2 = (6 << 5),/*!<reserved*/ * Transfer the number of bytes/words specified by first byte/word
DMA_VLEN_LEN2 = (7 << 5) /*!<Use LEN for transfer count*/ * (up to a maximum specified by LEN).
}dma_vlen_t; * 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 */
/** address increment modes */ /* Transfer Types (Byte 6 [6:5]) */
typedef enum dma_inc_t #define DMA_SINGLE 0x00 /* Single */
{ #define DMA_BLOCK 0x20 /* Block */
DMA_NOINC = 0, /*!<No increment*/ #define DMA_RPT_SINGLE 0x40 /* Repeated single */
DMA_INC = 1, /*!<Increment*/ #define DMA_RPT_BLOCK 0x60 /* Repeated block */
DMA_INC2 = 2, /*!<Increment 2*/
DMA_DEC = 3 /*!<Decrement*/
}dma_inc_t;
/** transfer types */ /* Source Increment Modes (Byte 7 [7:6])*/
typedef enum dma_type_t #define DMA_SRC_INC_NO 0x00 /* Source No increment */
{ #define DMA_SRC_INC_1 0x40 /* Source Increment 1 */
DMA_SINGLE = 0, /*!<Single*/ #define DMA_SRC_INC_2 0x80 /* Source Increment 2 */
DMA_BLOCK = 1, /*!<Block*/ #define DMA_SRC_DEC 0xC0 /* Source Decrement 1 */
DMA_RPT = 2, /*!<Repeated single*/ /* Source Increment Modes (Byte 7 [5:4])*/
DMA_BLOCK_RPT=3 /*!<Repeated block*/ #define DMA_DST_INC_NO 0x00 /* DestinationNo increment */
}dma_type_t; #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 */ /** DMA configuration structure */
typedef struct dma_config_t typedef struct dma_config {
{ uint8_t src_h; /* source address high byte*/
uint8_t src_h; /*!<source address high byte*/ uint8_t src_l; /* source address low byte*/
uint8_t src_l; /*!<source address low byte*/ uint8_t dst_h; /* dest. address high byte*/
uint8_t dst_h; /*!<dest. address high byte*/ uint8_t dst_l; /* dest. address low 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_h; /*!<transfer mode in high 3 bits, length high byte, 4 lowest bits*/ uint8_t len_l; /* length low byte*/
uint8_t len_l; /*!<length low byte*/ uint8_t wtt; /* 7: wordsize, [6:5] transfer mode, [4:0] trigger */
uint8_t t_mode; /*!<transfer mode: bit7=word mode, 6-5=block/single 4-0=trigger */ /* [7:6] src inc, [5:4] dst_inc, 3: IRQ, 2: M8(vlen), [1-0] prio */
uint8_t addr_mode; /*!<address mode: 7-6=src inc, 5-4=dst_inc, 3=IRQ, 2=M8(vlen) 1-0:priority*/ uint8_t inc_prio;
} dma_config_t;
}dma_config_t; #ifdef DMA_CONF_ON
#define DMA_ON DMA_CONF_ON
extern void dma_init(void) __banked; #else
typedef void (*dma_func)(void *); #define DMA_ON 0
extern dma_config_t dma_conf[4];
#ifdef HAVE_DMA
typedef uint8_t xDMAHandle;
#define dma_config(channel, src, src_inc, dst, dst_inc, length, vlen_mode, t_mode, trigger, proc) dma_config2(channel,src,src_inc, dst, dst_inc, length, 0, vlen_mode, t_mode, trigger, proc)
/*
extern xDMAHandle dma_config(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
uint16_t length, dma_vlen_t vlen_mode, dma_type_t t_mode,
dma_trigger_t trigger, struct process * p);
*/
extern xDMAHandle dma_config2(uint8_t channel, void *src, dma_inc_t src_inc, void *dst, dma_inc_t dst_inc,
uint16_t length, uint8_t word_mode, dma_vlen_t vlen_mode, dma_type_t t_mode,
dma_trigger_t trigger, struct process * p) __banked;
extern uint8_t dma_arm(xDMAHandle channel) __banked;
extern uint8_t dma_abort(xDMAHandle channel) __banked;
extern uint8_t dma_trigger(xDMAHandle channel) __banked;
extern uint8_t dma_state(xDMAHandle channel) __banked;
void dma_config_print(xDMAHandle channel) __banked;
#endif #endif
extern void dma_ISR( void ) __interrupt (DMA_VECTOR); /* 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*/ #endif /*__DMA_H*/

View file

@ -14,9 +14,10 @@
#include "dev/dma.h" #include "dev/dma.h"
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
#include "banked.h"
extern struct process * dma_callback[4]; #if DMA_ON
extern struct process * dma_callback[DMA_CHANNEL_COUNT];
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#ifdef HAVE_RF_DMA #ifdef HAVE_RF_DMA
@ -34,10 +35,11 @@ extern void spi_rx_dma_callback(void);
void void
dma_ISR(void) __interrupt (DMA_VECTOR) dma_ISR(void) __interrupt (DMA_VECTOR)
{ {
#ifdef HAVE_DMA #if DMA_ON
uint8_t i; uint8_t i;
#endif #endif
EA=0; EA=0;
IRCON_DMAIF = 0;
#ifdef HAVE_RF_DMA #ifdef HAVE_RF_DMA
if((DMAIRQ & 1) != 0) { if((DMAIRQ & 1) != 0) {
DMAIRQ &= ~1; DMAIRQ &= ~1;
@ -51,17 +53,16 @@ dma_ISR(void) __interrupt (DMA_VECTOR)
spi_rx_dma_callback(); spi_rx_dma_callback();
} }
#endif #endif
#ifdef HAVE_DMA #if DMA_ON
for(i = 0; i < 4; i++) { for(i = 0; i < DMA_CHANNEL_COUNT; i++) {
if((DMAIRQ & (1 << i + 1)) != 0) { if((DMAIRQ & (1 << i)) != 0) {
DMAIRQ &= ~(1 << i+1); DMAIRQ &= ~(1 << i);
if(dma_callback[i] != 0) { if(dma_callback[i] != 0) {
process_poll(dma_callback[i]); process_poll(dma_callback[i]);
} }
} }
} }
#endif #endif
IRCON_DMAIF = 0;
EA = 1; EA = 1;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -36,8 +36,6 @@
#include "sys/cc.h" #include "sys/cc.h"
#include <cc2430_sfr.h> #include <cc2430_sfr.h>
extern uint8_t p0ien;
extern uint8_t p2ien;
#define HWCONF_PIN(name, port, bit) \ #define HWCONF_PIN(name, port, bit) \
static CC_INLINE void name##_SELECT() {P##port##SEL &= ~(1 << bit);} \ static CC_INLINE void name##_SELECT() {P##port##SEL &= ~(1 << bit);} \
@ -51,10 +49,10 @@ static CC_INLINE void name##_MAKE_INPUT() {P##port##DIR &= ~(1 << bit); }
#define HWCONF_IRQ_XXX(name, port, bit) \ #define HWCONF_IRQ_XXX(name, port, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \ static CC_INLINE void name##_ENABLE_IRQ() { \
if ( port == 2 ) { PICTL |= P2IEN; p2ien |= 1<<bit; } \ if ( port == 2 ) { PICTL |= P2IEN; p2ien |= 1<<bit; IEN2 |= P2IE; } \
if (( port == 0) && ( bit <4)) { PICTL |= P0IENL; p0ien |= 1<<bit; } \ if (( port == 0) && ( bit <4)) { PICTL |= P0IENL; p0ien |= 1<<bit; IEN1 |= P0IE; } \
if ((port == 0) && ( bit >=4)) { PICTL |= P0IENH; p0ien |= 1<<bit; } \ if ((port == 0) && ( bit >=4)) { PICTL |= P0IENH; p0ien |= 1<<bit; IEN1 |= P0IE; } \
if ( port == 1) { P##port##IEN |= 1 << bit; } \ if ( port == 1) { P##port##IEN |= 1 << bit; IEN2 |= P1IE; } \
} \ } \
static CC_INLINE void name##_DISABLE_IRQ() { \ static CC_INLINE void name##_DISABLE_IRQ() { \
if ( port == 2 ) { \ if ( port == 2 ) { \
@ -73,7 +71,11 @@ static CC_INLINE void name##_DISABLE_IRQ() { \
} \ } \
static CC_INLINE int name##_IRQ_ENABLED() {return P##port##IEN & (1 << bit);} \ static CC_INLINE int name##_IRQ_ENABLED() {return P##port##IEN & (1 << bit);} \
static CC_INLINE int name##_CHECK_IRQ() {return P##port##IFG & (1 << bit);} \ static CC_INLINE int name##_CHECK_IRQ() {return P##port##IFG & (1 << bit);} \
static CC_INLINE int name##_IRQ_PORT() {return IRQ_PORT##port;} static CC_INLINE void name##_IRQ_FLAG_OFF() { \
P##port##IFG &= ~(1 << bit); \
if (port == 0) {IRCON &= ~P0IF;} \
else {IRCON2 &= ~P##port##IF;} \
}
#define HWCONF_IRQ(name, port, bit) \ #define HWCONF_IRQ(name, port, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \ static CC_INLINE void name##_ENABLE_IRQ() { \
@ -86,4 +88,62 @@ static CC_INLINE int name##_IRQ_ENABLED() {return P##port##IEN & (1 << bit);}
static CC_INLINE int name##_CHECK_IRQ() {return P##port##IFG & (1 << bit);} \ static CC_INLINE int name##_CHECK_IRQ() {return P##port##IFG & (1 << bit);} \
static CC_INLINE int name##_IRQ_PORT() {return IRQ_PORT##port;} static CC_INLINE int name##_IRQ_PORT() {return IRQ_PORT##port;}
#define HWCONF_PORT_0_IRQ(name, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \
if ( bit <4 ) { PICTL |= P0IENL; p0ien |= 1<<bit; IEN1 |= P0IE; } \
if ( bit >=4 ) { PICTL |= P0IENH; p0ien |= 1<<bit; IEN1 |= P0IE; } \
} \
static CC_INLINE void name##_DISABLE_IRQ() { \
if ( bit <4) { \
p0ien &= ~(1<<bit); \
if ((p0ien&0xf)==0) PICTL &= ~P0IENL; \
} \
if ( bit >=4) { \
p0ien &= ~(1<<bit); \
if ((p0ien&0xf0)==0) PICTL &= ~P0IENH; \
} \
} \
static CC_INLINE int name##_IRQ_ENABLED() {return p0ien & (1 << bit);} \
static CC_INLINE void name##_IRQ_EDGE_SELECTD() {PICTL |= P0ICON;} \
static CC_INLINE void name##_IRQ_EDGE_SELECTU() {PICTL &= ~P0ICON;} \
static CC_INLINE int name##_CHECK_IRQ() {return P0IFG & (1 << bit);} \
static CC_INLINE void name##_IRQ_FLAG_OFF() { \
IRCON_P0IF = 0; \
P0IFG = 0; \
}
#define HWCONF_PORT_1_IRQ(name, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { P1IEN |= 1 << bit; IEN2 |= P1IE; } \
static CC_INLINE void name##_DISABLE_IRQ() { \
P1IEN &= ~(1 << bit); \
if (P1IEN == 0) { IEN2 &= ~P1IE; } \
} \
static CC_INLINE int name##_IRQ_ENABLED() { return P1IEN & (1 << bit); } \
static CC_INLINE void name##_IRQ_EDGE_SELECTD() {PICTL |= P1ICON;} \
static CC_INLINE void name##_IRQ_EDGE_SELECTU() {PICTL &= ~P1ICON;} \
static CC_INLINE int name##_CHECK_IRQ() { return P1IFG & (1 << bit); } \
static CC_INLINE void name##_IRQ_FLAG_OFF() { \
IRCON2_P1IF = 0; \
P1IFG = 0; \
}
#define HWCONF_PORT_2_IRQ(name, bit) \
static CC_INLINE void name##_ENABLE_IRQ() { \
PICTL |= P2IEN; \
p2ien |= 1<<bit; \
IEN2 |= P2IE; \
} \
static CC_INLINE void name##_DISABLE_IRQ() { \
p2ien &= ~(1<<bit); \
if (p2ien==0) { PICTL &= ~P2IEN; IEN2 &= ~P2IE; } \
} \
static CC_INLINE int name##_IRQ_ENABLED() {return p2ien & (1 << bit);} \
static CC_INLINE void name##_IRQ_EDGE_SELECTD() {PICTL |= P2ICON;} \
static CC_INLINE void name##_IRQ_EDGE_SELECTU() {PICTL &= ~P2ICON;} \
static CC_INLINE int name##_CHECK_IRQ() {return P2IFG & (1 << bit);} \
static CC_INLINE void name##_IRQ_FLAG_OFF() { \
IRCON2_P2IF = 0; \
P2IFG = 0; \
}
#endif /* __HWCONF_H__ */ #endif /* __HWCONF_H__ */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, Swedish Institute of Computer Science * Copyright (c) 2010, Loughborough University - Computer Science
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -27,37 +27,31 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* This file is part of the Contiki operating system. * 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.
* *
* @(#)$Id: lpm.h,v 1.1 2009/12/22 09:28:15 zdshelby Exp $ * \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/ */
#ifndef __LPM_H__ #ifndef __LPM_H__
#define __LPM_H__ #define __LPM_H__
#include <io.h>
#include "contiki-conf.h" #include "contiki-conf.h"
#ifdef LPM_CONF_ON #define LPM_MODE_NONE 0 /* No LPM - Always on */
#define LPM_ON LPM_CONF_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 #else
#define LPM_ON LPM1 #define LPM_MODE LPM_MODE_IDLE
#endif /* LPM_CONF_ON */ #endif /* LPM_CONF_MODE */
#ifdef LPM_CONF_OFF
#define LPM_OFF LPM_CONF_OFF
#else
#define LPM_OFF LPM1_EXIT
#endif /* LPM_CONF_OFF */
#define LPM_SLEEP() do { if(lpm_status == LPM_STATUS_ON) LPM_ON; } while(0)
#define LPM_AWAKE() do { if(lpm_status == LPM_STATUS_ON) LPM_OFF; } while(0)
extern unsigned char lpm_status;
void lpm_on(void);
void lpm_off(void);
#define LPM_STATUS_OFF 0
#define LPM_STATUS_ON 1
#endif /* __LPM_H__ */ #endif /* __LPM_H__ */

135
cpu/cc2430/dev/random.c Normal file
View file

@ -0,0 +1,135 @@
/*
* 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
* Random number generator routines exploiting the cc2430 hardware
* capabilities.
*
* This file overrides core/lib/random.c.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "cc2430_sfr.h"
#include "dev/cc2430_rf.h"
/*---------------------------------------------------------------------------*/
/**
* \brief Generates a new random number using the cc2430 RNG.
* \return The random number.
*/
unsigned short
random_rand(void)
{
/* Clock the RNG LSFR once */
ADCCON1 |= ADRCTRL0;
return (RNDL | (RNDH << 8));
}
/*---------------------------------------------------------------------------*/
/**
* \brief Seed the cc2430 random number generator.
* \param seed Seed value for the RNG.
*
* If the SEED argument is 0, seed the RNG with IF_ADC as
* discussed in the cc2430 datasheet (rev. 2.1), section 13.11.2.2,
* page 134. Seeding with this method should not be done during
* normal radio operation. Thus, use this function before
* initialising the network.
*
* If the SEED is provided, seed with this value instead. This will
* result in the same sequence of random numbers each time the node
* reboots. So, don't use it unless you have a reason (e.g. tests)
*/
void
random_init(unsigned short seed)
{
int i;
/* Comment out this if() block to save a nice 16 bytes of code size */
if(seed) {
/* If the caller provides a seed, write the high-byte first and then
* write the low byte */
RNDL = seed >> 8; /* High byte first */
RNDL = seed & 0xFF;
return;
}
/*
* cc2430 Datasheet:
* "When a true random value is required, the LFSR should be seeded by
* writing RNDL with random values from the IF_ADC in the RF receive path."
*
* "To use this seeding method, the radio must first be powered on by
* enabling the voltage regulator"
*/
RFPWR &= ~RREG_RADIO_PD; /* Turn on the voltage regulator */
while(!(RFIF & IRQ_RREG_ON)); /* Wait for power up*/
/* OK, it's powered. The respective interrupt flag has been set, clear it */
RFIF &= ~IRQ_RREG_ON;
/*
* "The radio should be placed in infinite TX state, to avoid possible sync
* detect in RX state."
*
* Judging by old chipcon cc2430 code examples as well as by the way cc2530
* works, this is very likely to be "RX state" (i.e. a typo in the datasheet)
*
* With infinite TX, ADCTSTx always read as 0 so we'll use infinite RX
*/
MDMCTRL1L = 0x02; /* RX mode 10 - RX_INFINITE state */
/* "Enter RX State - Immediate" command strobe */
cc2430_rf_command(ISRXON);
/* Make sure the RNG is on */
ADCCON1 &= ~(ADRCTRL1 | ADRCTRL0);
/* Wait for IF_ADC I-branch and Q-branch values */
while(!(ADCTSTH & ADCTSTL));
/* 32 times as per the chipcon example. This seems to increase randomness */
for(i = 0; i < 32; i++) {
/* Seed the RNG by writing into RNDL twice with values from ADCTSTx */
RNDL = ADCTSTH;
RNDL = ADCTSTL;
/* Clock the RNG LSFR once */
ADCCON1 |= ADRCTRL0;
}
/*
* Exit RX state. Just shut down, network initialisation will take care of
* properly starting the radio for us.
*/
RFPWR |= RREG_RADIO_PD;
}

View file

@ -1,88 +0,0 @@
/*
* Copyright (c) 2007, Takahide Matsutsuka.
* 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.
*
* $Id: rs232.h,v 1.1 2009/09/08 20:07:35 zdshelby Exp $
*
*/
/*
* \file
* This is RS-232C process based on polling.
* \author
* Takahide Matsutsuka <markn@markn.org>
*/
#ifndef __RS232_H__
#define __RS232_H__
/*
* Implement the following methods for each platform.
*/
/*
* An architecture-depend implementation of RS-232C initialization.
*/
void rs232_arch_init(unsigned long ubr);
/*
* An architecture-depend implementation of RS-232C polling.
* @return character, stat == zero if no input.
*/
unsigned char rs232_arch_poll(unsigned char* stat);
/*
* An architecture-depend implementation of RS-232C writing a byte.
*/
void rs232_arch_writeb(unsigned char ch);
PROCESS_NAME(rs232_process);
/*
* if you want to use simple serial communication,
* define RS232_CONF_CALLBACK as serial_input_byte.
* The default is SLIP.
*/
#ifdef RS232_CONF_CALLBACK
#define RS232_CALLBACK RS232_CONF_CALLBACK
#else /* RS232_CONF_CALLBACK */
#define RS232_CALLBACK slip_input_byte
#endif /* RS232_CONF_CALLBACK */
#ifdef RS232_CONF_BUFISZE
#define RS232_BUFSIZE RS232_CONF_BUFISZE
#else /* RS232_CONF_BUFISZE */
#define RS232_BUFSIZE 64
#endif /* RS232_CONF_BUFISZE */
#ifdef RS232_CONF_BAUD_RATE
#define RS232_BAUD_RATE RS232_CONF_BAUD_RATE
#else /* RS232_CONF_BAUD_RATE */
#define RS232_BAUD_RATE 9600
#endif /* RS232_CONF_BAUD_RATE */
#endif /* __RS232_H__ */

View file

@ -1,41 +0,0 @@
/**
* \file
*
* uart write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
* non-interrupt routines which may be called from ISR's and therefore should be in HOME bank.
*
*/
#include <stdlib.h>
#include <string.h>
#include "cc2430_sfr.h"
#include "dev/leds.h"
#include "dev/uart.h"
/*---------------------------------------------------------------------------*/
/* Write one byte over the UART. */
void
uart0_writeb(uint8_t byte)
{
IRCON2_UTX0IF = 0;
U0BUF = byte;
while(!IRCON2_UTX0IF); /* Wait until byte has been transmitted. */
IRCON2_UTX0IF = 0;
}
/*---------------------------------------------------------------------------*/
/* Write one byte over the UART. */
void
uart1_writeb(uint8_t byte)
{
IRCON2_UTX1IF = 0;
U1BUF = byte;
while(!IRCON2_UTX1IF); /* Wait until byte has been transmitted. */
IRCON2_UTX1IF = 0;
}
/*---------------------------------------------------------------------------*/

View file

@ -2,24 +2,42 @@
#define UART_H #define UART_H
#include "contiki-conf.h" #include "contiki-conf.h"
#include "banked.h"
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
#include "8051def.h"
void uart0_init(uint32_t speed) __banked; /*---------------------------------------------------------------------------*/
void uart0_writeb(uint8_t byte); /* 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 cc2430 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)
void uart0_set_input(int (*input)(unsigned char c)); /*
* 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
void uart0_rxISR( void ) __interrupt (URX0_VECTOR); #endif /* UART_H */
void uart0_txISR( void ) __interrupt (UTX0_VECTOR);
void uart1_init(uint32_t speed) __banked;
void uart1_writeb(uint8_t byte);
void uart1_set_input(int (*input)(unsigned char c));
void uart1_rxISR( void ) __interrupt (URX1_VECTOR);
void uart1_txISR( void ) __interrupt (UTX1_VECTOR);
#endif /*UART_H*/

69
cpu/cc2430/dev/uart0.c Normal file
View file

@ -0,0 +1,69 @@
/**
* \file
*
* uart0 write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
*/
#include <stdlib.h>
#include <string.h>
#include "cc2430_sfr.h"
#include "dev/uart0.h"
#if UART_ZERO_ENABLE
/*---------------------------------------------------------------------------*/
void
uart0_init()
{
UART_SET_SPEED(0, UART_115_M, UART_115_E);
#ifdef UART0_ALTERNATIVE_2
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 &= ~U0CFG; /*alternative port 1 = P0.5-2*/
#ifdef UART0_RTSCTS
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#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 = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
}
/*---------------------------------------------------------------------------*/
/* Write one byte over the UART. */
void
uart0_writeb(uint8_t byte)
{
IRCON2_UTX0IF = 0;
U0BUF = byte;
while(!IRCON2_UTX0IF); /* Wait until byte has been transmitted. */
IRCON2_UTX0IF = 0;
}
#endif

31
cpu/cc2430/dev/uart0.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef UART_0_H
#define UART_0_H
#include "contiki-conf.h"
#include "cc2430_sfr.h"
#include "8051def.h"
#include "uart.h"
/*---------------------------------------------------------------------------*/
/* UART0 Enable - Disable */
#ifdef UART_ZERO_CONF_ENABLE
#define UART_ZERO_ENABLE UART_ZERO_CONF_ENABLE
#else
#define UART_ZERO_ENABLE 0
#endif
/*---------------------------------------------------------------------------*/
/* UART0 Function Declarations */
#if UART_ZERO_ENABLE
void uart0_init();
void uart0_writeb(uint8_t byte);
void uart0_set_input(int (*input)(unsigned char c));
void uart0_rx_ISR( void ) __interrupt (URX0_VECTOR);
void uart0_tx_ISR( void ) __interrupt (UTX0_VECTOR);
/* Macro to turn on / off UART RX Interrupt */
#define UART0_RX_INT(v) IEN0_URX0IE = v
#endif
#endif /* UART_0_H */

74
cpu/cc2430/dev/uart1.c Normal file
View file

@ -0,0 +1,74 @@
/**
* \file
*
* uart1 write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
*/
#include <stdlib.h>
#include <string.h>
#include "cc2430_sfr.h"
#include "dev/uart1.h"
#if UART_ONE_ENABLE
/*---------------------------------------------------------------------------*/
/* UART1 initialization */
void
uart1_init()
{
#ifdef UART1_ALTERNATIVE_1
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 |= 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 = U_MODE | U_RE; /* UART mode, receiver enable */
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
}
/*---------------------------------------------------------------------------*/
/* Write one byte over the UART. */
void
uart1_writeb(uint8_t byte)
{
IRCON2_UTX1IF = 0;
U1BUF = byte;
while(!IRCON2_UTX1IF); /* Wait until byte has been transmitted. */
IRCON2_UTX1IF = 0;
}
/*---------------------------------------------------------------------------*/
#endif

39
cpu/cc2430/dev/uart1.h Normal file
View file

@ -0,0 +1,39 @@
#ifndef UART_1_H
#define UART_1_H
#include "contiki-conf.h"
#include "cc2430_sfr.h"
#include "8051def.h"
#include "uart.h"
/*---------------------------------------------------------------------------*/
/* UART1 Enable - Disable */
#ifdef UART_ONE_CONF_ENABLE
#define UART_ONE_ENABLE UART_ONE_CONF_ENABLE
#else
#define UART_ONE_ENABLE 0
#endif
/*---------------------------------------------------------------------------*/
/* UART1 Function Declarations */
#if UART_ONE_ENABLE
void uart1_init();
void uart1_writeb(uint8_t byte);
void uart1_set_input(int (*input)(unsigned char c));
#if UART_ONE_CONF_WITH_INPUT
void uart1_rx_ISR( void ) __interrupt (URX1_VECTOR);
void uart1_tx_ISR( void ) __interrupt (UTX1_VECTOR);
/* Macro to turn on / off UART RX Interrupt */
#define UART1_RX_INT(v) IEN0_URX1IE = v
#else
#define UART1_RX_INT(v)
#endif /* UART_ONE_CONF_WITH_INPUT */
#else
#define uart1_init(...)
#define uart1_writeb(...)
#define uart1_set_input(...)
#define UART1_RX_INT(v)
#endif /* UART_ONE_ENABLE */
#endif /* UART_1_H */

View file

@ -1,133 +0,0 @@
/**
* \file
*
* uart initialization routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
* non-interrupt routines typically only called once, stored in any bank.
*
*/
#include <stdlib.h>
#include <string.h>
#include "banked.h"
#include "cc2430_sfr.h"
#include "dev/leds.h"
#include "dev/uart.h"
/*---------------------------------------------------------------------------*/
void
uart0_init(uint32_t speed) __banked
{
if(speed == 115200) {
U0BAUD=216; /*115200*/
U0GCR =11; /*LSB first and 115200*/
}
else if(speed == 38400) {
U0BAUD=59; /*38400*/
U0GCR =10; /*LSB first and 38400*/
}
else if(speed == 9600) {
U0BAUD= 59; /* 9600 */
U0GCR = 8; /*LSB first and 9600*/
}
else { return; }
#ifdef UART0_ALTERNATIVE_2
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 &= ~U0CFG; /*alternative port 1 = P0.5-2*/
#ifdef UART0_RTSCTS
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
#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 = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
IEN0_URX0IE = 1;
}
/*---------------------------------------------------------------------------*/
/* UART1 initialization */
void
uart1_init(uint32_t speed) __banked
{
#ifdef UART1_ALTERNATIVE_1
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 |= 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(speed == 115200) {
U1BAUD=216; /*115200*/
U1GCR =11; /*LSB first and 115200*/
}
if(speed == 38400) {
U1BAUD=59; /*38400*/
U1GCR =10; /*LSB first and 38400*/
}
if(speed == 9600) {
U1BAUD= 59; /* 9600 */
U1GCR = 8; /*LSB first and 9600*/
}
#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 = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/
/*set priority group of group 3 to highest, so the UART won't miss bytes*/
IP1 |= IP1_3;
IP0 |= IP0_3;
IEN0_URX1IE = 1; /* Enable the RX interrupt */
}
/*---------------------------------------------------------------------------*/

View file

@ -16,10 +16,18 @@
#include "cc2430_sfr.h" #include "cc2430_sfr.h"
#include "dev/leds.h" #include "dev/leds.h"
#include "dev/uart.h" #include "dev/uart0.h"
#include "dev/uart1.h"
#include "sys/energest.h"
#if UART_ZERO_ENABLE
static int (*uart0_input_handler)(unsigned char c); static int (*uart0_input_handler)(unsigned char c);
#endif
#if UART_ONE_ENABLE
static int (*uart1_input_handler)(unsigned char c); static int (*uart1_input_handler)(unsigned char c);
#endif
#if UART_ZERO_ENABLE
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uart0_set_input(int (*input)(unsigned char c)) uart0_set_input(int (*input)(unsigned char c))
@ -29,18 +37,22 @@ uart0_set_input(int (*input)(unsigned char c))
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uart0_rxISR(void) __interrupt (URX0_VECTOR) uart0_rx_ISR(void) __interrupt (URX0_VECTOR)
{ {
ENERGEST_ON(ENERGEST_TYPE_IRQ);
TCON_URX0IF = 0; TCON_URX0IF = 0;
if(uart0_input_handler != NULL) { if(uart0_input_handler != NULL) {
uart0_input_handler(U0BUF); uart0_input_handler(U0BUF);
} }
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uart0_txISR( void ) __interrupt (UTX0_VECTOR) uart0_tx_ISR( void ) __interrupt (UTX0_VECTOR)
{ {
} }
#endif /* UART_ZERO_ENABLE */
#if UART_ONE_ENABLE
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uart1_set_input(int (*input)(unsigned char c)) uart1_set_input(int (*input)(unsigned char c))
@ -48,17 +60,22 @@ uart1_set_input(int (*input)(unsigned char c))
uart1_input_handler = input; uart1_input_handler = input;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if UART_ONE_CONF_WITH_INPUT
void void
uart1_rxISR(void) __interrupt (URX1_VECTOR) uart1_rx_ISR(void) __interrupt (URX1_VECTOR)
{ {
ENERGEST_ON(ENERGEST_TYPE_IRQ);
TCON_URX1IF = 0; TCON_URX1IF = 0;
if(uart1_input_handler != NULL) { if(uart1_input_handler != NULL) {
uart1_input_handler(U1BUF); uart1_input_handler(U1BUF);
} }
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uart1_txISR( void ) __interrupt (UTX1_VECTOR) uart1_tx_ISR( void ) __interrupt (UTX1_VECTOR)
{ {
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* UART_ONE_CONF_WITH_INPUT */
#endif /* UART_ONE_ENABLE */

View file

@ -0,0 +1,124 @@
/*
* 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 for the cc2430 watchdog timer.
*
* This file contains an ISR and must reside in the HOME bank.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "sys/energest.h"
#include "cc2430_sfr.h"
#include "contiki-conf.h"
#include "dev/watchdog-cc2430.h"
/*---------------------------------------------------------------------------*/
/* The watchdog only throws interrupts in timer mode */
#if WDT_TIMER_MODE
void
cc4230_watchdog_ISR(void) __interrupt (WDT_VECTOR)
{
EA = 0;
ENERGEST_ON(ENERGEST_TYPE_IRQ);
/* Do something */
IRCON2 &= ~WDTIF;
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
EA = 1;
}
#endif
/*---------------------------------------------------------------------------*/
void
watchdog_init(void)
{
WDCTL = WDT_TIMER_MODE | WDT_INTERVAL;
#if WDT_TIMER_MODE
/* Enable the watchdog interrupts in timer mode */
IEN2 |= WDTIE;
#endif
return;
}
/*---------------------------------------------------------------------------*/
void
watchdog_start(void)
{
WDCTL |= WDT_EN;
}
/*---------------------------------------------------------------------------*/
void
watchdog_periodic(void)
{
#if WDT_TIMER_MODE
/* In timer mode, all we need to do is write 1 to WDT:CLR[0] */
WDCTL |= WDT_CLR0;
#else
/* Write the 'clear' sequence while maintaining mode and interval setting */
WDCTL = (WDCTL & 0x0F) | WDT_CLR3 | WDT_CLR1;
WDCTL = (WDCTL & 0x0F) | WDT_CLR2 | WDT_CLR0;
#endif
}
/*---------------------------------------------------------------------------*/
void
watchdog_stop(void)
{
#if WDT_TIMER_MODE
/* In timer mode, the watchdog can actually be stopped */
WDCTL &= ~WDT_EN;
IRCON2 &= ~WDTIF;
#else
/* In watchdog mode, stopping is impossible so we just reset the timer */
watchdog_periodic();
#endif
}
/*---------------------------------------------------------------------------*/
void
watchdog_reboot(void)
{
#if WDT_TIMER_MODE
/* Switch modes to watchdog, minimum interval, enable */
WDCTL = WDT_EN | WDT_TIMEOUT_2_MSEC;
#else
/* Let's get this over with ASAP */
WDCTL = WDT_TIMEOUT_2_MSEC;
#endif
/* Dis-acknowledge all interrupts while we wait for the dog to bark */
DISABLE_INTERRUPTS();
/* NOP till the dog barks... */
while(1) {
__asm
nop
__endasm;
}
}

View file

@ -0,0 +1,72 @@
/*
* 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 header file for the cc2430 watchdog timer.
*
* The interrupt service routine's prototype must be included by the
* file containing main().
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef WATCHDOG_CC2430_H_
#define WATCHDOG_CC2430_H_
#include "dev/watchdog.h"
#include "cc2430_sfr.h"
#include "contiki-conf.h"
#define WDT_TIMEOUT_1_SEC 0x00
#define WDT_TIMEOUT_250_MSEC WDT_INT0
#define WDT_TIMEOUT_15_MSEC WDT_INT1
#define WDT_TIMEOUT_2_MSEC WDT_INT1 | WDT_INT0
#if WDT_CONF_TIMER_MODE
#define WDT_TIMER_MODE WDT_MODE /* Timer */
#else
#define WDT_TIMER_MODE 0x00 /* Watchdog */
#endif
#ifdef WDT_CONF_INTERVAL
#define WDT_INTERVAL WDT_CONF_INTERVAL
#else
#define WDT_INTERVAL WDT_TIMEOUT_1_SEC /* 2 secs */
#endif
/* The watchdog only throws interrupts in timer mode */
#if WDT_TIMER_MODE
void cc4230_watchdog_ISR(void) __interrupt (WDT_VECTOR);
#endif
#endif /* WATCHDOG_CC2430_H_ */

View file

@ -1,10 +0,0 @@
#ifndef __IO_H__
#define __IO_H__
#include <cc2430_sfr.h>
#ifndef BV
#define BV(x) (1<<(x))
#endif
#endif /* __IO_H__ */

View file

@ -1,192 +0,0 @@
/*
* Copyright (c) 2007, Takahide Matsutsuka.
* 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
* Z80 machine-specific implementation for supporting multithread.
* \author
* Takahide Matsutsuka <markn@markn.org>
*/
#include "sys/mt.h"
#include "mtarch.h"
/*--------------------------------------------------------------------------*/
void
mtarch_init(void)
{
}
/*--------------------------------------------------------------------------*/
void
mtarch_start(struct mtarch_thread *t,
void (*function)(void *), void *data)
{
uint16_t i;
for(i = 0; i < MTARCH_STACKSIZE; i++) {
t->stack[i] = i;
}
t->sp = &t->stack[MTARCH_STACKSIZE - 1];
/* A parameter for method for thread function. */
*t->sp = (uint16_t)data;
--t->sp;
/* This will be a return address of thread function. */
*t->sp = (uint16_t)mt_exit;
--t->sp;
/* The thread function, is used as a return address of mtarch_switch. */
*t->sp = (uint16_t)function;
--t->sp;
/*
* Space for registers.
* af, bc, de, hl, ix, iy, af', bc', de', hl'
*/
/*
* Z80 stack basis:
* push stores the data AFTER decrementing sp.
* pop reads the data BEFORE incrementing sp.
*/
t->sp = t->sp - 9;
}
/*--------------------------------------------------------------------------*/
static struct mtarch_thread *running_thread;
static uint16_t *sptmp;
static void
mtarch_switch()
{
__asm
di ; disable interrupt
; normal registers
push af
push bc
push de
push hl
push ix
push iy
; back registers
ex af,af'
push af
exx
push bc
push de
push hl
; swap between running_thread->sp and SP reg
; _running_thread in asembler below points running_thread->sp
; sptmp = sp;
ld (_sptmp),sp
; sp = *(running_thread->sp);
ld ix,(_running_thread)
ld l,0(ix)
ld h,1(ix)
ld sp,hl
; running_thread->sp = sptmp;
ld hl,(_sptmp)
ld 0(ix),l
ld 1(ix),h
; back registers
pop hl
pop de
pop bc
exx
pop af
ex af,af'
; normal registers
pop iy
pop ix
pop hl
pop de
pop bc
pop af
ei ; enable interrupt
__endasm;
// here sp indicates the address that point the function
}
/*--------------------------------------------------------------------------*/
void
mtarch_exec(struct mtarch_thread *t)
{
running_thread = t;
mtarch_switch();
running_thread = NULL;
}
/*--------------------------------------------------------------------------*/
void
mtarch_remove()
{
}
/*--------------------------------------------------------------------------*/
void
mtarch_yield()
{
if (running_thread == NULL) {
/* ERROR! we have no runnning thread. */
return;
}
mtarch_switch();
}
/*--------------------------------------------------------------------------*/
void mtarch_stop(struct mtarch_thread *thread)
{
}
/*--------------------------------------------------------------------------*/
void
mtarch_pstop()
{
}
/*--------------------------------------------------------------------------*/
void
mtarch_pstart()
{
}
/*--------------------------------------------------------------------------*/
int
mtarch_stack_usage(struct mtarch_thread *t)
{
uint16_t i;
for (i = 0; i < MTARCH_STACKSIZE; i++) {
if (t->stack[i] != i) {
return MTARCH_STACKSIZE - i;
}
}
return 0;
}
/*--------------------------------------------------------------------------*/

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, Takahide Matsutsuka. * Copyright (c) 2010, Loughborough University - Computer Science
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -28,38 +28,23 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
/* /*
* \file * \file
* Z80 machine-specific difinitions for supporting multithread. * Stub header file for cc2430 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 * \author
* Takahide Matsutsuka <markn@markn.org> * George Oikonomou - <oikonomou@users.sourceforge.net>
*/ */
#ifndef __MTARCH_H__ #ifndef __MTARCH_H__
#define __MTARCH_H__ #define __MTARCH_H__
/* Unit of the stack is 2byte wide. */
#ifndef MTARCH_STACKSIZE
#define MTARCH_STACKSIZE 128
#endif /* MTARCH_STACKSIZE */
struct mtarch_thread { struct mtarch_thread {
/* unsigned char *sp;
* On top of the mtarch_thread must be the address for the stack pointer.
* See details at mtarch_switch in mtarch.c
*/
uint16_t *sp;
/*
* Stack is 2-byte wide, so please note that you need 2 * MTARCH_STACKSIZE
* bytes for the stack area for each thread.
*/
uint16_t stack[MTARCH_STACKSIZE];
}; };
/*
* A function for debugging purpose, placed here by following other implementations.
*/
int mtarch_stack_usage(struct mtarch_thread *t);
#endif /* __MTARCH_H__ */ #endif /* __MTARCH_H__ */

122
cpu/cc2430/rtimer-arch.c Normal file
View file

@ -0,0 +1,122 @@
/*
* 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 and etimer are using the sleep timer on the cc2430
*
* clock_init() has set our tick speed prescaler already, so we
* are ticking with 500 kHz freq.
*
* rtimer_clock_t is unsigned short (16bit on the cc2430)
* It thus makes sense to use the 16bit clock (Timer 1)
*
* This file contains an ISR and must reside in the HOME bank
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "sys/rtimer.h" /* Includes rtimer-arch.h for us */
#include "cc2430_sfr.h"
#include "sys/energest.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
void
rtimer_arch_init(void)
{
PRINTF("rtimer_arch_init() ");
/*
* - 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 = (T1DIV1 | T1MODE0); /* 00001001 */
PRINTF("T1CTL=0x%02x\n", T1CTL);
/* Acknowledge Timer 1 Interrupts */
IEN1_T1IE = 1;
PRINTF("IEN1_T1IE=0x%02x\n", IEN1_T1IE);
/* Timer 1, Channel 1. Compare Mode (0x04), Interrupt mask on (0x40) */
T1CCTL1 = T1MODE + T1IM;
PRINTF("T1CCTL1=0x%02x\n", T1CCTL1);
/* Interrupt Mask Flags: No interrupt on overflow */
TIMIF &= ~OVFIM;
PRINTF("TIMIF=0x%02x\n", TIMIF);
PRINTF("done\n");
}
/*---------------------------------------------------------------------------*/
void
rtimer_arch_schedule(rtimer_clock_t t)
{
PRINTF("rtimer_arch_schedule(%u)\n", t);
/* set the compare mode values so we can get an interrupt after t */
T1CC1L = (unsigned char) t;
T1CC1H = (unsigned char) (t >> 8);
PRINTF("T1CC1=%u, t=%u\n", (T1CC1L + (T1CC1H << 8)), t);
/* Turn on compare mode interrupt */
PRINTF("T1CTL=0x%02x\n", T1CTL);
T1CCTL1 |= T1IM;
}
/*---------------------------------------------------------------------------*/
void
cc2430_timer_1_ISR(void) __interrupt (T1_VECTOR)
{
IEN1_T1IE = 0; /* Ignore Timer 1 Interrupts */
ENERGEST_ON(ENERGEST_TYPE_IRQ);
/* No more interrupts from Channel 1 till next rtimer_arch_schedule() call.
* Setting the mask will instantly generate an interrupt so we clear the
* flag first. */
T1CTL &= ~(CH1IF);
T1CCTL1 &= ~T1IM;
rtimer_run_next();
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
IEN1_T1IE = 1; /* Acknowledge Timer 1 Interrupts */
}

View file

@ -33,18 +33,31 @@
/** /**
* \file * \file
* A brief description of what this file is. * Hardware-dependent function declarations used to
* support the contiki rtimer module.
*
* We use Timer 1 on the cc2431.
*
* \author * \author
* Adam Dunkels <adam@sics.se> * Zach Shelby (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net>
* (rtimer-arch implementation for cc2430)
*/ */
#ifndef __RTIMER_ARCH_H__ #ifndef __RTIMER_ARCH_H__
#define __RTIMER_ARCH_H__ #define __RTIMER_ARCH_H__
#include "contiki-conf.h" #include "contiki-conf.h"
#include "cc2430_sfr.h"
#define RTIMER_ARCH_SECOND 1000 /*
* 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() clock_time() #define rtimer_arch_now() ((rtimer_clock_t)(T1CNTL + (T1CNTH << 8)))
void cc2430_timer_1_ISR(void) __interrupt (T1_VECTOR);
#endif /* __RTIMER_ARCH_H__ */ #endif /* __RTIMER_ARCH_H__ */

View file

@ -1,25 +1,26 @@
# segment.rules file assigns source code modules to specific banks # segment.rules files assign source code modules to specific banks
# segment.rules is constructed from any segment.rules found in the search path # These files are only used when we build code with banking (HAVE_BANKING=1)
# the search path is defined in Makefile.cc2430 # The final segment.rules file is constructed from any segment.rules found in
# segment.rules get processed by a perl snippet listed in the Makefile.cc2430 # the search path, defined in Makefile.cc2430
# the processed output is put into the obj_* directory # 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 # comments starting with "#" are supported
# perl regular expression matching can be used on the file name specification # 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 --
# some code must be placed in all banks (or SDCC/aslink will complain at link time)
# code called from function pointers must be in HOME/CSEG/BANK0
# interrupt code must also be in HOME/CSEG/BANK0
# code not marked with __banked can only be called from code in the same bank
# #
HOME intr.c # All interrupt code must live in HOME/BANK0 # general rules --
HOME bus.c # flash_read cannot be banked. # This file is only used when the Makefile defines HAVE_BANKING=1
HOME clock.c # cannot bank clock.c code because header file is part of core. # SDCC's standard libraries will always go in CSEG - We don't touch them
HOME uart.c # Interrupt code must be in HOME. Specify all files with an ISR here
BANK3 uart_init.c # All files without an associated rule get allocated to a bank automatically
BANK2 dma.c
CSEG cc2430/dev/bus.c # Files with ISRs must be in HOME
CSEG autostart.c HOME intr.c # Match all files ending in intr.c (e.g. uart_intr.c)
BANK2 cc2430/dev/cc2430_rf.c HOME rtimer-arch.c
BANK1 cc2430/ HOME watchdog-cc2430.c
BANK1 . HOME clock.c
# Some cc2430 files which need special treatment
HOME bus.c # bus.c::flash_read() must be run from HOME (if compiled in)

View file

@ -1,11 +0,0 @@
$match_me = pop @ARGV;
#print "searching for $match_me\n";
while (<>) {
s/#.*$//; # filter out comments
s/^\s*//; # filter out leading white space
@F=split /\s+/; # split on white space
if (($_ =~ m/\S\s+\S/) && ($match_me =~ m/$F[1]/)) {
print $F[0]."\n";
exit; #return only first match
}
}

View file

@ -1,221 +0,0 @@
;;;
;;;
;;; uip_arch-asm.S
;;;
;;; \file
;;; Z80 architecture-depend uip module
;;; for calculating checksums
;;;
;;; \author
;;; Takahide Matsutsuka <markn@markn.org>
;;;
.module uip_arch-asm
;; export symbols
.globl _uip_add32
.globl _uip_arch_chksum
.globl _uip_chksum
;; import symbols
.globl _uip_acc32
.globl _uip_buf
.area _DATA
.area _GSINIT
.area _CODE
;; ---------------------------------
;; void uip_add32(uint8_t *op32, uint16_t op16);
;; Stack; retl reth op32l op32h op16l op16h
;; ABCDEHL____
;; return void
;; _uip_acc32 = op32 + op16
;; ---------------------------------
_uip_add32_start::
_uip_add32:
;; HL = #_op32l
ld hl, #2
add hl, sp
;; DE = #(_op32)
ld e, (hl)
inc hl
ld d, (hl)
inc hl
;; BC = op16
ld c, (hl)
inc hl
ld b, (hl)
;; HL = #(_op32) + 3
ld hl, #3
add hl, de
;; DE = #_uip_acc32 + 3
ld de, #_uip_acc32 + 3
;; uip_acc32[3] = op32[3] + op16l;
ld a, (hl)
add a, c
ld (de), a
;; uip_acc32[2] = op32[2] + op16h + carry;
dec hl
dec de
ld a, (hl)
adc a, b
ld (de), a
jr nc, _uip_add32_nocarry1
;; uip_acc32[1]
dec hl
dec de
ld a, (hl)
inc a
ld (de), a
jr nz, _uip_add32_nocarry0
;; uip_acc32[0]
dec hl
dec de
ld a, (hl)
inc a
ld (de), a
ret
_uip_add32_nocarry1:
;; uip_acc32[1]
dec hl
dec de
ld a, (hl)
ld (de), a
_uip_add32_nocarry0:
;; uip_acc32[0]
dec hl
dec de
ld a, (hl)
ld (de), a
ret
_uip_add32_end::
;; ---------------------------------
;; static uint16_t chksum(uint16_t sum, const uint8_t *data, uint16_t len)
;; Stack; retl reth suml sumh datal datah lenl lenh
;; ABCDEHL____
;; return HL
;; ---------------------------------
_uip_arch_chksum_start::
_uip_arch_chksum:
push ix
;; IX = #_suml
ld ix, #4
add ix, sp
;; BC = sum
ld c, 0(ix)
ld b, 1(ix)
;; DE = #data
ld e, 2(ix)
ld d, 3(ix)
;; (lenl, lenh) <- dataptr + len - 1 (last address)
;; (len) + DE - 1 -> (len)
ld l, 4(ix)
ld h, 5(ix)
add hl, de
dec hl
ld 4(ix), l
ld 5(ix), h
_uip_arch_chksum_loop:
;; compare HL(last address) and DE(dataptr)
;; HL - DE
;; if (HL < DE) C,NZ else if (HL = DE) NC,Z=1 otherwise NC,NZ
;; HL = last address, DE = current pointer
ld l, 4(ix)
ld h, 5(ix)
ld a, h
sub d
jr nz, _uip_arch_chksum_compared
ld a, l
sub e
;; if (last address == dataptr) _uip_arch_chksum_loop_exit_add_trailing
jr z, _uip_arch_chksum_loop_exit_add_trailing
_uip_arch_chksum_compared:
;; if (last address > dataptr) _uip_arch_chksum_loop_exit
jr c, _uip_arch_chksum_loop_exit
;; bc = dataptr[0],dataptr[1] + bc
ld a, (de)
ld h, a
inc de
ld a, (de)
ld l, a
push hl
add hl, bc
inc de
ld b, h
ld c, l
;; HL = t
pop hl
;; BC - HL
;; if (sumBC < tHL) sum++
ld a, b
sub h
jr nz, _uip_arch_chksum_compared_t
ld a, c
sub l
_uip_arch_chksum_compared_t:
jr nc, _uip_arch_chksum_nocarry_t
inc bc
_uip_arch_chksum_nocarry_t:
jr _uip_arch_chksum_loop
_uip_arch_chksum_loop_exit_add_trailing:
;; HL = last address
;; bc = bc + (last address)<<8
ld a, b
add a, (hl)
ld b, a
jr nc, _uip_arch_chksum_loop_exit
inc bc
_uip_arch_chksum_loop_exit:
ld l, c
ld h, b
pop ix
ret
_uip_arch_chksum_end::
;; ---------------------------------
;; uint16_t uip_chksum(void);
;; Stack; retl reth datal datah lenl lenh
;; ABCDEHL____
;; return HL
;; return htons(chksum(0, (uint8_t *)data, len));
;; ---------------------------------
_uip_chksum_start::
_uip_chksum:
ld hl, #5
add hl, sp
;; HL indicates #_lenh
ld b, #2
_uip_chksum_loop:
ld d, (hl)
dec hl
ld e, (hl)
dec hl
push de
djnz _uip_chksum_loop
ld bc, #0
push bc
call _uip_arch_chksum
pop af
pop af
pop af
;; convert to BIG ENDIAN (htons)
ld a, l
ld l, h
ld h, a
ret
_uip_chksum_end::

View file

@ -1,216 +0,0 @@
/*
* Copyright (c) 2007, Takahide Matsutsuka.
* 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.
*
* $Id: uip_arch.c,v 1.2 2010/10/19 18:29:04 adamdunkels Exp $
*
*/
/*
* \file
* Z80 architecture-depend uip module
* for calculating checksums
* \author
* Takahide Matsutsuka <markn@markn.org>
*/
#include <stddef.h>
#include "uip_arch.h"
static const uint16_t sizeof_uip_ipaddr_t = sizeof(uip_ipaddr_t);
static const uint16_t offset_tcpip_hdr_len = offsetof(struct uip_tcpip_hdr, len);
static const uint16_t offset_tcpip_hdr_srcipaddr = offsetof(struct uip_tcpip_hdr, srcipaddr);
/*--------------------------------------------------------------------------*/
static void upper_layer_chksum() {
__asm
;; ---------------------------------
;; static uint16_t upper_layer_chksum(uint8_t proto);
;; Stack; retl reth
;; @param C proto
;; ABCDEHL____
;; ---------------------------------
;; HL = BUF = &uip_buf[UIP_LLH_LEN]
ld hl, #_uip_buf
ld de, #UIP_LLH_LEN
add hl, de
push hl
;; HL = BUF->len[0]
push ix
ld ix, #_offset_tcpip_hdr_len
ld e, 0(ix)
ld d, 1(ix)
add hl, de
pop ix
;; DE = upper layer length
ld d, (hl)
inc hl
ld e, (hl)
#if UIP_CONF_IPV6
#else
ld a, e
sub a, #UIP_IPH_LEN
ld e, a
jr nc, _upper_layer_chksum_setlen2
dec d
_upper_layer_chksum_setlen2:
#endif
;; bc = upper_leyer_len + proto
ld b, d
ld a, e
add a, c
ld c, a
jr nc, _upper_layer_chksum_setlen3
inc b
_upper_layer_chksum_setlen3:
pop hl ; BUF
push de
push ix
ld ix, #_offset_tcpip_hdr_srcipaddr
ld e, 0(ix)
ld d, 1(ix)
add hl, de
ld e, l
ld d, h
ld ix, #_sizeof_uip_ipaddr_t
ld l, 0(ix)
ld h, 1(ix)
pop ix
sla l
rl h
push hl
push de
push bc
call _uip_arch_chksum ; hl = sum
pop af
pop af
pop af
;; de is still stacked
ld b, h
ld c, l
ld hl, #_uip_buf
ld de, #UIP_IPH_LEN
add hl, de
_upper_layer_chksum_call:
ld de, #UIP_LLH_LEN
add hl, de
push hl
push bc
call _uip_arch_chksum
pop af
pop af
pop af
ld a, h
or a, l
jr nz, _upper_layer_uip_htons
ld hl, #0xffff
jr _upper_layer_ret
_upper_layer_uip_htons:
ld a, l
ld l, h
ld h, a
_upper_layer_ret:
__endasm;
}
/*--------------------------------------------------------------------------*/
uint16_t
uip_ipchksum(void)
{
__asm
;; ---------------------------------
;; uint16_t uip_ipchksum(void);
;; Stack; retl reth
;; ABCDEHL____
;; return HL
;; ---------------------------------
ld hl, #UIP_IPH_LEN
push hl
;; HL = BUF = &uip_buf[UIP_LLH_LEN]
ld hl, #_uip_buf
;; BC = sum = 0
ld bc, #0
jp _upper_layer_chksum_call
__endasm;
}
/*--------------------------------------------------------------------------*/
#if UIP_CONF_IPV6
uint16_t
uip_icmp6chksum(void)
{
__asm
;; ---------------------------------
;; uint16_t uip_icmp6chksum(void);
;; Stack; retl reth
;; ABCDEHL____
;; return HL
;; ---------------------------------
ld c, #UIP_PROTO_ICMP6
jp _upper_layer_chksum
__endasm;
}
#endif /* UIP_CONF_IPV6 */
/*--------------------------------------------------------------------------*/
uint16_t
uip_tcpchksum(void)
{
__asm
;; ---------------------------------
;; uint16_t uip_tcpchksum(void);
;; Stack; retl reth
;; ABCDEHL____
;; return HL
;; ---------------------------------
ld c, #UIP_PROTO_TCP
jp _upper_layer_chksum
__endasm;
}
/*--------------------------------------------------------------------------*/
#if UIP_UDP_CHKSUMS
uint16_t
uip_udpchksum(void)
{
__asm
;; ---------------------------------
;; uint16_t uip_udpchksum(void);
;; Stack; retl reth
;; ABCDEHL____
;; return HL
;; ---------------------------------
ld c, #UIP_PROTO_UDP
jp _upper_layer_chksum
__endasm;
}
#endif /* UIP_UDP_CHKSUMS */
/*--------------------------------------------------------------------------*/

79
cpu/cc253x/8051def.h Normal file
View file

@ -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 <markn@markn.org> (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net>
* (updates for the cc2530 ports)
*/
#ifndef __8051_DEF_H__
#define __8051_DEF_H__
#include <stdint.h>
/*
* 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__ */

198
cpu/cc253x/Makefile.cc253x Normal file
View file

@ -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

245
cpu/cc253x/bank-alloc.py Normal file
View file

@ -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 - <oikonomou@users.sourceforge.net>
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()

669
cpu/cc253x/cc253x.h Normal file
View file

@ -0,0 +1,669 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 2009Revised September 2010
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef __CC253X_H__
#define __CC253X_H__
/*---------------------------------------------------------------------------*/
/* Compiler Abstraction */
#include <compiler.h>
/*---------------------------------------------------------------------------
* 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 14 configuration address low */
SFR(DMA1CFGH, 0xD3); /* DMA channel 14 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 (0x60000x63FF), 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{15} */
SFRX(USBCS0, 0x6211); /* EP0 Control and Status (USBINDEX = 0) */
SFRX(USBCSIL, 0x6211); /* IN EP{15} Control and Status, Low */
SFRX(USBCSIH, 0x6212); /* IN EP{15} Control and Status, High */
SFRX(USBMAXO, 0x6213); /* Max. Packet Size for OUT EP{15} */
SFRX(USBCSOL, 0x6214); /* OUT EP{15} Control and Status, Low */
SFRX(USBCSOH, 0x6215); /* OUT EP{15} Control and Status, High */
SFRX(USBCNT0, 0x6216); /* Number of Received Bytes in EP0 FIFO (USBINDEX = 0) */
SFRX(USBCNTL, 0x6216); /* Number of Bytes in EP{15} OUT FIFO, Low */
SFRX(USBCNTH, 0x6217); /* Number of Bytes in EP{15} 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 14 configuration address low */
SFRX(X_DMA1CFGH, 0x70D3); /* DMA channel 14 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__ */

489
cpu/cc253x/dev/cc2530-rf.c Normal file
View file

@ -0,0 +1,489 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 - <oikonomou@users.sourceforge.net>
*/
#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 <string.h>
/*---------------------------------------------------------------------------*/
#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,
};
/*---------------------------------------------------------------------------*/

127
cpu/cc253x/dev/cc2530-rf.h Normal file
View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 - <oikonomou@users.sourceforge.net>
*/
#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__ */

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 - <oikonomou@users.sourceforge.net>
*/
#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__ */

182
cpu/cc253x/dev/clock.c Normal file
View file

@ -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 - <oikonomou@users.sourceforge.net> - 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();
}
/*---------------------------------------------------------------------------*/

69
cpu/cc253x/dev/dma.c Normal file
View file

@ -0,0 +1,69 @@
/**
* \file
* Driver for the cc2430 DMA controller. Can be assigned to any bank
*
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
* Further Modifications:
* George Oikonomou <oikonomou@users.sourceforge.net>
*
*/
#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

148
cpu/cc253x/dev/dma.h Normal file
View file

@ -0,0 +1,148 @@
/**
* \file
* Header file for the cc2430 DMA controller
*
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
* Further Modifications:
* George Oikonomou <oikonomou@users.sourceforge.net>
*/
#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*/

68
cpu/cc253x/dev/dma_intr.c Normal file
View file

@ -0,0 +1,68 @@
/**
* \file
* DMA driver ISRs
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
*
* DMA interrupt routines, must be stored in HOME bank
*/
#include <stdio.h>
#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;
}
/*---------------------------------------------------------------------------*/

57
cpu/cc253x/dev/lpm.h Normal file
View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#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__ */

145
cpu/cc253x/dev/port.h Normal file
View file

@ -0,0 +1,145 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 - <oikonomou@users.sourceforge.net>
*/
#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__ */

111
cpu/cc253x/dev/random.c Normal file
View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 - <oikonomou@users.sourceforge.net>
*/
#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();
}

View file

@ -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 */

43
cpu/cc253x/dev/uart.h Normal file
View file

@ -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 */

75
cpu/cc253x/dev/uart0.c Normal file
View file

@ -0,0 +1,75 @@
/**
* \file
*
* uart0 write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
*/
#include <stdlib.h>
#include <string.h>
#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

41
cpu/cc253x/dev/uart0.h Normal file
View file

@ -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 */

74
cpu/cc253x/dev/uart1.c Normal file
View file

@ -0,0 +1,74 @@
/**
* \file
*
* uart1 write routines
*
* \author
*
* Anthony "Asterisk" Ambuehl
*
*/
#include <stdlib.h>
#include <string.h>
#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

38
cpu/cc253x/dev/uart1.h Normal file
View file

@ -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 */

88
cpu/cc253x/dev/watchdog.c Normal file
View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#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;
}
}

View file

@ -1,19 +1,19 @@
/* /*
* Copyright (c) 2007, Takahide Matsutsuka. * Copyright (c) 2010, Loughborough University - Computer Science
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above * 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* 3. The name of the author may not be used to endorse or promote * 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior * products derived from this software without specific prior
* written permission. * written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -25,52 +25,26 @@
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: rs232.c,v 1.1 2009/09/08 20:07:35 zdshelby Exp $
* *
*/ */
/*
* \file
* This is RS-232C process based on polling.
* Note that rs232.c and rs232-slip.c cannot be used at the same time.
* \author
* Takahide Matsutsuka <markn@markn.org>
*/
#include "contiki.h" /*
#include "dev/slip.h" * \file
#include "dev/serial.h" * Stub header file for multi-threading. It doesn't do anything, it
#include "dev/rs232.h" * 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 - <oikonomou@users.sourceforge.net>
*/
#ifndef __MTARCH_H__
#define __MTARCH_H__
PROCESS(rs232_process, "RS-232C polling process"); struct mtarch_thread {
/*---------------------------------------------------------------------------*/ unsigned char *sp;
PROCESS_THREAD(rs232_process, ev, data) };
{
static struct etimer timer;
char ch;
unsigned char i, stat;
PROCESS_BEGIN();
rs232_arch_init(RS232_BAUD_RATE); #endif /* __MTARCH_H__ */
etimer_set(&timer, CLOCK_SECOND / 16);
while(1) {
PROCESS_WAIT_EVENT();
if (etimer_expired(&timer)) {
for (i = 0; i < RS232_BUFSIZE; i++) {
ch = rs232_arch_poll(&stat);
if (stat == 0) {
break;
}
/* We have an input data */
RS232_CALLBACK(ch);
}
etimer_reset(&timer);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

113
cpu/cc253x/rtimer-arch.c Normal file
View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#include "sys/rtimer.h"
#include "sfr-bits.h"
#include "cc253x.h"
#include "sys/energest.h"
#include "debug.h"
#include <stdio.h>
#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 */
}

61
cpu/cc253x/rtimer-arch.h Normal file
View file

@ -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 - <oikonomou@users.sourceforge.net>
* (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__ */

22
cpu/cc253x/segment.rules Normal file
View file

@ -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

195
cpu/cc253x/sfr-bits.h Normal file
View file

@ -0,0 +1,195 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 - <oikonomou@users.sourceforge.net>
*/
#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_ */

54
cpu/cc253x/soc.c Normal file
View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 - <oikonomou@users.sourceforge.net>
*/
#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();
}

46
cpu/cc253x/soc.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
* 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 - <oikonomou@users.sourceforge.net>
*/
#ifndef __SOC_H__
#define __SOC_H__
void soc_init();
#endif /* __SOC_H__ */

View file

@ -0,0 +1,6 @@
CONTIKI_PROJECT = hello-world blink-hello timer-test sensors-demo
all: $(CONTIKI_PROJECT)
CONTIKI = ../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1 @@
TARGET = cc2530dk

View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#include "contiki.h"
#include "dev/leds.h"
#include <stdio.h> /* 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();
}
/*---------------------------------------------------------------------------*/

View file

@ -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

View file

@ -0,0 +1 @@
TARGET = cc2530dk

View file

@ -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 <address v6>/<prefix>
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.

View file

@ -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 <string.h>
#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();
}
/*---------------------------------------------------------------------------*/

View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#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_ */

View file

@ -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 <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
*/
#include "net/uip.h"
#include "net/uip-ds6.h"
#include "net/rpl/rpl.h"
#include "dev/slip.h"
#include <string.h>
#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
};
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,23 @@
/**
* \file
* Basic hello world example
* \author
* Zach Shelby <zach@sensinode.com>
*/
#include "contiki.h"
#include <stdio.h> /* 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();
}
/*---------------------------------------------------------------------------*/

View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#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 <stdio.h>
#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();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,10 @@
DEFINES+=PROJECT_CONF_H
PROJECT_SOURCEFILES += stub-rdc.c
CONTIKI_PROJECT = sniffer
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1 @@
TARGET = cc2530dk

View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#include "netstack.h"
/*---------------------------------------------------------------------------*/
void
netstack_init(void)
{
NETSTACK_RADIO.init();
}
/*---------------------------------------------------------------------------*/

View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#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_ */

View file

@ -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();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,100 @@
/*
* 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 - <oikonomou@users.sourceforge.net>
*/
#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
send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list)
{
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,
send_list,
input,
on,
off,
cca,
};
/*---------------------------------------------------------------------------*/

View file

@ -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 <zach@sensinode.com> (Original)
* George Oikonomou - <oikonomou@users.sourceforge.net> (rtimer code)
*
*/
#include "contiki.h"
#include "sys/clock.h"
#include "sys/rtimer.h"
#include "dev/leds.h"
#include <stdio.h>
/*---------------------------------------------------------------------------*/
#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();
}
/*---------------------------------------------------------------------------*/

View file

@ -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

View file

@ -0,0 +1 @@
TARGET = cc2530dk

View file

@ -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 <string.h>
#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();
}
/*---------------------------------------------------------------------------*/

View file

@ -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 <string.h>
#include <stdio.h>
#include "dev/button-sensor.h"
#include "debug.h"
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#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();
}
/*---------------------------------------------------------------------------*/

View file

@ -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 - <oikonomou@users.sourceforge.net>
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#define BUTTON_SENSOR_CONF_ON 1
#define UIP_CONF_ICMP6 1
#endif /* PROJECT_CONF_H_ */

View file

@ -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 <string.h>
#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();
}
/*---------------------------------------------------------------------------*/

View file

@ -99,14 +99,13 @@ test_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_
uint8_t method = REST.get_method_type(request); uint8_t method = REST.get_method_type(request);
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid));
PRINTF("/test "); PRINTF("/test ");
if (method & METHOD_GET) if (method & METHOD_GET)
{ {
PRINTF("GET "); PRINTF("GET ");
/* Code 2.05 CONTENT is default. */ /* Code 2.05 CONTENT is default. */
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid));
} }
else if (method & METHOD_POST) else if (method & METHOD_POST)
{ {
@ -215,7 +214,7 @@ separate_handler(void* request, void* response, uint8_t *buffer, uint16_t prefer
} }
else else
{ {
PRINTF("ACKED "); PRINTF("STORED ");
separate_active = 1; separate_active = 1;
/* Take over and skip response by engine. */ /* Take over and skip response by engine. */
@ -237,7 +236,7 @@ separate_periodic_handler(resource_t *resource)
coap_transaction_t *transaction = NULL; coap_transaction_t *transaction = NULL;
if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) ) if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) )
{ {
PRINTF("RESPONSE"); PRINTF("RESPONSE (%s %u)\n", separate_store->request_metadata.type==COAP_TYPE_CON?"CON":"NON", separate_store->request_metadata.mid);
coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */
@ -262,7 +261,7 @@ separate_periodic_handler(resource_t *resource)
return 1; return 1;
} else { } else {
PRINTF("ERROR (transaction)"); PRINTF("ERROR (transaction)\n");
} }
} /* if (separate_active) */ } /* if (separate_active) */

View file

@ -2,7 +2,17 @@ ifndef TARGET
TARGET=sensinode TARGET=sensinode
endif endif
# Make absolutely certain that you specify your device here
DEFINES+=MODEL_N740
# These examples don't need code banking so we turn it off
#HAVE_BANKING=1
CONTIKI_PROJECT = hello_world clock_test rf_test_rx rf_test_tx CONTIKI_PROJECT = hello_world clock_test rf_test_rx rf_test_tx
# New examples added by George Oikonomou - Loughborough University
CONTIKI_PROJECT += timer-test blink-hello broadcast-rime
all: $(CONTIKI_PROJECT) all: $(CONTIKI_PROJECT)
CONTIKI = ../.. CONTIKI = ../..

View file

@ -1,6 +1,11 @@
Sensinode platform example and test applications Sensinode platform example and test applications
- by Zach Shelby (zach@sensinode.com) - by Zach Shelby (zach@sensinode.com)
Some more examples by George Oikonomou - Loughborough University
cc2431-location-engine, udp-ipv6, broadcast-rime
blink-hello, event-post, timer-test
<oikonomou@users.sourceforge.net>
This directory contains example and test applications for This directory contains example and test applications for
Sensinode CC2430 based devices. By default it is set to use the Sensinode CC2430 based devices. By default it is set to use the
sensinode platform: sensinode platform:
@ -32,8 +37,21 @@ These make options are defined in /platform/sensinode/Makefile.sensinode
Descriptions of applications: Descriptions of applications:
hello_world A simple hello world app. hello_world A simple hello world app.
clock_test Test and example of sys/clock.h related features. clock_test Test and example of sys/clock.h related features.
rf_test_tx Test for transmitting packets rf_test_tx Test for transmitting packets
rf_test_rc Test for receiving packets rf_test_rc Test for receiving packets
Recent Additions:
udp-ipv6 UDP client-server example over uIPv6. Uses link-local and global
addresses. Button 1 on the client will send an echo request.
broadcast-rime Just a broadcast rime example, slightly modified
sensors Demonstrating button and ADC functionality
cc2431-location-engine
Example demonstrating the usage cc2431 location engine (blind node)
N.B. Not all sensinode devides have a cc2431
event-post Demonstrating the interaction between two processes with custom events
blink-hello Hello World with LED blinking.
timer-test Same as clock_test above + testing the rtimer-arch code
border-router 802.15.4 to SLIP bridge example. The node will forward packets
from the 15.4 network to its UART (and thus a connected PC over SLIP)

View file

@ -0,0 +1,91 @@
/* 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 <G.Oikonomou@lboro.ac.uk>
*/
#include "contiki.h"
#include "dev/leds.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
/* We declare the two processes */
PROCESS(hello_world_process, "Hello world process");
PROCESS(blink_process, "LED blink process");
/* We require the processes to be started automatically */
AUTOSTART_PROCESSES(&hello_world_process, &blink_process);
/*---------------------------------------------------------------------------*/
/* Implementation of the first process */
PROCESS_THREAD(hello_world_process, ev, data)
{
/* variables are declared static to ensure their values are maintained
between subsequent calls.
All the code between PROCESS_THREAD and PROCESS_BEGIN() runs each time
the process is invoked. */
static struct etimer timer;
static int count;
/* any process must start with this. */
PROCESS_BEGIN();
/* set the etimer module to generate an event in one second.
CLOCK_CONF_SECOND is #define as 128 */
etimer_set(&timer, CLOCK_CONF_SECOND * 4);
count = 0;
/* Don't declare variables after PROCESS_BEGIN.
* While it will compile fine with TARGET=native (gcc is happy),
* SDCC doesn't like it. Soon as you try TARGET=sensinode you will get:
* syntax error: token -> 'int' ;
* Try uncommenting the line below and observe the results */
/* int whoops = 0;
* whoops = 0; */
while (1)
{
/* wait here for an event to happen */
PROCESS_WAIT_EVENT();
/* This achieves the same
* PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); */
/* if the event is the timer event as expected... */
if(ev == PROCESS_EVENT_TIMER)
{
/* do the process work */
printf("Sensor says no... #%d\r\n", count);
count ++;
/* reset the timer so it will generate an other event
* the exact same time after it expired (periodicity guaranteed) */
etimer_reset(&timer);
}
/* and loop */
}
/* any process must end with this, even if it is never reached. */
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/* Implementation of the second process */
PROCESS_THREAD(blink_process, ev, data)
{
static struct etimer timer;
PROCESS_BEGIN();
while (1)
{
/* we set the timer from here every time */
etimer_set(&timer, CLOCK_CONF_SECOND);
/* and wait until the event we receive is the one we're waiting for */
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
printf("Blink... (state %0.2X).\r\n", leds_get());
/* update the LEDs */
leds_toggle(LEDS_GREEN);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

Some files were not shown because too many files have changed in this diff Show more