Initial commit of cc2430 cpu port files. Currently used by /platform/sensinode.

This commit is contained in:
zdshelby 2009-09-08 20:07:35 +00:00
parent c4ae18e37b
commit c9954072c9
19 changed files with 3434 additions and 0 deletions

83
cpu/cc2430/8051def.h Normal file
View file

@ -0,0 +1,83 @@
/*
* \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>
*/
#ifndef __8051_DEF_H__
#define __8051_DEF_H__
#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 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 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;
typedef signed long int32_t; /* 32 bit type */
#ifndef _SIZE_T_DEFINED
#define _SIZE_T_DEFINED
typedef unsigned int size_t;
#endif
/* Compiler configurations */
#define CCIF
#define CLIF
#define CC_CONF_CONST_FUNCTION_BUG
/* Critical section management */
#define DISABLE_INTERRUPTS() EA = 0;
#define ENABLE_INTERRUPTS() EA = 1;
#define ENTER_CRITICAL() \
{ \
__asm \
push ACC \
push IE \
__endasm; \
} \
EA = 0;
#define EXIT_CRITICAL() \
{ \
__asm \
pop ACC \
__endasm; \
ACC &= 0x80; \
IE |= ACC; \
__asm \
pop ACC \
__endasm; \
}
/*
* Enable architecture-depend checksum calculation
* for uIP configuration.
* @see uip_arch.h
* @see uip_arch-asm.S
*/
#define UIP_ARCH_ADD32 1
#define UIP_ARCH_CHKSUM 1
#define UIP_ARCH_IPCHKSUM
#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__ */

View file

@ -0,0 +1,71 @@
CONTIKI_CPU_DIRS = . net
CONTIKI_SOURCEFILES += #mtarch.c rtimer-arch.c elfloader-stub.c watchdog.c
### Compiler definitions
CC = sdcc
LD = sdcc
AS = sdcc
AR = sdcclib
OBJCOPY = objcopy
STRIP = strip
CFLAGS += --std-c99 --model-large --stack-auto -DSDCC_CC2430
CFLAGS += -DRIME_CONF_NO_POLITE_ANNOUCEMENTS
ASFLAGS += -plosgff
LDFLAGS += --model-large --stack-auto -DSDCC_CC2430 --out-fmt-ihx
LDFLAGS += --xram-loc 57344 --xram-size 8192
AROPTS = -a
### CPU-dependent cleanup files
CLEAN += *.lnk *.sym *.lib *.ihx *.rel *.mem *.rst *.asm
### CPU-dependent directories
CONTIKI_CPU_DIRS = . dev
### CPU-dependent source files
CONTIKI_SOURCEFILES += bus.c clock.c uart.c cc2430_rf.c dma.c
CONTIKI_ASMFILES +=
CONTIKI_ASMOBJECTFILES = ${addprefix $(OBJECTDIR)/,$(CONTIKI_ASMFILES:.S=.o)}
CONTIKI_CASMOBJECTFILES = ${addprefix $(OBJECTDIR)/,$(CONTIKI_CASMFILES:.cS=.o)}
CONTIKI_PLATFORM_DIRS = $(PLATFORM_APPDIRS) \
${addprefix $(CONTIKI)/platform/$(TARGET)/, $(CONTIKI_TARGET_DIRS)}
### Compilation rules
#CUSTOM_RULE_C_TO_OBJECTDIR_O=1
CUSTOM_RULE_ALLOBJS_TO_TARGETLIB=1
ifdef CUSTOM_RULE_CS_TO_OBJECTDIR_O
$(OBJECTDIR)/%.o: %.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
endif
#CUSTOM_RULE_ALLOBJS_TO_TARGETLIB
contiki-$(TARGET).lib: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) $(CONTIKI_ASMOBJECTFILES) $(CONTIKI_CASMOBJECTFILES)
rm -f $@
for target in $^; do echo $$target >> $@; done
%.$(TARGET): %.ihx
# .rel is the object file default suffix under sdcc
%.rel: %.co
mv $< $@
# .ihx is the sdcc binary output file
.PRECIOUS: %.ihx %.rel
# .ihx is the sdcc binary output file
%.ihx: %.rel $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).lib
$(CC) $(LDFLAGS) -o $@ $*.rel -lcontiki-$(TARGET).lib
# Force the compilation of %.$(TARGET) to compile the %.ihx file.
%.$(TARGET): %.ihx
@

703
cpu/cc2430/cc2430_sfr.h Normal file
View file

