diff --git a/cpu/cc2430/8051def.h b/cpu/cc2430/8051def.h new file mode 100644 index 000000000..cabcccbd0 --- /dev/null +++ b/cpu/cc2430/8051def.h @@ -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 + */ + +#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__ */ diff --git a/cpu/cc2430/Makefile.cc2430 b/cpu/cc2430/Makefile.cc2430 new file mode 100644 index 000000000..193a1e00b --- /dev/null +++ b/cpu/cc2430/Makefile.cc2430 @@ -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 + @ diff --git a/cpu/cc2430/cc2430_sfr.h b/cpu/cc2430/cc2430_sfr.h new file mode 100644 index 000000000..0a8fb0161 --- /dev/null +++ b/cpu/cc2430/cc2430_sfr.h @@ -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*/ diff --git a/cpu/cc2430/dev/bus.c b/cpu/cc2430/dev/bus.c new file mode 100644 index 000000000..0ce5de117 --- /dev/null +++ b/cpu/cc2430/dev/bus.c @@ -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 + */ + +#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++; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/bus.h b/cpu/cc2430/dev/bus.h new file mode 100644 index 000000000..826918c2e --- /dev/null +++ b/cpu/cc2430/dev/bus.h @@ -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 + */ + + +#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__ */ diff --git a/cpu/cc2430/dev/cc2430_rf.c b/cpu/cc2430/dev/cc2430_rf.c new file mode 100644 index 000000000..b012f3012 --- /dev/null +++ b/cpu/cc2430/dev/cc2430_rf.c @@ -0,0 +1,658 @@ +/** + * \file + * CC2430 RF driver + * \author + * Zach Shelby + */ + +#include + +#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; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/cc2430_rf.h b/cpu/cc2430/dev/cc2430_rf.h new file mode 100644 index 000000000..90d97eeb6 --- /dev/null +++ b/cpu/cc2430/dev/cc2430_rf.h @@ -0,0 +1,106 @@ +/** + * \file + * CC2430 RF driver header file + * \author + * Zach Shelby + */ + +#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__ */ diff --git a/cpu/cc2430/dev/clock.c b/cpu/cc2430/dev/clock.c new file mode 100644 index 000000000..00513596c --- /dev/null +++ b/cpu/cc2430/dev/clock.c @@ -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 /*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*/ +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/dma.c b/cpu/cc2430/dev/dma.c new file mode 100644 index 000000000..494778e77 --- /dev/null +++ b/cpu/cc2430/dev/dma.c @@ -0,0 +1,233 @@ +/** + * \file + * DMA driver + * \author + * Original: Martti Huttunen + * Port: Zach Shelby + */ + +#include + +#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; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/dma.h b/cpu/cc2430/dev/dma.h new file mode 100644 index 000000000..36c32c06c --- /dev/null +++ b/cpu/cc2430/dev/dma.h @@ -0,0 +1,116 @@ +/** + * \file + * DMA driver header + * \author + * Original: Martti Huttunen + * Port: Zach Shelby + */ + +#ifndef __DMA_H +#define __DMA_H + +#include "cc2430_sfr.h" + +/** DMA triggers */ +typedef enum dma_trigger_t +{ + DMA_T_NONE=0, /*! + */ + +#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(); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/rs232.h b/cpu/cc2430/dev/rs232.h new file mode 100644 index 000000000..865e8a415 --- /dev/null +++ b/cpu/cc2430/dev/rs232.h @@ -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 + */ + +#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__ */ diff --git a/cpu/cc2430/dev/uart.c b/cpu/cc2430/dev/uart.c new file mode 100644 index 000000000..f1ad42ec7 --- /dev/null +++ b/cpu/cc2430/dev/uart.c @@ -0,0 +1,187 @@ +#include +#include + +#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) +{ +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/uart.h b/cpu/cc2430/dev/uart.h new file mode 100644 index 000000000..a53cd3584 --- /dev/null +++ b/cpu/cc2430/dev/uart.h @@ -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*/ diff --git a/cpu/cc2430/mtarch.c b/cpu/cc2430/mtarch.c new file mode 100644 index 000000000..97614ad43 --- /dev/null +++ b/cpu/cc2430/mtarch.c @@ -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 + */ +#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; +} +/*--------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/mtarch.h b/cpu/cc2430/mtarch.h new file mode 100644 index 000000000..9c458be98 --- /dev/null +++ b/cpu/cc2430/mtarch.h @@ -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 + */ +#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__ */ + diff --git a/cpu/cc2430/rtimer-arch.h b/cpu/cc2430/rtimer-arch.h new file mode 100644 index 000000000..be2aec319 --- /dev/null +++ b/cpu/cc2430/rtimer-arch.h @@ -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 + */ + +#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__ */ diff --git a/cpu/cc2430/uip_arch-asm.S b/cpu/cc2430/uip_arch-asm.S new file mode 100644 index 000000000..0f9decbc1 --- /dev/null +++ b/cpu/cc2430/uip_arch-asm.S @@ -0,0 +1,221 @@ +;;; +;;; +;;; uip_arch-asm.S +;;; +;;; \file +;;; Z80 architecture-depend uip module +;;; for calculating checksums +;;; +;;; \author +;;; Takahide Matsutsuka +;;; + .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:: diff --git a/cpu/cc2430/uip_arch.c b/cpu/cc2430/uip_arch.c new file mode 100644 index 000000000..923882f8a --- /dev/null +++ b/cpu/cc2430/uip_arch.c @@ -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 + */ + +#include +#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 */ +/*--------------------------------------------------------------------------*/