@ -0,0 +1,703 @@
/**
*
* \file cc2430_sfr.h
* \brief CC2430 registers header file for CC2430.
*
* Definitions for CC2430 SFR registers.
*
*
*/
#ifndef REG_CC2430_H
#define REG_CC2430_H
/* BYTE Register */
__sfr __at (0x80) P0 ;
/* P0 */
__sbit __at (0x87) P0_7 ;
__sbit __at (0x86) P0_6 ;
__sbit __at (0x85) P0_5 ;
__sbit __at (0x84) P0_4 ;
__sbit __at (0x83) P0_3 ;
__sbit __at (0x82) P0_2 ;
__sbit __at (0x81) P0_1 ;
__sbit __at (0x80) P0_0 ;
__sfr __at (0x81) SP ;
__sfr __at (0x82) DPL0 ;
__sfr __at (0x83) DPH0 ;
/*DPL and DPH correspond DPL0 and DPH0 (82-83)*/
__sfr __at (0x84) DPL1;
__sfr __at (0x85) DPH1;
__sfr __at (0x86) U0CSR;
#define U_MODE 0x80
#define U_RE 0x40
#define U_SLAVE 0x20
#define U_FE 0x10
#define U_ERR 0x08
#define U_RXB 0x04
#define U_TXB 0x02
#define U_ACTIVE 0x01
__sfr __at (0x87) PCON ;
/* PCON (0x87) */
#define IDLE 0x01
__sfr __at (0x88) TCON ;
/* TCON (0x88) */
__sbit __at (0x8F) TCON_URX1IF;
/*__sbit __at (0x8E) RES;*/
__sbit __at (0x8D) TCON_ADCIF;
/*__sbit __at (0x8C) RES;*/
__sbit __at (0x8B) TCON_URX0IF;
__sbit __at (0x8A) TCON_IT1;
__sbit __at (0x89) TCON_RFERRIF;
__sbit __at (0x88) TCON_IT0;
__sfr __at (0x89) P0IFG;
__sfr __at (0x8A) P1IFG;
__sfr __at (0x8B) P2IFG;
__sfr __at (0x8C) PICTL;
/*PICTL bits*/
#define PADSC 0x40
#define P2IEN 0x20
#define P0IENH 0x10
#define P0IENL 0x08
#define P2ICON 0x04
#define P1ICON 0x02
#define P0ICON 0x01
__sfr __at (0x8D) P1IEN;
__sfr __at (0x8F) P0INP;
__sfr __at (0x90) P1 ;
/* P1 */
__sbit __at (0x90) P1_0 ;
__sbit __at (0x91) P1_1 ;
__sbit __at (0x92) P1_2 ;
__sbit __at (0x93) P1_3 ;
__sbit __at (0x94) P1_4 ;
__sbit __at (0x95) P1_5 ;
__sbit __at (0x96) P1_6 ;
__sbit __at (0x97) P1_7 ;
__sfr __at (0x91) RFIM;
__sfr __at (0x92) DPS;
__sfr __at (0x93) _XPAGE; /*MPAGE as paging register for sdcc*/
__sfr __at (0x94) T2CMP;
__sfr __at (0x95) ST0;
__sfr __at (0x96) ST1;
__sfr __at (0x97) ST2;
__sfr __at (0x98) S0CON ;
__sbit __at (0x99) S0CON_ENCIF_1;
__sbit __at (0x98) S0CON_ENCIF_0;
__sfr __at (0x99) HSRC;
__sfr __at (0x9A) IEN2;
/*IEN2 bits*/
#define WDTIE 0x20
#define P1IE 0x10
#define UTX1IE 0x08
#define UTX0IE 0x04
#define P2IE 0x02
#define RFIE 0x01
__sfr __at (0x9B) S1CON;
/*S1CON bits*/
#define RFIF_1 0x02
#define RFIF_0 0x01
__sfr __at (0x9C) T2PEROF0;
__sfr __at (0x9D) T2PEROF1;
__sfr __at (0x9E) T2PEROF2;
/*T2PEROF2 bits*/
#define CMPIM 0x80
#define PERIM 0x40
#define OFCMPIM 0x20
#define PEROF23 0x08
#define PEROF22 0x04
#define PEROF21 0x02
#define PEROF20 0x01
__sfr __at (0x9F) FMAP;
__sfr __at (0xA0) P2 ;
/* P2 */
__sbit __at (0xA0) P2_0 ;
__sbit __at (0xA1) P2_1 ;
__sbit __at (0xA2) P2_2 ;
__sbit __at (0xA3) P2_3 ;
__sbit __at (0xA4) P2_4 ;
/*__sbit __at (0xA5) P2_5 ;
__sbit __at (0xA6) P2_6 ;
__sbit __at (0xA7) P2_7 ;*/
__sfr __at (0xA1) T2OF0;
__sfr __at (0xA2) T2OF1;
__sfr __at (0xA3) T2OF2;
__sfr __at (0xA4) T2CAPLPL;
__sfr __at (0xA5) T2CAPHPH;
__sfr __at (0xA6) T2TLD;
__sfr __at (0xA7) T2THD;
__sfr __at (0xA8) IE ;
__sfr __at (0xA8) IEN0;
/*IEN0 bits*/
#define IEN0_EA_MASK 0x80
#define STIE 0x20
#define ENCIE 0x10
#define URX1IE 0x08
#define URX0IE 0x04
#define ADCIE 0x02
#define RFERRIE 0x01
/* IEN0 (0xA8) */
__sbit __at (0xAF) EA;
__sbit __at (0xAF) IEN0_EA;
/*__sbit __at (0xAE) RES;*/
__sbit __at (0xAD) IEN0_STIE;
__sbit __at (0xAC) IEN0_ENCIE;
__sbit __at (0xAB) IEN0_URX1IE;
__sbit __at (0xAA) IEN0_URX0IE;
__sbit __at (0xA9) IEN0_ADCIE;
__sbit __at (0xA8) IEN0_RFERRIE;
__sfr __at (0xA9) IP0;
/*IP0 bits*/
#define IP0_5 0x20
#define IP0_4 0x10
#define IP0_3 0x08
#define IP0_2 0x04
#define IP0_1 0x02
#define IP0_0 0x01
__sfr __at (0xAB) FWT;
__sfr __at (0xAC) FADDRL;
__sfr __at (0xAD) FADDRH;
__sfr __at (0xAE) FCTL;
#define F_BUSY 0x80
#define F_SWBSY 0x40
#define F_CONTRD 0x10
#define F_WRITE 0x02
#define F_ERASE 0x01
__sfr __at (0xAF) FWDATA;
/*No port 3 (0xB0)*/
__sfr __at (0xB1) ENCDI;
__sfr __at (0xB2) ENCDO;
__sfr __at (0xB3) ENCCS;
#define CCS_MODE2 0x40
#define CCS_MODE1 0x20
#define CCS_MODE0 0x10
#define CCS_RDY 0x08
#define CCS_CMD1 0x04
#define CCS_CMD0 0x02
#define CCS_ST 0x01
__sfr __at (0xB4) ADCCON1;
/*ADCCON1 bits*/
#define ADEOC 0x80
#define ADST 0x40
#define ADSTS1 0x20
#define ADSTS0 0x10
#define ADRCTRL1 0x08
#define ADRCTRL0 0x04
__sfr __at (0xB5) ADCCON2;
/*ADCCON2 bits*/
#define ADSREF1 0x80
#define ADSREF0 0x40
#define ADSDIV1 0x20
#define ADSDIV0 0x10
#define ADSCH3 0x08
#define ADSCH2 0x04
#define ADSCH1 0x02
#define ADSCH0 0x01
__sfr __at (0xB6) ADCCON3;
/*ADCCON3 bits*/
#define ADEREF1 0x80
#define ADEREF0 0x40
#define ADEDIV1 0x20
#define ADEDIV0 0x10
#define ADECH3 0x08
#define ADECH2 0x04
#define ADECH1 0x02
#define ADECH0 0x01
__sfr __at (0xB7) RCCTL;
#undef IP /*this is 0xb8 in base core*/
__sfr __at (0xB8) IEN1;
/*IEN1 bits*/
#define P0IE 0x20
#define T4IE 0x10
#define T3IE 0x08
#define T2IE 0x04
#define T1IE 0x02
#define DMAIE 0x01
/* IEN1 (0xB8) */
/*__sbit __at (0xBF) IEN1_RES;*/
/*__sbit __at (0xBE) RES;*/
__sbit __at (0xBD) IEN1_P0IE;
__sbit __at (0xBC) IEN1_T4IE;
__sbit __at (0xBB) IEN1_T3IE;
__sbit __at (0xBA) IEN1_T2IE;
__sbit __at (0xB9) IEN1_T1IE;
__sbit __at (0xB8) IEN1_DMAIE;
__sfr __at (0xB9) IP1;
/*IP1 bits*/
#define IP1_5 0x20
#define IP1_4 0x10
#define IP1_3 0x08
#define IP1_2 0x04
#define IP1_1 0x02
#define IP1_0 0x01
__sfr __at (0xBA) ADCL;
__sfr __at (0xBB) ADCH;
__sfr __at (0xBC) RNDL;
__sfr __at (0xBD) RNDH;
__sfr __at (0xBE) SLEEP;
#define XOSC_STB 0x40
#define HFRC_STB 0x20
#define RST1 0x10
#define RST0 0x08
#define OSC_PD 0x04
#define SLEEP_MODE1 0x02
#define SLEEP_MODE0 0x01
__sfr __at (0xC0) IRCON;
/*IRCON bits*/
#define STIF 0x80
#define P0IF 0x20
#define T4IF 0x10
#define T3IF 0x08
#define T2IF 0x04
#define T1IF 0x02
#define DMAIF 0x01
/* IRCON */
__sbit __at (0xC7) IRCON_STIF ;
/*__sbit __at (0x86) IRCON_6 ;*/
__sbit __at (0xC5) IRCON_P0IF;
__sbit __at (0xC4) IRCON_T4IF;
__sbit __at (0xC3) IRCON_T3IF;
__sbit __at (0xC2) IRCON_T2IF;
__sbit __at (0xC1) IRCON_T1IF;
__sbit __at (0xC0) IRCON_DMAIF;
__sfr __at (0xC1) U0BUF;
__sfr __at (0xC2) U0BAUD;
__sfr __at (0xC3) T2CNF;
/*T2SEL bits*/
#define CMPIF 0x80
#define PERIF 0x40
#define OFCMPIF 0x20
#define CMSEL 0x08
#define SYNC 0x02
#define RUN 0x01
__sfr __at (0xC4) U0UCR;
#define U_FLUSH 0x80
#define U_FLOW 0x40
#define U_D9 0x20
#define U_BIT9 0x10
#define U_PARITY 0x08
#define U_SPB 0x04
#define U_STOP 0x02
#define U_START 0x01
__sfr __at (0xC5) U0GCR;
#define U_CPOL 0x80
#define U_CPHA 0x40
#define U_ORDER 0x20
#define U_BAUD_E4 0x10
#define U_BAUD_E3 0x08
#define U_BAUD_E2 0x04
#define U_BAUD_E1 0x02
#define U_BAUD_E0 0x01
__sfr __at (0xC6) CLKCON;
#define OSC32K 0x80
#define OSC 0x40
#define TICKSPD2 0x20
#define TICKSPD1 0x10
#define TICKSPD0 0x08
#define CLKSPD 0x01
__sfr __at (0xC7) MEMCTR;
#define MUNIF 0x40
__sfr __at (0xC8) T2CON;
__sfr __at (0xC9) WDCTL;
#define WDT_CLR3 0x80
#define WDT_CLR2 0x40
#define WDT_CLR1 0x20
#define WDT_CLR0 0x10
#define WDT_EN 0x08
#define WDT_MODE 0x04
#define WDT_INT1 0x02
#define WDT_INT0 0x01
__sfr __at (0xCA) T3CNT;
__sfr __at (0xCB) T3CTL;
/*T3CTL bits*/
#define T3DIV2 0x80
#define T3DIV1 0x40
#define T3DIV0 0x20
#define T3START 0x10
#define T3OVFIM 0x08
#define T3CLR 0x04
#define T3MODE1 0x02
#define T3MODE0 0x01
__sfr __at (0xCC) T3CCTL0;
/*T3CCTL0 bits*/
#define T3IM 0x40
#define T3CMP2 0x20
#define T3CMP1 0x10
#define T3CMP0 0x08
#define T3MODE 0x04
#define T3CAP1 0x02
#define T3CAP0 0x01
__sfr __at (0xCD) T3CC0;
__sfr __at (0xCE) T3CCTL1;
/*T3CCTL0 bits apply*/
__sfr __at (0xCF) T3CC1;
__sfr __at (0xD0) PSW ;
/* PSW */
__sbit __at (0xD0) P ;
__sbit __at (0xD1) F1 ;
__sbit __at (0xD2) OV ;
__sbit __at (0xD3) RS0 ;
__sbit __at (0xD4) RS1 ;
__sbit __at (0xD5) F0 ;
__sbit __at (0xD6) AC ;
__sbit __at (0xD7) CY ;
__sfr __at (0xD1) DMAIRQ;
/*DMAIRQ bits*/
#define DMAIF4 0x10
#define DMAIF3 0x08
#define DMAIF2 0x04
#define DMAIF1 0x02
#define DMAIF0 0x01
__sfr __at (0xD2) DMA1CFGL;
__sfr __at (0xD3) DMA1CFGH;
__sfr __at (0xD4) DMA0CFGL;
__sfr __at (0xD5) DMA0CFGH;
__sfr __at (0xD6) DMAARM;
/*DMAARM bits*/
#define ABORT 0x80
#define DMAARM4 0x10
#define DMAARM3 0x08
#define DMAARM2 0x04
#define DMAARM1 0x02
#define DMAARM0 0x01
__sfr __at (0xD7) DMAREQ;
/*DMAREQ bits*/
#define DMAREQ4 0x10
#define DMAREQ3 0x08
#define DMAREQ2 0x04
#define DMAREQ1 0x02
#define DMAREQ0 0x01
__sfr __at (0xD8) TIMIF;
/*TIMIF bits*/
#define OVFIM 0x40
#define T4CH1IF 0x20
#define T4CH0IF 0x10
#define T4OVFIF 0x08
#define T3CH1IF 0x04
#define T3CH0IF 0x02
#define T3OVFIF 0x01
__sfr __at (0xD9) RFD;
__sfr __at (0xDA) T1CC0L;
__sfr __at (0xDB) T1CC0H;
__sfr __at (0xDC) T1CC1L;
__sfr __at (0xDD) T1CC1H;
__sfr __at (0xDE) T1CC2L;
__sfr __at (0xDF) T1CC2H;
__sfr __at (0xE0) ACC;
__sfr __at (0xE1) RFST;
__sfr __at (0xE2) T1CNTL;
__sfr __at (0xE3) T1CNTH;
__sfr __at (0xE4) T1CTL;
/*T1CTL bits*/
#define CH2IF 0x80
#define CH1IF 0x40
#define CH0IF 0x20
#define OVFIF 0x10
#define T1DIV1 0x08
#define T1DIV0 0x04
#define T1MODE1 0x02
#define T1MODE0 0x01
__sfr __at (0xE5) T1CCTL0;
/*T1CCTL0 bits*/
#define T1CPSEL 0x80
#define T1IM 0x40
#define T1CMP2 0x20
#define T1CMP1 0x10
#define T1CMP0 0x08
#define T1MODE 0x04
#define T1CAP1 0x02
#define T1CAP0 0x01
__sfr __at (0xE6) T1CCTL1;
/*Bits defined in T1CCTL0 */
__sfr __at (0xE7) T1CCTL2;
/*Bits defined in T1CCTL0 */
__sfr __at (0xE8) IRCON2;
/*IRCON2 bits*/
#define WDTIF 0x10
#define P1IF 0x08
#define UTX1IF 0x04
#define UTX0IF 0x02
#define P2IF 0x01
/* IRCON 2 */
/*__sbit __at (0xEF) IRCON2_P1_7 ;
__sbit __at (0xEE) IRCON2_P1_6 ;
__sbit __at (0xED) IRCON2_P1_5 ;*/
__sbit __at (0xEC) IRCON2_WDTIF ;
__sbit __at (0xEB) IRCON2_P1IF ;
__sbit __at (0xEA) IRCON2_UTX1IF ;
__sbit __at (0xE9) IRCON2_UTX0IF ;
__sbit __at (0xE8) IRCON2_P2IF;
__sfr __at (0xE9) RFIF;
/*RFIF bits*/
#define IRQ_RREG_ON 0x80
#define IRQ_TXDONE 0x40
#define IRQ_FIFOP 0x20
#define IRQ_SFD 0x10
#define IRQ_CCA 0x08
#define IRQ_CSP_WT 0x04
#define IRQ_CSP_STOP 0x02
#define IRQ_CSP_INT 0x01
__sfr __at (0xEA) T4CNT;
__sfr __at (0xEB) T4CTL;
/*T4CTL bits*/
#define T4DIV2 0x80
#define T4DIV1 0x40
#define T4DIV0 0x20
#define T4START 0x10
#define T4OVFIM 0x08
#define T4CLR 0x04
#define T4MODE1 0x02
#define T4MODE0 0x01
__sfr __at (0xEC) T4CCTL0;
/*T4CCTL0 bits*/
#define T4IM 0x40
#define T4CMP2 0x20
#define T4CMP1 0x10
#define T4CMP0 0x08
#define T4MODE 0x04
#define T4CAP1 0x02
#define T4CAP0 0x01
__sfr __at (0xED) T4CC0;
__sfr __at (0xEE) T4CCTL1;
/*T4CCTL0 bits apply*/
__sfr __at (0xEF) T4CC1;
__sfr __at (0xF0) B ;
__sfr __at (0xF1) PERCFG;
/*PERCFG bits*/
#define T1CFG 0x40
#define T3CFG 0x20
#define T4CFG 0x10
#define U1CFG 0x02
#define U0CFG 0x01
__sfr __at (0xF2) ADCCFG;
/*ADCCFG bits*/
#define ADC7EN 0x80
#define ADC6EN 0x40
#define ADC5EN 0x20
#define ADC4EN 0x10
#define ADC3EN 0x08
#define ADC2EN 0x04
#define ADC1EN 0x02
#define ADC0EN 0x01
__sfr __at (0xF3) P0SEL;
__sfr __at (0xF4) P1SEL;
__sfr __at (0xF5) P2SEL;
/*P2SEL bits*/
#define PRI3P1 0x40
#define PRI2P1 0x20
#define PRI1P1 0x10
#define PRI0P1 0x08
#define SELP2_4 0x04
#define SELP2_3 0x02
#define SELP2_0 0x01
__sfr __at (0xF6) P1INP;
__sfr __at (0xF7) P2INP;
/*P2INP bits*/
#define PDUP2 0x80
#define PDUP1 0x40
#define PDUP0 0x20
#define MDP2_4 0x10
#define MDP2_3 0x08
#define MDP2_2 0x04
#define MDP2_1 0x02
#define MDP2_0 0x01
__sfr __at (0xF8) U1CSR;
__sfr __at (0xF9) U1BUF;
__sfr __at (0xFA) U1BAUD;
__sfr __at (0xFB) U1UCR;
__sfr __at (0xFC) U1GCR;
__sfr __at (0xFD) P0DIR;
__sfr __at (0xFE) P1DIR;
__sfr __at (0xFF) P2DIR;
/*P2DIR bits*/
#define PRI1P0 0x80
#define PRI0P0 0x40
#define DIRP2_4 0x10
#define DIRP2_3 0x08
#define DIRP2_2 0x04
#define DIRP2_1 0x02
#define DIRP2_0 0x01
/* IEN0 */
/*__sbit __at (0xA8) EA ;
__sbit __at (0x99) TI ;
__sbit __at (0x9A) RB8 ;
__sbit __at (0x9B) TB8 ;
__sbit __at (0x9C) REN ;
__sbit __at (0x9D) SM2 ;
__sbit __at (0x9E) SM1 ;
__sbit __at (0x9F) SM0 ;*/
/* Interrupt numbers: address = (number * 8) + 3 */
/*#undef IE0_VECTOR
#undef TF0_VECTOR
#undef IE1_VECTOR
#undef TF1_VECTOR
#undef SI0_VECTOR*/
/* CC2430 interrupt vectors */
#define RFERR_VECTOR 0
#define ADC_VECTOR 1
#define URX0_VECTOR 2
#define URX1_VECTOR 3
#define ENC_VECTOR 4
#define ST_VECTOR 5
#define P2INT_VECTOR 6
#define UTX0_VECTOR 7
#define DMA_VECTOR 8
#define T1_VECTOR 9
#define T2_VECTOR 10
#define T3_VECTOR 11
#define T4_VECTOR 12
#define P0INT_VECTOR 13
#define UTX1_VECTOR 14
#define P1INT_VECTOR 15
#define RF_VECTOR 16
#define WDT_VECTOR 17
/* RF control registers*/
__xdata __at (0xDF02) unsigned char MDMCTRL0H;
__xdata __at (0xDF03) unsigned char MDMCTRL0L;
__xdata __at (0xDF04) unsigned char MDMCTRL1H;
__xdata __at (0xDF05) unsigned char MDMCTRL1L;
__xdata __at (0xDF06) unsigned char RSSIH;
__xdata __at (0xDF07) unsigned char RSSIL;
__xdata __at (0xDF08) unsigned char SYNCWORDH;
__xdata __at (0xDF09) unsigned char SYNCWORDL;
__xdata __at (0xDF0A) unsigned char TXCTRLH;
__xdata __at (0xDF0B) unsigned char TXCTRLL;
__xdata __at (0xDF0C) unsigned char RXCTRL0H;
__xdata __at (0xDF0D) unsigned char RXCTRL0L;
__xdata __at (0xDF0E) unsigned char RXCTRL1H;
__xdata __at (0xDF0F) unsigned char RXCTRL1L;
__xdata __at (0xDF10) unsigned char FSCTRLH;
__xdata __at (0xDF11) unsigned char FSCTRLL;
__xdata __at (0xDF12) unsigned char CSPX;
__xdata __at (0xDF13) unsigned char CSPY;
__xdata __at (0xDF14) unsigned char CSPZ;
__xdata __at (0xDF15) unsigned char CSPCTRL;
__xdata __at (0xDF16) unsigned char CSPT;
__xdata __at (0xDF17) unsigned char RFPWR;
#define ADI_RADIO_PD 0x10
#define RREG_RADIO_PD 0x08
#define RREG_DELAY_MASK 0x07
__xdata __at (0xDF20) unsigned char FSMTCH;
__xdata __at (0xDF21) unsigned char FSMTCL;
__xdata __at (0xDF22) unsigned char MANANDH;
__xdata __at (0xDF23) unsigned char MANANDL;
__xdata __at (0xDF24) unsigned char MANORH;
__xdata __at (0xDF25) unsigned char MANORL;
__xdata __at (0xDF26) unsigned char AGCCTRLH;
__xdata __at (0xDF27) unsigned char AGCCTRLL;
__xdata __at (0xDF39) unsigned char FSMSTATE;
__xdata __at (0xDF3A) unsigned char ADCTSTH;
__xdata __at (0xDF3B) unsigned char ADCTSTL;
__xdata __at (0xDF3C) unsigned char DACTSTH;
__xdata __at (0xDF3D) unsigned char DACTSTL;
__xdata __at (0xDF43) unsigned char IEEE_ADDR0;
__xdata __at (0xDF44) unsigned char IEEE_ADDR1;
__xdata __at (0xDF45) unsigned char IEEE_ADDR2;
__xdata __at (0xDF46) unsigned char IEEE_ADDR3;
__xdata __at (0xDF47) unsigned char IEEE_ADDR4;
__xdata __at (0xDF48) unsigned char IEEE_ADDR5;
__xdata __at (0xDF49) unsigned char IEEE_ADDR6;
__xdata __at (0xDF4A) unsigned char IEEE_ADDR7;
__xdata __at (0xDF4B) unsigned char PANIDH;
__xdata __at (0xDF4C) unsigned char PANIDL;
__xdata __at (0xDF4D) unsigned char SHORTADDRH;
__xdata __at (0xDF4E) unsigned char SHORTADDRL;
__xdata __at (0xDF4F) unsigned char IOCFG0;
__xdata __at (0xDF50) unsigned char IOCFG1;
__xdata __at (0xDF51) unsigned char IOCFG2;
__xdata __at (0xDF52) unsigned char IOCFG3;
__xdata __at (0xDF53) unsigned char RXFIFOCNT;
__xdata __at (0xDF54) unsigned char FSMTC1;
#define ABORTRX_ON_SRXON 0x20
#define RX_INTERRUPTED 0x10
#define AUTO_TX2RX_OFF 0x08
#define RX2RX_TIME_OFF 0x04
#define PENDING_OR 0x02
#define ACCEPT_ACKPKT 0x01
__xdata __at (0xDF60) unsigned char CHVER;
__xdata __at (0xDF61) unsigned char CHIPID;
__xdata __at (0xDF62) unsigned char RFSTATUS;
#define TX_ACTIVE 0x10
#define FIFO 0x08
#define FIFOP 0x04
#define SFD 0x02
#define CCA 0x01
__xdata __at (0xDFC1) unsigned char U0BUF_SHADOW;
__xdata __at (0xDFD9) unsigned char RFD_SHADOW;
__xdata __at (0xDFF9) unsigned char U1BUF_SHADOW;
#endif /*REG_CC2430*/

132
cpu/cc2430/dev/bus.c Normal file
View file

@ -0,0 +1,132 @@
/*
* 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: bus.c,v 1.1 2009/09/08 20:07:35 zdshelby Exp $
*/
/**
* \file
* Initialization functions for the 8051 bus
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "cc2430_sfr.h"
#include "dev/bus.h"
#include "sys/clock.h"
/*---------------------------------------------------------------------------*/
void
bus_init(void)
{
CLKCON = (0x00 | OSC32K); /* 32k internal */
while(CLKCON != (0x00 | OSC32K));
P1DIR |= 0x0E;
IEN0_EA = 1;
/* Initialize the clock */
clock_init();
}
/*---------------------------------------------------------------------------*/
/**
* Read a block of code memory.
* The code must be placed in the lowest bank of flash.
*
* \param address address to read from flash
* \param buffer buffer to store data
* \param size number of bytes to read
*/
void
flash_read(uint8_t *buf, uint32_t address, uint8_t size)
{
buf; /*dptr0*/
address; /*stack-6*/
size; /*stack-7*/
buf;
DISABLE_INTERRUPTS();
__asm
mov dpl, r2
mov dph, r3
mov a, r0
push acc
mov a, r2
push acc
mov a, _MEMCTR
push acc
mov a, _bp
add a, #0xf9 ;stack - 7 = size
mov r0,a
mov a, @r0 ;r2 = size
mov r2, a ;r2 = size
inc r0
mov a, @r0
mov _DPL1, a ;DPTR1 = address & 0x7FFF | 0x8000
inc r0
mov a, @r0
orl a, #0x80
mov _DPH1, a
inc r0 ;MEMCTR = ((address >> 15 & 3) << 4) | 0x01 (bank select)
mov a, @r0
dec r0
rrc a
mov a, @r0
rrc a
rr a
rr a
anl a, #0x30
orl a, #1
mov _MEMCTR,a
lp1:
mov _DPS, #1 ;active DPTR = 1
clr a
movc a, @a+dptr ;read flash (DPTR1)
inc dptr
mov _DPS, #0 ;active DPTR = 0
movx @dptr,a ;write to DPTR0
inc dptr
djnz r2,lp1 ;while (--size)
pop acc
mov _MEMCTR, a ;restore bank
pop acc
mov r2,a
pop acc
mov r0,a
__endasm;
ENABLE_INTERRUPTS();
DPL1 = *buf++;
}
/*---------------------------------------------------------------------------*/

54
cpu/cc2430/dev/bus.h Normal file
View file

@ -0,0 +1,54 @@
/*
* 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: bus.h,v 1.1 2009/09/08 20:07:35 zdshelby Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __BUS_H__
#define __BUS_H__
#include "cc2430_sfr.h"
#include "8051def.h"
#define inline
void bus_init(void);
void flash_read(uint8_t *buf, uint32_t address, uint8_t size);
void cc2430_clock_ISR( void ) __interrupt (ST_VECTOR);
#endif /* __BUS_H__ */

658
cpu/cc2430/dev/cc2430_rf.c Normal file
View file

@ -0,0 +1,658 @@
/**
* \file
* CC2430 RF driver
* \author
* Zach Shelby <zach@sensinode.com>
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/radio.h"
#include "dev/cc2430_rf.h"
#include "cc2430_sfr.h"
#include "dev/leds.h"
#include "sys/clock.h"
#include "net/rime/packetbuf.h"
#include "net/rime/rimestats.h"
static void (* receiver_callback)(const struct radio_driver *);
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_send(const void *data, unsigned short len);
void cc2430_rf_init(void);
#ifndef RF_DEFAULT_POWER
#define RF_DEFAULT_POWER 100
#endif
#ifndef RF_DEFAULT_CHANNEL
#define RF_DEFAULT_CHANNEL 18
#endif
#ifndef CC2430_CONF_CHECKSUM
#define CC2430_CONF_CHECKSUM 0
#endif /* CC2420_CONF_CHECKSUM */
#if CC2430_CONF_CHECKSUM
#include "lib/crc16.h"
#define CHECKSUM_LEN 2
#else
#define CHECKSUM_LEN 0
#endif /* CC2430_CONF_CHECKSUM */
#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);
#define DEBUG 1
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) do {} while (0)
#endif
#define RX_ACTIVE 0x80
#define TX_ACK 0x40
#define TX_ON_AIR 0x20
#define RX_NO_DMA
#ifdef HAVE_RF_ERROR
uint8_t rf_error = 0;
#endif
uint8_t rf_initialized = 0;
uint8_t rf_tx_power;
uint8_t rf_flags;
uint8_t rf_channel = 0;
rf_address_mode_t rf_addr_mode;
uint16_t rf_manfid;
uint8_t rf_softack;
/*---------------------------------------------------------------------------*/
PROCESS(cc2430_rf_process, "CC2430 RF driver");
/*---------------------------------------------------------------------------*/
const struct radio_driver cc2430_rf_driver =
{
cc2430_rf_send,
cc2430_rf_read,
cc2430_rf_set_receiver,
cc2430_rf_on,
cc2430_rf_off,
};
/*---------------------------------------------------------------------------*/
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();
}
/*---------------------------------------------------------------------------*/
void
cc2430_rf_init(void)
{
if(rf_initialized) {
return;
}
printf("cc2430_rf_init called\n");
RFPWR &= ~RREG_RADIO_PD; /*make sure it's powered*/
while((RFPWR & ADI_RADIO_PD) == 1);
while((RFIF & IRQ_RREG_ON) == 0); /*wait for power up*/
SLEEP &= ~OSC_PD; /*Osc on*/
while((SLEEP & XOSC_STB) == 0); /*wait for power up*/
rf_flags = 0;
rf_softack = 0;
rf_addr_mode = RF_DECODER_NONE;
FSMTC1 = 1; /*don't abort reception, if enable called, accept ack, auto rx after tx*/
MDMCTRL0H = 0x02; /* Generic client, standard hysteresis, decoder on 0x0a */
MDMCTRL0L = 0xE2; /* automatic ACK and CRC, standard CCA and preamble 0xf2 */
MDMCTRL1H = 0x30; /* Defaults */
MDMCTRL1L = 0x0;
RXCTRL0H = 0x32; /* RX tuning optimized */
RXCTRL0L = 0xf5;
/* get ID for MAC */
rf_manfid = CHVER;
rf_manfid <<= 8;
rf_manfid += CHIPID;
cc2430_rf_channel_set(RF_DEFAULT_CHANNEL);
cc2430_rf_command(ISFLUSHTX);
cc2430_rf_command(ISFLUSHRX);
RFIM = IRQ_FIFOP;
RFIF &= ~(IRQ_FIFOP);
S1CON &= ~(RFIF_0 | RFIF_1);
IEN2 |= RFIE;
RF_TX_LED_OFF();
RF_RX_LED_OFF();
rf_initialized = 1;
process_start(&cc2430_rf_process, NULL);
}
/*---------------------------------------------------------------------------*/
void
cc2430_rf_set_receiver(void (* recv)(const struct radio_driver *))
{
receiver_callback = recv;
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_send(const void *payload, unsigned short payload_len)
{
uint8_t i, counter;
/*PRINTF("cc2430_rf_send\n");*/
if(rf_flags & TX_ACK) {
return -1;
}
if((rf_flags & RX_ACTIVE) == 0) {
cc2430_rf_rx_enable();
}
/* Check packet attributes */
/*printf("packetbuf_attr: txpower = %d\n", packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER));*/
/* Should set TX power according to this if > 0 */
PRINTF("cc2430_rf: sending %d byte payload\n", payload_len);
RIMESTATS_ADD(lltx);
/* Add checksum to end of packet as in cc2420 driver? */
/* Send */
cc2430_rf_command(ISFLUSHTX);
RFD = (payload_len + 2);
for(i = 0 ; i < payload_len; i++) {
RFD = ((unsigned char*)(payload))[i];
}
RFD = (0);
RFD = (0);
if(cc2430_rf_cca_check(0,0) == -1) {
return -1;
}
/* Start the transmission */
RFIF &= ~IRQ_TXDONE;
cc2430_rf_command(ISTXON);
counter = 0;
while(!(RFSTATUS & TX_ACTIVE) && (counter++ < 3)) {
clock_delay(10);
}
if(!(RFSTATUS & TX_ACTIVE)) {
printf("cc2430_rf: TX never active.\n");
cc2430_rf_command(ISFLUSHTX);
return -1;
} else {
RF_RX_LED_OFF();
RF_TX_LED_ON();
// rf_flags |= TX_ON_AIR;
}
return 1;
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_read(void *buf, unsigned short bufsize)
{
uint8_t i, len, type;
#if CC2420_CONF_CHECKSUM
uint16_t checksum;
#endif /* CC2420_CONF_CHECKSUM */
/* RX interrupt polled the cc2430_rf_process, now read the RX FIFO */
/* Check the length */
len = RFD;
len &= 0x7f;
printf("cc2430_rf: received %d bytes\n", len);
/* Check for validity */
if(len > CC2430_MAX_PACKET_LEN) {
/* Oops, we must be out of sync. */
printf("error: bad sync\n");
cc2430_rf_command(ISFLUSHRX);
RIMESTATS_ADD(badsynch);
return 0;
}
if(len <= CC2430_MIN_PACKET_LEN) {
printf("error: too short\n");
cc2430_rf_command(ISFLUSHRX);
RIMESTATS_ADD(tooshort);
return 0;
}
if(len - CHECKSUM_LEN > bufsize) {
printf("error: too long\n");
cc2430_rf_command(ISFLUSHRX);
RIMESTATS_ADD(toolong);
return 0;
}
/* Check the type */
type = RFD;
type &= 0x07;
if(typ e== 0x02) {
printf("cc2430_rf: ack\n");
} else {
/* Read the buffer */
printf("cc2430_rf: data = ");
for(i = 0; i < (len - 2 - CHECKSUM_LEN); i++) {
((unsigned char*)(buf))[i] = RFD;
printf("%c", ((unsigned char*)(buf))[i]);
}
printf("\n");
#if CC2430_CONF_CHECKSUM
/* Deal with the checksum */
#endif /* CC2430_CONF_CHECKSUM */
}
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, ((int8_t) RFD) - 45);
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, RFD);
cc2430_rf_command(ISFLUSHRX);
RIMESTATS_ADD(llrx);
RF_RX_LED_OFF();
return (len - 2 - CHECKSUM_LEN);
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_off(void)
{
return cc2430_rf_rx_disable();
}
/*---------------------------------------------------------------------------*/
int
cc2430_rf_on(void)
{
return cc2430_rf_rx_enable();
}
/*---------------------------------------------------------------------------*/
/**
* Execute a single CSP command.
*
* \param command command to execute
*
*/
void cc2430_rf_command(uint8_t command)
{
if(command >= 0xE0) { /*immediate strobe*/
uint8_t fifo_count;
switch(command) { /*hardware bug workaround*/
case ISRFOFF:
case ISRXON:
case ISTXON:
fifo_count = RXFIFOCNT;
RFST = command;
clock_delay(2);
if(fifo_count != RXFIFOCNT) {
RFST = ISFLUSHRX;
RFST = ISFLUSHRX;
}
break;
default:
RFST = command;
}
} else if(command == SSTART) {
RFIF &= ~IRQ_CSP_STOP; /*clear IRQ flag*/
RFST = SSTOP; /*make sure there is a stop in the end*/
RFST = ISSTART; /*start execution*/
while((RFIF & IRQ_CSP_STOP) == 0);
} else {
RFST = command; /*write command*/
}
}
/*---------------------------------------------------------------------------*/
/**
* Select RF channel.
*
* \param channel channel number to select
*
* \return channel value or negative (invalid channel number)
*/
/* channel freqdiv = (2048 + FSCTRL(9:0)) / 4
freq = (2048 + FSCTRL(9:0)) MHz */
int8_t
cc2430_rf_channel_set(uint8_t channel)
{
uint16_t freq;
if((channel < 11) || (channel > 26)) {
return -1;
}
cc2430_rf_command(ISSTOP); /*make sure CSP is not running*/
cc2430_rf_command(ISRFOFF);
/* Channel values: 11-26 */
freq = (uint16_t) channel - 11;
freq *= 5; /*channel spacing*/
freq += 357; /*correct channel range*/
freq |= 0x4000; /*LOCK_THR = 1*/
FSCTRLH = (freq >> 8);
FSCTRLL = (uint8_t)freq;
cc2430_rf_command(ISRXON);
rf_channel = channel;
return (int8_t) channel;
}
/*---------------------------------------------------------------------------*/
/*PA_LEVEL TXCTRL register Output Power [dBm] Current Consumption [mA]
31 0xA0FF 0 17.4
27 0xA0FB -1 16.5
23 0xA0F7 -3 15.2
19 0xA0F3 -5 13.9
15 0xA0EF -7 12.5
11 0xA0EB -10 11.2
7 0xA0E7 -15 9.9
3 0xA0E3 -25 8.5*/
/**
* Select RF transmit power.
*
* \param new_power new power level (in per cent)
*
* \return new level or negative (value out of range)
*/
int8_t
cc2430_rf_power_set(uint8_t new_power)
{
uint16_t power;
if(new_power > 100) {
return -1;
}
power = 31 * new_power;
power /= 100;
power += 0xA160;
/* Set transmitter power */
TXCTRLH = (power >> 8);
TXCTRLL = (uint8_t)power;
rf_tx_power = (int8_t) new_power;
return rf_tx_power;
}
/*---------------------------------------------------------------------------*/
/**
* Enable RF receiver.
*
*
* \return pdTRUE
* \return pdFALSE bus not free
*/
int8_t
cc2430_rf_rx_enable(void)
{
printf("cc2430_rf_rx_enable called\n");
if(!(rf_flags & RX_ACTIVE)) {
IOCFG0 = 0x7f; // Set the FIFOP threshold 127
RSSIH = 0xd2; /* -84dbm = 0xd2 default, 0xe0 -70 dbm */
rf_flags |= RX_ACTIVE;
RFPWR &= ~RREG_RADIO_PD; /*make sure it's powered*/
while((RFIF & IRQ_RREG_ON) == 0); /*wait for power up*/
SLEEP &= ~OSC_PD; /*Osc on*/
while((SLEEP & XOSC_STB) == 0); /*wait for power up*/
cc2430_rf_command(ISRXON);
cc2430_rf_command(ISFLUSHRX);
}
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* Disable RF receiver.
*
*
* \return pdTRUE
* \return pdFALSE bus not free
*/
int8_t cc2430_rf_rx_disable(void)
{
cc2430_rf_command(ISSTOP); /*make sure CSP is not running*/
cc2430_rf_command(ISRFOFF);
RFPWR |= RREG_RADIO_PD; /*RF powerdown*/
rf_flags = 0;
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* Enable RF transmitter.
*
*
* \return pdTRUE
* \return pdFALSE bus not free
*/
int8_t
cc2430_rf_tx_enable(void)
{
DMAARM = 0x80 + (1 << 0); /*ABORT + channel bit*/
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* Set address decoder on/off.
*
* \param param 1=on 0=off.
* \return pdTRUE operation successful
*/
int8_t
cc2430_rf_address_decoder_mode(rf_address_mode_t mode)
{
int8_t retval = -1;
rf_softack = 0;
/* set oscillator on*/
switch(mode) {
case RF_SOFTACK_MONITOR:
rf_softack = 1;
case RF_MONITOR:
MDMCTRL0H |= 0x10; /*Address-decode off , coordinator*/
MDMCTRL0L &= ~0x10; /*no automatic ACK */
break;
case RF_DECODER_COORDINATOR:
MDMCTRL0H |= 0x18; /*Address-decode on , coordinator*/
MDMCTRL0L |= 0x10; /*automatic ACK */
break;
case RF_DECODER_ON:
MDMCTRL0H |= 0x08; /*Address-decode on */
MDMCTRL0L &= ~0x10; /* no automatic ACK */
break;
default:
MDMCTRL0H &= ~0x18; /* Generic client */
MDMCTRL0L &= ~0x10; /* no automatic ACK */
break;
}
rf_addr_mode = mode;
retval = 1;
return retval;
}
/*---------------------------------------------------------------------------*/
/**
* Channel energy detect.
*
* Coordinator use this function detect best channel for PAN-network.
* \return RSSI-energy level dBm.
* \return 0 operation failed.
*/
int8_t
cc2430_rf_analyze_rssi(void)
{
int8_t retval = -128;
/*pause_us(128);*/
retval = (int8_t)RSSIL;
retval -= 45;
return retval;
}
/*---------------------------------------------------------------------------*/
/**
* Clear channel assesment check.
*
* \return pdTRUE CCA clear
* \return pdFALSE CCA reserved
*/
int8_t
cc2430_rf_cca_check(uint8_t backoff_count, uint8_t slotted)
{
uint8_t counter, cca = 1;
int8_t retval = 1;
backoff_count;
cc2430_rf_command(ISRXON);
clock_delay(64);
switch(slotted) {
case 1:
if(RFSTATUS & CCA) {
counter = 0;
cca = 1;
while(cca != 0) {
if(counter > 1) {
cca = 0;
}
clock_delay(256);
if(!(RFSTATUS & CCA)) {
cca = 0;
retval = -1;
}
counter++;
}
} else {
retval = -1;
}
break;
case 0:
if(!(RFSTATUS & CCA)) {
retval = -1;
} else {
}
break;
}
return retval;
}
/*---------------------------------------------------------------------------*/
/**
* Send ACK.
*
*\param pending set up pending flag if pending > 0.
*/
void
cc2430_rf_send_ack(uint8_t pending)
{
if(pending) {
cc2430_rf_command(ISACKPEND);
} else {
cc2430_rf_command(ISACK);
}
}
/*---------------------------------------------------------------------------*/
/**
* RF interrupt service routine.
*
*/
void
cc2430_rf_ISR( void ) __interrupt (RF_VECTOR)
{
EA = 0;
RF_TX_LED_ON();
if(RFIF & IRQ_TXDONE) {
RF_TX_LED_OFF();
RFIF &= ~IRQ_TXDONE;
cc2430_rf_command(ISFLUSHTX);
}
if(RFIF & IRQ_FIFOP) {
RF_TX_LED_OFF();
if(RFSTATUS & FIFO) {
RF_RX_LED_ON();
/* Poll the RF process which calls cc2430_rf_read() */
process_poll(&cc2430_rf_process);
} else {
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
}
RFIF &= ~IRQ_FIFOP;
}
S1CON &= ~(RFIF_0 | RFIF_1);
RFIM |= IRQ_FIFOP;
EA = 1;
}
/*---------------------------------------------------------------------------*/
/**
* RF error interrupt service routine.
*
*/
void
cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR)
{
EA = 0;
TCON_RFERRIF = 0;
#ifdef HAVE_RF_ERROR
rf_error = 254;
#endif
cc2430_rf_command(ISRFOFF);
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISFLUSHRX);
cc2430_rf_command(ISRXON);
RF_RX_LED_OFF();
RF_TX_LED_OFF();
EA = 1;
}
/*---------------------------------------------------------------------------*/

106
cpu/cc2430/dev/cc2430_rf.h Normal file
View file

@ -0,0 +1,106 @@
/**
* \file
* CC2430 RF driver header file
* \author
* Zach Shelby <zach@sensinode.com>
*/
#ifndef __CC2430_RF_H__
#define __CC2430_RF_H__
#include "contiki.h"
#include "dev/radio.h"
#include "cc2430_sfr.h"
#include "dev/dma.h"
/* Constants */
typedef enum rf_address_mode_t
{
RF_DECODER_NONE = 0,
RF_DECODER_COORDINATOR,
RF_SOFTACK_MONITOR,
RF_MONITOR,
RF_SOFTACK_CLIENT,
RF_DECODER_ON
}rf_address_mode_t;
typedef enum
{
MAC_NONE = 0,
MAC_RECEIVE=1,
MAC_ACK_RX=2,
MAC_TIMER_ACK=3,
MAC_TIMER_CCA=4,
MAC_TRANSMIT=5,
MAC_CONTROL=6,
MAC_TIMER_NONE=7,
MAC_LOOP=8,
MAC_ED_SCAN=9,
MAC_RSSI_CHECK=10,
MAC_GW_DIS = 11
}mac_event_t;
/*CSP command set*/
#define SSTOP 0xDF
/*this is not a real command but a way of having rf_command
wait until the script is done*/
#define SSTART 0xDE
#define SNOP 0xC0
#define STXCALN 0xC1
#define SRXON 0xC2
#define STXON 0xC3
#define STXONCCA 0xC4
#define SRFOFF 0xC5
#define SFLUSHRX 0xC6
#define SFLUSHTX 0xC7
#define SACK 0xC8
#define SACKPEND 0xC9
#define ISTXCALN 0xE1
#define ISRXON 0xE2
#define ISTXON 0xE3
#define ISTXONCCA 0xE4
#define ISRFOFF 0xE5
#define ISFLUSHRX 0xE6
#define ISFLUSHTX 0xE7
#define ISACK 0xE8
#define ISACKPEND 0xE9
#define ISSTOP 0xFF
#define ISSTART 0xFE
#define MAC_IFS (1200/128)
#define CC2430_MAX_PACKET_LEN 127
#define CC2430_MIN_PACKET_LEN 4
extern const struct radio_driver cc2430_rf_driver;
/* radio_driver functions */
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_send(const void *data, unsigned short len);
/* RF driver functions */
void cc2430_rf_init(void);
void cc2430_rf_command(uint8_t command);
int8_t cc2430_rf_channel_set(uint8_t channel);
int8_t cc2430_rf_power_set(uint8_t new_power);
int8_t cc2430_rf_rx_enable(void);
int8_t cc2430_rf_rx_disable(void);
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);
extern void cc2430_rf_ISR( void ) __interrupt (RF_VECTOR);
extern void cc2430_rf_error_ISR( void ) __interrupt (RFERR_VECTOR);
#ifdef HAVE_RF_DMA
void rf_dma_callback_isr(void);
#endif
#endif /* __CC2430_RF_H__ */

159
cpu/cc2430/dev/clock.c Normal file
View file

@ -0,0 +1,159 @@
/*
* 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)
*/
/**
* TODO: Implement clock_fine() and clock_fine_max_ticks() using another timer?
*/
#include <stdio.h> /*for debug printf*/
#include "sys/clock.h"
#include "sys/etimer.h"
#include "cc2430_sfr.h"
/*Sleep timer runs on the 32k RC osc. */
/* One clock tick is 7.8 ms */
#define TICK_VAL (32768/128)
#define MAX_TICKS (~((clock_time_t)0) / 2)
/* Used in sleep timer interrupt for calculating the next interrupt time */
static unsigned long timer_value;
/*starts calculating the ticks right after reset*/
static volatile clock_time_t count = 0;
/*calculates seconds*/
static volatile clock_time_t seconds = 0;
/*---------------------------------------------------------------------------*/
/**
* 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
__endasm;
}
}
/*---------------------------------------------------------------------------*/
/**
* 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);
}
/*---------------------------------------------------------------------------*/
clock_time_t
clock_time(void)
{
return count;
}
/*---------------------------------------------------------------------------*/
CCIF unsigned long
clock_seconds(void)
{
return seconds;
}
/*---------------------------------------------------------------------------*/
void
clock_init(void)
{
CLKCON = OSC32K | TICKSPD2|TICKSPD1|TICKSPD0; /*tickspeed 250 kHz*/
/*Initialize tick value*/
timer_value = ST0; /*sleep timer 0. low bits [7:0]*/
timer_value += ((unsigned long int)ST1) << 8; /*middle bits [15:8]*/
timer_value += ((unsigned long int)ST2) << 16; /*high bits [23:16]*/
timer_value += TICK_VAL; /*init value 256*/
ST2 = (unsigned char) (timer_value >> 16);
ST1 = (unsigned char) (timer_value >> 8);
ST0 = (unsigned char) timer_value;
IEN0 |= STIE; /*interrupt enable for sleep timers. STIE=Interrupt mask, CPU. */
}
/*---------------------------------------------------------------------------*/
void
cc2430_clock_ISR( void ) __interrupt (ST_VECTOR)
{
IEN0_EA = 0; /*interrupt disable*/
/* When using the cooperative scheduler the timer 2 ISR is only
required to increment the RTOS tick count. */
/*Read value of the ST0,ST1,ST2 and then 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) { /*core/sys/etimer.c*/
etimer_request_poll();
}
IRCON &= ~STIF; /*IRCON.STIF=Sleep timer interrupt flag. This flag called this interrupt func, now reset it*/
IEN0_EA = 1; /*interrupt enable*/
}
/*---------------------------------------------------------------------------*/

233
cpu/cc2430/dev/dma.c Normal file
View file

@ -0,0 +1,233 @@
/**
* \file
* DMA driver
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/dma.h"
#include "cc2430_sfr.h"
dma_config_t dma_conf[4];
struct process * dma_callback[4];
/*---------------------------------------------------------------------------*/
void
dma_init(void)
{
uint16_t tmp_ptr;
memset(dma_conf, 0, 4*sizeof(dma_config_t));
for(tmp_ptr = 0; tmp_ptr < 4; tmp_ptr++) {
dma_callback[tmp_ptr] = 0;
}
tmp_ptr = (uint16_t) &(dma_conf[0]);
DMA1CFGH = tmp_ptr >> 8;
DMA1CFGL = tmp_ptr;
IEN1_DMAIE = 1; /*enable DMA interrupts*/
}
/*---------------------------------------------------------------------------*/
#ifdef HAVE_DMA
/**
* 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 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_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)
{
if((!channel) || (channel > 4)) {
return 0;
}
DMAIRQ &= ~(1 << channel);
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 = (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.
*
* \param channel channel handle;
*
* \return pdTRUE
* \return pdFALSE semaphore creation failed
*/
uint8_t
dma_arm(xDMAHandle channel)
{
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)
{
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)
{
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)
{
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
dma_config_print(xDMAHandle channel)
{
uint8_t ch_id = channel - 1;
if(ch_id > 4) {
return;
}
printf("DMA channel %d @ %x %x ", ch_id, (uint16_t) &(dma_conf[ch_id]) >> 8, (uint16_t) &(dma_conf[ch_id]) & 0xFF);
{
uint8_t i;
uint8_t *ptr = (uint8_t *)&(dma_conf[ch_id]);
for(i = 0; i< 8; i++) {
if(i != 0) {
printf(":%x", *ptr++);
}
}
printf("\n");
}
}
#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)
{
#ifdef HAVE_DMA
uint8_t i;
#endif
EA=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
#ifdef HAVE_DMA
for(i = 0; i < 4; i++) {
if((DMAIRQ & (1 << i + 1)) != 0) {
DMAIRQ &= ~(1 << i+1);
if(dma_callback[i] != 0) {
process_poll(dma_callback[i]);
}
}
}
#endif
IRCON_DMAIF = 0;
EA = 1;
}
/*---------------------------------------------------------------------------*/

116
cpu/cc2430/dev/dma.h Normal file
View file

@ -0,0 +1,116 @@
/**
* \file
* DMA driver header
* \author
* Original: Martti Huttunen <martti@sensinode.com>
* Port: Zach Shelby <zach@sensinode.com>
*/
#ifndef __DMA_H
#define __DMA_H
#include "cc2430_sfr.h"
/** DMA triggers */
typedef enum dma_trigger_t
{
DMA_T_NONE=0, /*!<DMA No trigger, setting DMAREQ.DMAREQx bit starts transfer*/
DMA_T_PREV=1, /*!<DMA DMA channel is triggered by completion of previous channel*/
DMA_T_T1_CH0=2, /*!<Timer 1 Timer 1, compare, channel 0*/
DMA_T_T1_CH1=3, /*!<Timer 1 Timer 1, compare, channel 1*/
DMA_T_T1_CH2=4, /*!<Timer 1 Timer 1, compare, channel 2*/
DMA_T_T2_COMP=5, /*!<Timer 2 Timer 2, compare*/
DMA_T_T2_OVFL=6, /*!<Timer 2 Timer 2, overflow*/
DMA_T_T3_CH0=7, /*!<Timer 3 Timer 3, compare, channel 0*/
DMA_T_T3_CH1=8, /*!<Timer 3 Timer 3, compare, channel 1*/
DMA_T_T4_CH0=9, /*!<Timer 4 Timer 4, compare, channel 0*/
DMA_T_T4_CH1=10, /*!<Timer 4 Timer 4, compare, channel 1*/
DMA_T_ST=11, /*!<Sleep Timer Sleep Timer compare*/
DMA_T_IOC_0=12, /*!<IO Controller Port 0 I/O pin input transition*/
DMA_T_IOC_1=13, /*!<IO Controller Port 1 I/O pin input transition*/
DMA_T_URX0=14, /*!<USART0 USART0 RX complete*/
DMA_T_UTX0=15, /*!<USART0 USART0 TX complete*/
DMA_T_URX1=16, /*!<USART1 USART1 RX complete*/
DMA_T_UTX1=17, /*!<USART1 USART1 TX complete*/
DMA_T_FLASH=18, /*!<Flash controller Flash data write complete*/
DMA_T_RADIO=19, /*!<Radio RF packet byte received/transmit*/
DMA_T_ADC_CHALL=20, /*!<ADC ADC end of a conversion in a sequence, sample ready*/
DMA_T_ADC_CH11=21, /*!<ADC ADC end of conversion channel 0 in sequence, sample ready*/
DMA_T_ADC_CH21=22, /*!<ADC ADC end of conversion channel 1 in sequence, sample ready*/
DMA_T_ADC_CH32=23, /*!<ADC ADC end of conversion channel 2 in sequence, sample ready*/
DMA_T_ADC_CH42=24, /*!<ADC ADC end of conversion channel 3 in sequence, sample ready*/
DMA_T_ADC_CH53=25, /*!<ADC ADC end of conversion channel 4 in sequence, sample ready*/
DMA_T_ADC_CH63=26, /*!<ADC ADC end of conversion channel 5 in sequence, sample ready*/
DMA_T_ADC_CH74=27, /*!<ADC ADC end of conversion channel 6 in sequence, sample ready*/
DMA_T_ADC_CH84=28, /*!<ADC ADC end of conversion channel 7 in sequence, sample ready*/
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 */
typedef enum dma_vlen_t
{
DMA_VLEN_LEN = (0 << 5),/*!<Use LEN for transfer count*/
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.*/
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.*/
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).*/
DMA_VLEN_RES1 = (5 << 5),/*!<reserved*/
DMA_VLEN_RES2 = (6 << 5),/*!<reserved*/
DMA_VLEN_LEN2 = (7 << 5) /*!<Use LEN for transfer count*/
}dma_vlen_t;
/** address increment modes */
typedef enum dma_inc_t
{
DMA_NOINC = 0, /*!<No increment*/
DMA_INC = 1, /*!<Increment*/
DMA_INC2 = 2, /*!<Increment 2*/
DMA_DEC = 3 /*!<Decrement*/
}dma_inc_t;
/** transfer types */
typedef enum dma_type_t
{
DMA_SINGLE = 0, /*!<Single*/
DMA_BLOCK = 1, /*!<Block*/
DMA_RPT = 2, /*!<Repeated single*/
DMA_BLOCK_RPT=3 /*!<Repeated block*/
}dma_type_t;
/** DMA configuration structure */
typedef struct dma_config_t
{
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; /*!<transfer mode in high 3 bits, length high byte, 4 lowest bits*/
uint8_t len_l; /*!<length low byte*/
uint8_t t_mode; /*!<transfer mode: bit7=word mode, 6-5=block/single 4-0=trigger */
uint8_t addr_mode; /*!<address mode: 7-6=src inc, 5-4=dst_inc, 3=IRQ, 2=M8(vlen) 1-0:priority*/
}dma_config_t;
extern void dma_init(void);
typedef void (*dma_func)(void *);
extern dma_config_t dma_conf[4];
#ifdef HAVE_DMA
typedef uint8_t xDMAHandle;
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 uint8_t dma_arm(xDMAHandle channel);
extern uint8_t dma_abort(xDMAHandle channel);
extern uint8_t dma_trigger(xDMAHandle channel);
extern uint8_t dma_state(xDMAHandle channel);
void dma_config_print(xDMAHandle channel);
#endif
extern void dma_ISR( void ) __interrupt (DMA_VECTOR);
#endif /*__DMA_H*/

76
cpu/cc2430/dev/rs232.c Normal file
View file

@ -0,0 +1,76 @@
/*
* 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.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"
#include "dev/serial.h"
#include "dev/rs232.h"
PROCESS(rs232_process, "RS-232C polling process");
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(rs232_process, ev, data)
{
static struct etimer timer;
char ch;
unsigned char i, stat;
PROCESS_BEGIN();
rs232_arch_init(RS232_BAUD_RATE);
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();
}
/*---------------------------------------------------------------------------*/

88
cpu/cc2430/dev/rs232.h Normal file
View file

@ -0,0 +1,88 @@
/*
* 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__ */

187
cpu/cc2430/dev/uart.c Normal file
View file

@ -0,0 +1,187 @@
#include <stdlib.h>
#include <string.h>
#include "cc2430_sfr.h"
#include "dev/leds.h"
#include "dev/uart.h"
static int (*uart0_input_handler)(unsigned char c);
static int (*uart1_input_handler)(unsigned char c);
/*---------------------------------------------------------------------------*/
void
uart0_init(uint32_t speed)
{
if(speed != 115200) {
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
if(speed == 115200) {
U0BAUD=216; /*115200*/
U0GCR =11; /*LSB first and 115200*/
}
if(speed == 38400) {
U0BAUD=59; /*38400*/
U0GCR =10; /*LSB first and 38400*/
}
if(speed == 9600) {
U0BAUD= 59; /* 9600 */
U0GCR = 8; /*LSB first and 9600*/
}
#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;
}
/*---------------------------------------------------------------------------*/
/* 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;
}
/*---------------------------------------------------------------------------*/
void
uart0_set_input(int (*input)(unsigned char c))
{
uart0_input_handler = input;
}
/*---------------------------------------------------------------------------*/
void
uart0_rxISR(void) __interrupt (URX0_VECTOR)
{
TCON_URX0IF = 0;
if(uart0_input_handler != NULL) {
uart0_input_handler(U0BUF);
}
}
/*---------------------------------------------------------------------------*/
void
uart0_txISR( void ) __interrupt (UTX0_VECTOR)
{
}
/*---------------------------------------------------------------------------*/
/* UART1 initialization */
void
uart1_init(uint32_t speed)
{
#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 */
}
/*---------------------------------------------------------------------------*/
/* 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;
}
/*---------------------------------------------------------------------------*/
void
uart1_set_input(int (*input)(unsigned char c))
{
uart1_input_handler = input;
}
/*---------------------------------------------------------------------------*/
void
uart1_rxISR(void) __interrupt (URX1_VECTOR)
{
TCON_URX1IF = 0;
if(uart1_input_handler != NULL) {
uart1_input_handler(U1BUF);
}
}
/*---------------------------------------------------------------------------*/
void
uart1_txISR( void ) __interrupt (UTX1_VECTOR)
{
}
/*---------------------------------------------------------------------------*/

24
cpu/cc2430/dev/uart.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef UART_H
#define UART_H
#include "contiki-conf.h"
#include "cc2430_sfr.h"
void uart0_init(uint32_t speed);
void uart0_writeb(uint8_t byte);
void uart0_set_input(int (*input)(unsigned char c));
void uart0_rxISR( void ) __interrupt (URX0_VECTOR);
void uart0_txISR( void ) __interrupt (UTX0_VECTOR);
void uart1_init(uint32_t speed);
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*/

192
cpu/cc2430/mtarch.c Normal file
View file

@ -0,0 +1,192 @@
/*
* 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)
{
u16_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 = (u16_t)data;
--t->sp;
/* This will be a return address of thread function. */
*t->sp = (u16_t)mt_exit;
--t->sp;
/* The thread function, is used as a return address of mtarch_switch. */
*t->sp = (u16_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 u16_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)
{
u16_t i;
for (i = 0; i < MTARCH_STACKSIZE; i++) {
if (t->stack[i] != i) {
return MTARCH_STACKSIZE - i;
}
}
return 0;
}
/*--------------------------------------------------------------------------*/

65
cpu/cc2430/mtarch.h Normal file
View file

@ -0,0 +1,65 @@
/*
* 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 difinitions for supporting multithread.
*
* \author
* Takahide Matsutsuka <markn@markn.org>
*/
#ifndef __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 {
/*
* On top of the mtarch_thread must be the address for the stack pointer.
* See details at mtarch_switch in mtarch.c
*/
u16_t *sp;
/*
* Stack is 2-byte wide, so please note that you need 2 * MTARCH_STACKSIZE
* bytes for the stack area for each thread.
*/
u16_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__ */

50
cpu/cc2430/rtimer-arch.h Normal file
View file

@ -0,0 +1,50 @@
/*
* 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
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __RTIMER_ARCH_H__
#define __RTIMER_ARCH_H__
#include "contiki-conf.h"
#define RTIMER_ARCH_SECOND 1000
#define rtimer_arch_now() clock_time()
#endif /* __RTIMER_ARCH_H__ */

221
cpu/cc2430/uip_arch-asm.S Normal file
View file

@ -0,0 +1,221 @@
;;;
;;;
;;; 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(u8_t *op32, u16_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 u16_t chksum(u16_t sum, const u8_t *data, u16_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::
;; ---------------------------------
;; u16_t uip_chksum(void);
;; Stack; retl reth datal datah lenl lenh
;; ABCDEHL____
;; return HL
;; return htons(chksum(0, (u8_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::

216
cpu/cc2430/uip_arch.c Normal file
View file

@ -0,0 +1,216 @@
/*
* 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.1 2009/09/08 20:07:35 zdshelby 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 u16_t sizeof_uip_ipaddr_t = sizeof(uip_ipaddr_t);
static const u16_t offset_tcpip_hdr_len = offsetof(struct uip_tcpip_hdr, len);
static const u16_t offset_tcpip_hdr_srcipaddr = offsetof(struct uip_tcpip_hdr, srcipaddr);
/*--------------------------------------------------------------------------*/
static void upper_layer_chksum() {
__asm
;; ---------------------------------
;; static u16_t upper_layer_chksum(u8_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_htons
ld hl, #0xffff
jr _upper_layer_ret
_upper_layer_htons:
ld a, l
ld l, h
ld h, a
_upper_layer_ret:
__endasm;
}
/*--------------------------------------------------------------------------*/
u16_t
uip_ipchksum(void)
{
__asm
;; ---------------------------------
;; u16_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
u16_t
uip_icmp6chksum(void)
{
__asm
;; ---------------------------------
;; u16_t uip_icmp6chksum(void);
;; Stack; retl reth
;; ABCDEHL____
;; return HL
;; ---------------------------------
ld c, #UIP_PROTO_ICMP6
jp _upper_layer_chksum
__endasm;
}
#endif /* UIP_CONF_IPV6 */
/*--------------------------------------------------------------------------*/
u16_t
uip_tcpchksum(void)
{
__asm
;; ---------------------------------
;; u16_t uip_tcpchksum(void);
;; Stack; retl reth
;; ABCDEHL____
;; return HL
;; ---------------------------------
ld c, #UIP_PROTO_TCP
jp _upper_layer_chksum
__endasm;
}
/*--------------------------------------------------------------------------*/
#if UIP_UDP_CHKSUMS
u16_t
uip_udpchksum(void)
{
__asm
;; ---------------------------------
;; u16_t uip_udpchksum(void);
;; Stack; retl reth
;; ABCDEHL____
;; return HL
;; ---------------------------------
ld c, #UIP_PROTO_UDP
jp _upper_layer_chksum
__endasm;
}
#endif /* UIP_UDP_CHKSUMS */
/*--------------------------------------------------------------------------*/