diff --git a/boards/iot-lab_M3/include/periph_conf.h b/boards/iot-lab_M3/include/periph_conf.h index 83831de7d78d..21e3d696f90b 100644 --- a/boards/iot-lab_M3/include/periph_conf.h +++ b/boards/iot-lab_M3/include/periph_conf.h @@ -22,9 +22,10 @@ * @brief Timer configuration * @{ */ -#define TIMER_NUMOF (2U) +#define TIMER_NUMOF (3U) #define TIMER_0_EN 1 #define TIMER_1_EN 1 +#define TIMER_2_EN 1 /* Timer 0 configuration */ #define TIMER_0_DEV TIM2 @@ -45,6 +46,16 @@ #define TIMER_1_ISR isr_tim3 #define TIMER_1_IRQ_CHAN TIM3_IRQn #define TIMER_1_IRQ_PRIO 1 + +/* Timer 2 configuration */ +#define TIMER_2_DEV TIM4 +#define TIMER_2_CHANNELS 2 +#define TIMER_2_PRESCALER (36000U) +#define TIMER_2_MAX_VALUE (0xffff) +#define TIMER_2_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_TIM4EN) +#define TIMER_2_ISR isr_tim4 +#define TIMER_2_IRQ_CHAN TIM4_IRQn +#define TIMER_2_IRQ_PRIO 1 /** @} */ /** @@ -84,7 +95,7 @@ /** * @brief GPIO configuration */ -#define GPIO_NUMOF 15 +#define GPIO_NUMOF 16 #define GPIO_0_EN 1 #define GPIO_1_EN 1 #define GPIO_2_EN 1 diff --git a/cpu/stm32f1/periph/timer.c b/cpu/stm32f1/periph/timer.c index 086e63d11bd7..ba1f31cfb7a0 100644 --- a/cpu/stm32f1/periph/timer.c +++ b/cpu/stm32f1/periph/timer.c @@ -67,6 +67,16 @@ int timer_init(tim_t dev, unsigned int ticks_per_us, void (*callback)(int)) /* select timer */ timer = TIMER_1_DEV; break; +#endif +#if TIMER_2_EN + case TIMER_2: + /* enable timer peripheral clock */ + TIMER_2_CLKEN(); + /* set timer's IRQ priority */ + NVIC_SetPriority(TIMER_2_IRQ_CHAN, TIMER_2_IRQ_PRIO); + /* select timer */ + timer = TIMER_2_DEV; + break; #endif case TIMER_UNDEFINED: default: @@ -113,6 +123,11 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value) case TIMER_1: timer = TIMER_1_DEV; break; +#endif +#if TIMER_2_EN + case TIMER_2: + timer = TIMER_2_DEV; + break; #endif case TIMER_UNDEFINED: default: @@ -160,6 +175,11 @@ int timer_clear(tim_t dev, int channel) case TIMER_1: timer = TIMER_1_DEV; break; +#endif +#if TIMER_2_EN + case TIMER_2: + timer = TIMER_2_DEV; + break; #endif case TIMER_UNDEFINED: default: @@ -196,6 +216,11 @@ unsigned int timer_read(tim_t dev) case TIMER_1: return TIMER_1_DEV->CNT; break; +#endif +#if TIMER_2_EN + case TIMER_2: + return TIMER_2_DEV->CNT; + break; #endif case TIMER_UNDEFINED: default: @@ -215,6 +240,11 @@ void timer_start(tim_t dev) case TIMER_1: TIMER_1_DEV->CR1 |= TIM_CR1_CEN; break; +#endif +#if TIMER_2_EN + case TIMER_2: + TIMER_2_DEV->CR1 |= TIM_CR1_CEN; + break; #endif case TIMER_UNDEFINED: break; @@ -233,6 +263,11 @@ void timer_stop(tim_t dev) case TIMER_1: TIMER_1_DEV->CR1 &= ~TIM_CR1_CEN; break; +#endif +#if TIMER_2_EN + case TIMER_2: + TIMER_2_DEV->CR1 &= ~TIM_CR1_CEN; + break; #endif case TIMER_UNDEFINED: break; @@ -251,6 +286,11 @@ void timer_irq_enable(tim_t dev) case TIMER_1: NVIC_EnableIRQ(TIMER_1_IRQ_CHAN); break; +#endif +#if TIMER_2_EN + case TIMER_2: + NVIC_EnableIRQ(TIMER_2_IRQ_CHAN); + break; #endif case TIMER_UNDEFINED: break; @@ -269,6 +309,11 @@ void timer_irq_disable(tim_t dev) case TIMER_1: NVIC_DisableIRQ(TIMER_1_IRQ_CHAN); break; +#endif +#if TIMER_2_EN + case TIMER_2: + NVIC_DisableIRQ(TIMER_2_IRQ_CHAN); + break; #endif case TIMER_UNDEFINED: break; @@ -287,6 +332,11 @@ void timer_reset(tim_t dev) case TIMER_1: TIMER_1_DEV->CNT = 0; break; +#endif +#if TIMER_2_EN + case TIMER_2: + TIMER_2_DEV->CNT = 0; + break; #endif case TIMER_UNDEFINED: break; @@ -314,6 +364,15 @@ __attribute__ ((naked)) void TIMER_1_ISR(void) } #endif +#if TIMER_2_EN +__attribute__ ((naked)) void TIMER_2_ISR(void) +{ + ISR_ENTER(); + irq_handler(TIMER_2, TIMER_2_DEV); + ISR_EXIT(); +} +#endif + static inline void irq_handler(tim_t timer, TIM_TypeDef *dev) { if (dev->SR & TIM_SR_UIF) { diff --git a/sys/net/openwsn_stack/Makefile b/sys/net/openwsn_stack/Makefile index 6df488daf543..e88ccce5cbbf 100644 --- a/sys/net/openwsn_stack/Makefile +++ b/sys/net/openwsn_stack/Makefile @@ -35,6 +35,7 @@ DIRS += openwsn/03b-IPv6 DIRS += openwsn/04-TRAN DIRS += openwsn/cross-layers DIRS += openwsn/07-App/rinfo +DIRS += openwsn/07-App/rleds DIRS += openwsn/07-App/rwellknown DIRS += openwsn/07-App/r6t DIRS += openwsn/07-App/ohlone diff --git a/sys/net/openwsn_stack/bsp/at86rf231_ow.h b/sys/net/openwsn_stack/bsp/at86rf231_ow.h new file mode 100644 index 000000000000..385078c953c3 --- /dev/null +++ b/sys/net/openwsn_stack/bsp/at86rf231_ow.h @@ -0,0 +1,657 @@ +/** +\brief Definitions for the Atmel AT86RF231 radio chip. +*/ + +#ifndef __ATMEL_H +#define __ATMEL_H + +//=========================== define ========================================== + +enum radio_antennaselection_enum { + RADIO_UFL_ANTENNA = 0x06, ///< Use the antenna connected by U.FL. + RADIO_CHIP_ANTENNA = 0x05, ///< Use the on-board chip antenna. +}; + +/** +\brief Possible values for the status of the radio. + +After you get an interrupt from the radio, read the status register +(RG_IRQ_STATUS) to know what type it is, amoung the following. +*/ +enum radio_irqstatus_enum { + AT_IRQ_BAT_LOW = 0x80, //< Supply voltage below the programmed threshold. + AT_IRQ_TRX_UR = 0x40, ///< Frame buffer access violation. + AT_IRQ_AMI = 0x20, ///< Address matching. + AT_IRQ_CCA_ED_DONE = 0x10, ///< End of a CCA or ED measurement. + AT_IRQ_TRX_END = 0x08, ///< Completion of a frame transmission/reception. + AT_IRQ_RX_START = 0x04, ///< Start of a PSDU reception. + AT_IRQ_PLL_UNLOCK = 0x02, ///< PLL unlock. + AT_IRQ_PLL_LOCK = 0x01, ///< PLL lock. +}; + +#define HAVE_REGISTER_MAP (1) +/** Offset for register TRX_STATUS + * @ingroup apiHalPHY230Reg + */ +#define RG_TRX_STATUS (0x01) + /** Access parameters for sub-register CCA_DONE in register @ref RG_TRX_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_CCA_DONE 0x01, 0x80, 7 + /** Access parameters for sub-register CCA_STATUS in register @ref RG_TRX_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_CCA_STATUS 0x01, 0x40, 6 +# define SR_reserved_01_3 0x01, 0x20, 5 + /** Access parameters for sub-register TRX_STATUS in register @ref RG_TRX_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_TRX_STATUS 0x01, 0x1f, 0 + /** Constant P_ON for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define P_ON (0) + /** Constant BUSY_RX for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define BUSY_RX (1) + /** Constant BUSY_TX for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define BUSY_TX (2) + /** Constant RX_ON for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define RX_ON (6) + /** Constant TRX_OFF for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define TRX_OFF (8) + /** Constant PLL_ON for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define PLL_ON (9) + /** Constant SLEEP for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define SLEEP (15) + /** Constant BUSY_RX_AACK for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define BUSY_RX_AACK (17) + /** Constant BUSY_TX_ARET for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define BUSY_TX_ARET (18) + /** Constant RX_AACK_ON for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define RX_AACK_ON (22) + /** Constant TX_ARET_ON for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define TX_ARET_ON (25) + /** Constant RX_ON_NOCLK for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define RX_ON_NOCLK (28) + /** Constant RX_AACK_ON_NOCLK for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define RX_AACK_ON_NOCLK (29) + /** Constant BUSY_RX_AACK_NOCLK for sub-register @ref SR_TRX_STATUS + * @ingroup apiHalPHY230Const + */ +# define BUSY_RX_AACK_NOCLK (30) + +/** Offset for register TRX_STATE + * @ingroup apiHalPHY230Reg + */ +#define RG_TRX_STATE (0x02) + /** Access parameters for sub-register TRAC_STATUS in register @ref RG_TRX_STATE + * @ingroup apiHalPHY230Sreg + */ +# define SR_TRAC_STATUS 0x02, 0xe0, 5 + /** Access parameters for sub-register TRX_CMD in register @ref RG_TRX_STATE + * @ingroup apiHalPHY230Sreg + */ +# define SR_TRX_CMD 0x02, 0x1f, 0 + /** Constant CMD_NOP for sub-register @ref SR_TRX_CMD + * @ingroup apiHalPHY230Const + */ +# define CMD_NOP (0) + /** Constant CMD_TX_START for sub-register @ref SR_TRX_CMD + * @ingroup apiHalPHY230Const + */ +# define CMD_TX_START (2) + /** Constant CMD_FORCE_TRX_OFF for sub-register @ref SR_TRX_CMD + * @ingroup apiHalPHY230Const + */ +# define CMD_FORCE_TRX_OFF (3) + /** Constant CMD_RX_ON for sub-register @ref SR_TRX_CMD + * @ingroup apiHalPHY230Const + */ +# define CMD_RX_ON (6) + /** Constant CMD_TRX_OFF for sub-register @ref SR_TRX_CMD + * @ingroup apiHalPHY230Const + */ +# define CMD_TRX_OFF (8) + /** Constant CMD_PLL_ON for sub-register @ref SR_TRX_CMD + * @ingroup apiHalPHY230Const + */ +# define CMD_PLL_ON (9) + /** Constant CMD_RX_AACK_ON for sub-register @ref SR_TRX_CMD + * @ingroup apiHalPHY230Const + */ +# define CMD_RX_AACK_ON (22) + /** Constant CMD_TX_ARET_ON for sub-register @ref SR_TRX_CMD + * @ingroup apiHalPHY230Const + */ +# define CMD_TX_ARET_ON (25) + +/** Offset for register TRX_CTRL_0 + * @ingroup apiHalPHY230Reg + */ +#define RG_TRX_CTRL_0 (0x03) + /** Access parameters for sub-register PAD_IO in register @ref RG_TRX_CTRL_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_PAD_IO 0x03, 0xc0, 6 + /** Access parameters for sub-register PAD_IO_CLKM in register @ref RG_TRX_CTRL_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_PAD_IO_CLKM 0x03, 0x30, 4 + /** Constant CLKM_2mA for sub-register @ref SR_PAD_IO_CLKM + * @ingroup apiHalPHY230Const + */ +# define CLKM_2mA (0) + /** Constant CLKM_4mA for sub-register @ref SR_PAD_IO_CLKM + * @ingroup apiHalPHY230Const + */ +# define CLKM_4mA (1) + /** Constant CLKM_6mA for sub-register @ref SR_PAD_IO_CLKM + * @ingroup apiHalPHY230Const + */ +# define CLKM_6mA (2) + /** Constant CLKM_8mA for sub-register @ref SR_PAD_IO_CLKM + * @ingroup apiHalPHY230Const + */ +# define CLKM_8mA (3) + /** Access parameters for sub-register CLKM_SHA_SEL in register @ref RG_TRX_CTRL_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_CLKM_SHA_SEL 0x03, 0x08, 3 + /** Access parameters for sub-register CLKM_CTRL in register @ref RG_TRX_CTRL_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_CLKM_CTRL 0x03, 0x07, 0 + /** Constant CLKM_no_clock for sub-register @ref SR_CLKM_CTRL + * @ingroup apiHalPHY230Const + */ +# define CLKM_no_clock (0) + /** Constant CLKM_1MHz for sub-register @ref SR_CLKM_CTRL + * @ingroup apiHalPHY230Const + */ +# define CLKM_1MHz (1) + /** Constant CLKM_2MHz for sub-register @ref SR_CLKM_CTRL + * @ingroup apiHalPHY230Const + */ +# define CLKM_2MHz (2) + /** Constant CLKM_4MHz for sub-register @ref SR_CLKM_CTRL + * @ingroup apiHalPHY230Const + */ +# define CLKM_4MHz (3) + /** Constant CLKM_8MHz for sub-register @ref SR_CLKM_CTRL + * @ingroup apiHalPHY230Const + */ +# define CLKM_8MHz (4) + /** Constant CLKM_16MHz for sub-register @ref SR_CLKM_CTRL + * @ingroup apiHalPHY230Const + */ +# define CLKM_16MHz (5) + +/** Offset for register PHY_TX_PWR + * @ingroup apiHalPHY230Reg + */ +#define RG_PHY_TX_PWR (0x05) + /** Access parameters for sub-register TX_AUTO_CRC_ON in register @ref RG_PHY_TX_PWR + * @ingroup apiHalPHY230Sreg + */ +# define SR_TX_AUTO_CRC_ON 0x05, 0x80, 7 +# define SR_reserved_05_2 0x05, 0x70, 4 + /** Access parameters for sub-register TX_PWR in register @ref RG_PHY_TX_PWR + * @ingroup apiHalPHY230Sreg + */ +# define SR_TX_PWR 0x05, 0x0f, 0 + +/** Offset for register PHY_RSSI + * @ingroup apiHalPHY230Reg + */ +#define RG_PHY_RSSI (0x06) +# define SR_reserved_06_1 0x06, 0xe0, 5 + /** Access parameters for sub-register RSSI in register @ref RG_PHY_RSSI + * @ingroup apiHalPHY230Sreg + */ +# define SR_RSSI 0x06, 0x1f, 0 + +/** Offset for register PHY_ED_LEVEL + * @ingroup apiHalPHY230Reg + */ +#define RG_PHY_ED_LEVEL (0x07) + /** Access parameters for sub-register ED_LEVEL in register @ref RG_PHY_ED_LEVEL + * @ingroup apiHalPHY230Sreg + */ +# define SR_ED_LEVEL 0x07, 0xff, 0 + +/** Offset for register PHY_CC_CCA + * @ingroup apiHalPHY230Reg + */ +#define RG_PHY_CC_CCA (0x08) + /** Access parameters for sub-register CCA_REQUEST in register @ref RG_PHY_CC_CCA + * @ingroup apiHalPHY230Sreg + */ +# define SR_CCA_REQUEST 0x08, 0x80, 7 + /** Access parameters for sub-register CCA_MODE in register @ref RG_PHY_CC_CCA + * @ingroup apiHalPHY230Sreg + */ +# define SR_CCA_MODE 0x08, 0x60, 5 + /** Access parameters for sub-register CHANNEL in register @ref RG_PHY_CC_CCA + * @ingroup apiHalPHY230Sreg + */ +# define SR_CHANNEL 0x08, 0x1f, 0 + +/** Offset for register CCA_THRES + * @ingroup apiHalPHY230Reg + */ +#define RG_CCA_THRES (0x09) + /** Access parameters for sub-register CCA_CS_THRES in register @ref RG_CCA_THRES + * @ingroup apiHalPHY230Sreg + */ +# define SR_CCA_CS_THRES 0x09, 0xf0, 4 + /** Access parameters for sub-register CCA_ED_THRES in register @ref RG_CCA_THRES + * @ingroup apiHalPHY230Sreg + */ +# define SR_CCA_ED_THRES 0x09, 0x0f, 0 + +/** Offset for register IRQ_MASK + * @ingroup apiHalPHY230Reg + */ +#define RG_IRQ_MASK (0x0e) + /** Access parameters for sub-register IRQ_MASK in register @ref RG_IRQ_MASK + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_MASK 0x0e, 0xff, 0 + +/** Offset for register IRQ_STATUS + * @ingroup apiHalPHY230Reg + */ +#define RG_IRQ_STATUS (0x0f) + /** Access parameters for sub-register IRQ_7_BAT_LOW in register @ref RG_IRQ_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7 + /** Access parameters for sub-register IRQ_6_TRX_UR in register @ref RG_IRQ_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6 + /** Access parameters for sub-register IRQ_5 in register @ref RG_IRQ_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_5 0x0f, 0x20, 5 + /** Access parameters for sub-register IRQ_4 in register @ref RG_IRQ_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_4 0x0f, 0x10, 4 + /** Access parameters for sub-register IRQ_3_TRX_END in register @ref RG_IRQ_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_3_TRX_END 0x0f, 0x08, 3 + /** Access parameters for sub-register IRQ_2_RX_START in register @ref RG_IRQ_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_2_RX_START 0x0f, 0x04, 2 + /** Access parameters for sub-register IRQ_1_PLL_UNLOCK in register @ref RG_IRQ_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1 + /** Access parameters for sub-register IRQ_0_PLL_LOCK in register @ref RG_IRQ_STATUS + * @ingroup apiHalPHY230Sreg + */ +# define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0 + +/** Offset for register VREG_CTRL + * @ingroup apiHalPHY230Reg + */ +#define RG_VREG_CTRL (0x10) + /** Access parameters for sub-register AVREG_EXT in register @ref RG_VREG_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_AVREG_EXT 0x10, 0x80, 7 + /** Access parameters for sub-register AVDD_OK in register @ref RG_VREG_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_AVDD_OK 0x10, 0x40, 6 + /** Access parameters for sub-register AVREG_TRIM in register @ref RG_VREG_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_AVREG_TRIM 0x10, 0x30, 4 + /** Constant AVREG_1_80V for sub-register @ref SR_AVREG_TRIM + * @ingroup apiHalPHY230Const + */ +# define AVREG_1_80V (0) + /** Constant AVREG_1_75V for sub-register @ref SR_AVREG_TRIM + * @ingroup apiHalPHY230Const + */ +# define AVREG_1_75V (1) + /** Constant AVREG_1_84V for sub-register @ref SR_AVREG_TRIM + * @ingroup apiHalPHY230Const + */ +# define AVREG_1_84V (2) + /** Constant AVREG_1_88V for sub-register @ref SR_AVREG_TRIM + * @ingroup apiHalPHY230Const + */ +# define AVREG_1_88V (3) + /** Access parameters for sub-register DVREG_EXT in register @ref RG_VREG_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_DVREG_EXT 0x10, 0x08, 3 + /** Access parameters for sub-register DVDD_OK in register @ref RG_VREG_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_DVDD_OK 0x10, 0x04, 2 + /** Access parameters for sub-register DVREG_TRIM in register @ref RG_VREG_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_DVREG_TRIM 0x10, 0x03, 0 + /** Constant DVREG_1_80V for sub-register @ref SR_DVREG_TRIM + * @ingroup apiHalPHY230Const + */ +# define DVREG_1_80V (0) + /** Constant DVREG_1_75V for sub-register @ref SR_DVREG_TRIM + * @ingroup apiHalPHY230Const + */ +# define DVREG_1_75V (1) + /** Constant DVREG_1_84V for sub-register @ref SR_DVREG_TRIM + * @ingroup apiHalPHY230Const + */ +# define DVREG_1_84V (2) + /** Constant DVREG_1_88V for sub-register @ref SR_DVREG_TRIM + * @ingroup apiHalPHY230Const + */ +# define DVREG_1_88V (3) + +/** Offset for register BATMON + * @ingroup apiHalPHY230Reg + */ +#define RG_BATMON (0x11) +# define SR_reserved_11_1 0x11, 0xc0, 6 + /** Access parameters for sub-register BATMON_OK in register @ref RG_BATMON + * @ingroup apiHalPHY230Sreg + */ +# define SR_BATMON_OK 0x11, 0x20, 5 + /** Access parameters for sub-register BATMON_HR in register @ref RG_BATMON + * @ingroup apiHalPHY230Sreg + */ +# define SR_BATMON_HR 0x11, 0x10, 4 + /** Access parameters for sub-register BATMON_VTH in register @ref RG_BATMON + * @ingroup apiHalPHY230Sreg + */ +# define SR_BATMON_VTH 0x11, 0x0f, 0 + +/** Offset for register XOSC_CTRL + * @ingroup apiHalPHY230Reg + */ +#define RG_XOSC_CTRL (0x12) + /** Access parameters for sub-register XTAL_MODE in register @ref RG_XOSC_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_XTAL_MODE 0x12, 0xf0, 4 + /** Access parameters for sub-register XTAL_TRIM in register @ref RG_XOSC_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_XTAL_TRIM 0x12, 0x0f, 0 + +/** Offset for register FTN_CTRL + * @ingroup apiHalPHY230Reg + */ +#define RG_FTN_CTRL (0x18) + /** Access parameters for sub-register FTN_START in register @ref RG_FTN_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_FTN_START 0x18, 0x80, 7 +# define SR_reserved_18_2 0x18, 0x40, 6 + /** Access parameters for sub-register FTNV in register @ref RG_FTN_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_FTNV 0x18, 0x3f, 0 + +/** Offset for register PLL_CF + * @ingroup apiHalPHY230Reg + */ +#define RG_PLL_CF (0x1a) + /** Access parameters for sub-register PLL_CF_START in register @ref RG_PLL_CF + * @ingroup apiHalPHY230Sreg + */ +# define SR_PLL_CF_START 0x1a, 0x80, 7 +# define SR_reserved_1a_2 0x1a, 0x70, 4 + /** Access parameters for sub-register PLL_CF in register @ref RG_PLL_CF + * @ingroup apiHalPHY230Sreg + */ +# define SR_PLL_CF 0x1a, 0x0f, 0 + +/** Offset for register PLL_DCU + * @ingroup apiHalPHY230Reg + */ +#define RG_PLL_DCU (0x1b) + /** Access parameters for sub-register PLL_DCU_START in register @ref RG_PLL_DCU + * @ingroup apiHalPHY230Sreg + */ +# define SR_PLL_DCU_START 0x1b, 0x80, 7 +# define SR_reserved_1b_2 0x1b, 0x40, 6 + /** Access parameters for sub-register PLL_DCUW in register @ref RG_PLL_DCU + * @ingroup apiHalPHY230Sreg + */ +# define SR_PLL_DCUW 0x1b, 0x3f, 0 + +/** Offset for register PART_NUM + * @ingroup apiHalPHY230Reg + */ +#define RG_PART_NUM (0x1c) + /** Access parameters for sub-register PART_NUM in register @ref RG_PART_NUM + * @ingroup apiHalPHY230Sreg + */ +# define SR_PART_NUM 0x1c, 0xff, 0 + /** Constant RF230 for sub-register @ref SR_PART_NUM + * @ingroup apiHalPHY230Const + */ +# define RF230 (2) + +/** Offset for register VERSION_NUM + * @ingroup apiHalPHY230Reg + */ +#define RG_VERSION_NUM (0x1d) + /** Access parameters for sub-register VERSION_NUM in register @ref RG_VERSION_NUM + * @ingroup apiHalPHY230Sreg + */ +# define SR_VERSION_NUM 0x1d, 0xff, 0 + +/** Offset for register MAN_ID_0 + * @ingroup apiHalPHY230Reg + */ +#define RG_MAN_ID_0 (0x1e) + /** Access parameters for sub-register MAN_ID_0 in register @ref RG_MAN_ID_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_MAN_ID_0 0x1e, 0xff, 0 + +/** Offset for register MAN_ID_1 + * @ingroup apiHalPHY230Reg + */ +#define RG_MAN_ID_1 (0x1f) + /** Access parameters for sub-register MAN_ID_1 in register @ref RG_MAN_ID_1 + * @ingroup apiHalPHY230Sreg + */ +# define SR_MAN_ID_1 0x1f, 0xff, 0 + +/** Offset for register SHORT_ADDR_0 + * @ingroup apiHalPHY230Reg + */ +#define RG_SHORT_ADDR_0 (0x20) + /** Access parameters for sub-register SHORT_ADDR_0 in register @ref RG_SHORT_ADDR_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_SHORT_ADDR_0 0x20, 0xff, 0 + +/** Offset for register SHORT_ADDR_1 + * @ingroup apiHalPHY230Reg + */ +#define RG_SHORT_ADDR_1 (0x21) + /** Access parameters for sub-register SHORT_ADDR_1 in register @ref RG_SHORT_ADDR_1 + * @ingroup apiHalPHY230Sreg + */ +# define SR_SHORT_ADDR_1 0x21, 0xff, 0 + +/** Offset for register PAN_ID_0 + * @ingroup apiHalPHY230Reg + */ +#define RG_PAN_ID_0 (0x22) + /** Access parameters for sub-register PAN_ID_0 in register @ref RG_PAN_ID_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_PAN_ID_0 0x22, 0xff, 0 + +/** Offset for register PAN_ID_1 + * @ingroup apiHalPHY230Reg + */ +#define RG_PAN_ID_1 (0x23) + /** Access parameters for sub-register PAN_ID_1 in register @ref RG_PAN_ID_1 + * @ingroup apiHalPHY230Sreg + */ +# define SR_PAN_ID_1 0x23, 0xff, 0 + +/** Offset for register IEEE_ADDR_0 + * @ingroup apiHalPHY230Reg + */ +#define RG_IEEE_ADDR_0 (0x24) + /** Access parameters for sub-register IEEE_ADDR_0 in register @ref RG_IEEE_ADDR_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_IEEE_ADDR_0 0x24, 0xff, 0 + +/** Offset for register IEEE_ADDR_1 + * @ingroup apiHalPHY230Reg + */ +#define RG_IEEE_ADDR_1 (0x25) + /** Access parameters for sub-register IEEE_ADDR_1 in register @ref RG_IEEE_ADDR_1 + * @ingroup apiHalPHY230Sreg + */ +# define SR_IEEE_ADDR_1 0x25, 0xff, 0 + +/** Offset for register IEEE_ADDR_2 + * @ingroup apiHalPHY230Reg + */ +#define RG_IEEE_ADDR_2 (0x26) + /** Access parameters for sub-register IEEE_ADDR_2 in register @ref RG_IEEE_ADDR_2 + * @ingroup apiHalPHY230Sreg + */ +# define SR_IEEE_ADDR_2 0x26, 0xff, 0 + +/** Offset for register IEEE_ADDR_3 + * @ingroup apiHalPHY230Reg + */ +#define RG_IEEE_ADDR_3 (0x27) + /** Access parameters for sub-register IEEE_ADDR_3 in register @ref RG_IEEE_ADDR_3 + * @ingroup apiHalPHY230Sreg + */ +# define SR_IEEE_ADDR_3 0x27, 0xff, 0 + +/** Offset for register IEEE_ADDR_4 + * @ingroup apiHalPHY230Reg + */ +#define RG_IEEE_ADDR_4 (0x28) + /** Access parameters for sub-register IEEE_ADDR_4 in register @ref RG_IEEE_ADDR_4 + * @ingroup apiHalPHY230Sreg + */ +# define SR_IEEE_ADDR_4 0x28, 0xff, 0 + +/** Offset for register IEEE_ADDR_5 + * @ingroup apiHalPHY230Reg + */ +#define RG_IEEE_ADDR_5 (0x29) + /** Access parameters for sub-register IEEE_ADDR_5 in register @ref RG_IEEE_ADDR_5 + * @ingroup apiHalPHY230Sreg + */ +# define SR_IEEE_ADDR_5 0x29, 0xff, 0 + +/** Offset for register IEEE_ADDR_6 + * @ingroup apiHalPHY230Reg + */ +#define RG_IEEE_ADDR_6 (0x2a) + /** Access parameters for sub-register IEEE_ADDR_6 in register @ref RG_IEEE_ADDR_6 + * @ingroup apiHalPHY230Sreg + */ +# define SR_IEEE_ADDR_6 0x2a, 0xff, 0 + +/** Offset for register IEEE_ADDR_7 + * @ingroup apiHalPHY230Reg + */ +#define RG_IEEE_ADDR_7 (0x2b) + /** Access parameters for sub-register IEEE_ADDR_7 in register @ref RG_IEEE_ADDR_7 + * @ingroup apiHalPHY230Sreg + */ +# define SR_IEEE_ADDR_7 0x2b, 0xff, 0 + +/** Offset for register XAH_CTRL + * @ingroup apiHalPHY230Reg + */ +#define RG_XAH_CTRL (0x2c) + /** Access parameters for sub-register MAX_FRAME_RETRIES in register @ref RG_XAH_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4 + /** Access parameters for sub-register MAX_CSMA_RETRIES in register @ref RG_XAH_CTRL + * @ingroup apiHalPHY230Sreg + */ +# define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1 +# define SR_reserved_2c_3 0x2c, 0x01, 0 + +/** Offset for register CSMA_SEED_0 + * @ingroup apiHalPHY230Reg + */ +#define RG_CSMA_SEED_0 (0x2d) + /** Access parameters for sub-register CSMA_SEED_0 in register @ref RG_CSMA_SEED_0 + * @ingroup apiHalPHY230Sreg + */ +# define SR_CSMA_SEED_0 0x2d, 0xff, 0 + +/** Offset for register CSMA_SEED_1 + * @ingroup apiHalPHY230Reg + */ +#define RG_CSMA_SEED_1 (0x2e) + /** Access parameters for sub-register MIN_BE in register @ref RG_CSMA_SEED_1 + * @ingroup apiHalPHY230Sreg + */ +# define SR_MIN_BE 0x2e, 0xc0, 6 +# define SR_reserved_2e_2 0x2e, 0x30, 4 + /** Access parameters for sub-register I_AM_COORD in register @ref RG_CSMA_SEED_1 + * @ingroup apiHalPHY230Sreg + */ +# define SR_I_AM_COORD 0x2e, 0x08, 3 + /** Access parameters for sub-register CSMA_SEED_1 in register @ref RG_CSMA_SEED_1 + * @ingroup apiHalPHY230Sreg + */ +# define SR_CSMA_SEED_1 0x2e, 0x07, 0 + +# define RG_ANT_DIV (0x0d) +//controls antenna diversity + +# define RG_RX_CTRL (0x0a) +//controls the sensitivity of the antenna diversity mode + +//=========================== typedef ========================================= + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +#endif diff --git a/sys/net/openwsn_stack/bsp/riot/board_info.h b/sys/net/openwsn_stack/bsp/riot/board_info.h index 963fe5835291..296f4e60a05c 100644 --- a/sys/net/openwsn_stack/bsp/riot/board_info.h +++ b/sys/net/openwsn_stack/bsp/riot/board_info.h @@ -14,6 +14,7 @@ to return the board's description. #include "stdint.h" #include "string.h" +#include "periph_conf.h" //=========================== defines ========================================= diff --git a/sys/net/openwsn_stack/bsp/riot/radio.c b/sys/net/openwsn_stack/bsp/riot/radio.c new file mode 100644 index 000000000000..5d60115ee43a --- /dev/null +++ b/sys/net/openwsn_stack/bsp/riot/radio.c @@ -0,0 +1,464 @@ +#include "board_ow.h" +#include "radio.h" +#include "at86rf231_ow.h" +#include "spi_ow.h" +#include "radiotimer.h" +#include "debugpins.h" +#include "leds.h" +#include "board.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + + +//=========================== defines ========================================= + +//=========================== variables ======================================= + +typedef struct { + radiotimer_capture_cbt startFrame_cb; + radiotimer_capture_cbt endFrame_cb; + radio_state_t state; +} radio_vars_t; + +radio_vars_t radio_vars; + +//=========================== prototypes ====================================== + +void radio_spiWriteReg(uint8_t reg_addr, uint8_t reg_setting); +uint8_t radio_spiReadReg(uint8_t reg_addr); +void radio_spiWriteTxFifo(uint8_t* bufToWrite, uint8_t lenToWrite); +void radio_spiReadRxFifo(uint8_t* pBufRead, + uint8_t* pLenRead, + uint8_t maxBufLen, + uint8_t* pLqi); +uint8_t radio_spiReadRadioInfo(void); + +//=========================== public ========================================== + +//===== admin + +void radio_init(void) { + + // clear variables + memset(&radio_vars,0,sizeof(radio_vars_t)); + + // change state + radio_vars.state = RADIOSTATE_STOPPED; + + // configure the radio + radio_spiWriteReg(RG_TRX_STATE, CMD_FORCE_TRX_OFF); // turn radio off + + radio_spiWriteReg(RG_IRQ_MASK, + (AT_IRQ_RX_START| AT_IRQ_TRX_END)); // tell radio to fire interrupt on TRX_END and RX_START + radio_spiReadReg(RG_IRQ_STATUS); // deassert the interrupt pin in case is high + radio_spiWriteReg(RG_ANT_DIV, RADIO_CHIP_ANTENNA); // use chip antenna +#define RG_TRX_CTRL_1 0x04 + radio_spiWriteReg(RG_TRX_CTRL_1, 0x20); // have the radio calculate CRC + //busy wait until radio status is TRX_OFF + uint16_t c = 0; + while((radio_spiReadReg(RG_TRX_STATUS) & 0x1F) != TRX_OFF) + ;// if (c++ == 10000) { +// DEBUG("radio_spiReadReg timeout\n"); +// break; +// } + + // change state + radio_vars.state = RADIOSTATE_RFOFF; +} + +void radio_setOverflowCb(radiotimer_compare_cbt cb) { + radiotimer_setOverflowCb(cb); +} + +void radio_setCompareCb(radiotimer_compare_cbt cb) { + radiotimer_setCompareCb(cb); +} + +void radio_setStartFrameCb(radiotimer_capture_cbt cb) { + radio_vars.startFrame_cb = cb; +} + +void radio_setEndFrameCb(radiotimer_capture_cbt cb) { + radio_vars.endFrame_cb = cb; +} + +//===== reset + +void radio_reset(void) { + PORT_PIN_RADIO_RESET_LOW(); +} + +//===== timer + +void radio_startTimer(PORT_TIMER_WIDTH period) { + radiotimer_start(period); +} + +PORT_TIMER_WIDTH radio_getTimerValue(void) { + return radiotimer_getValue(); +} + +void radio_setTimerPeriod(PORT_TIMER_WIDTH period) { + radiotimer_setPeriod(period); +} + +PORT_TIMER_WIDTH radio_getTimerPeriod(void) { + return radiotimer_getPeriod(); +} + +//===== RF admin + +void radio_setFrequency(uint8_t frequency) { + // change state + radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; + + // configure the radio to the right frequecy + radio_spiWriteReg(RG_PHY_CC_CCA,0x20+frequency); + + // change state + radio_vars.state = RADIOSTATE_FREQUENCY_SET; +} + +void radio_rfOn(void) { + PORT_PIN_RADIO_RESET_LOW(); +} + +void radio_rfOff(void) { + DEBUG("%s\n",__PRETTY_FUNCTION__); + // change state + radio_vars.state = RADIOSTATE_TURNING_OFF; + radio_spiReadReg(RG_TRX_STATUS); + DEBUG("step 1\n"); + // turn radio off + radio_spiWriteReg(RG_TRX_STATE, CMD_FORCE_TRX_OFF); + DEBUG("step 2\n"); + radio_spiWriteReg(RG_TRX_STATE, CMD_TRX_OFF); + + // busy wait until done + uint16_t c = 0; + while((radio_spiReadReg(RG_TRX_STATUS) & 0x1F) != TRX_OFF) + ;// if (c++ == 100000) { +// DEBUG("%s: radio_spiReadReg timeout\n", __PRETTY_FUNCTION__); +// break; +// } + + DEBUG("step 3\n"); + // wiggle debug pin + debugpins_radio_clr(); + leds_radio_off(); + DEBUG("step 4\n"); + // change state + radio_vars.state = RADIOSTATE_RFOFF; + DEBUG("step 5\n"); +} + +//===== TX + +void radio_loadPacket(uint8_t* packet, uint8_t len) { + // change state + radio_vars.state = RADIOSTATE_LOADING_PACKET; + + // load packet in TXFIFO + radio_spiWriteTxFifo(packet,len); + + // change state + radio_vars.state = RADIOSTATE_PACKET_LOADED; +} + +void radio_txEnable(void) { + // change state + radio_vars.state = RADIOSTATE_ENABLING_TX; + + // wiggle debug pin + debugpins_radio_set(); + leds_radio_on(); + + // turn on radio's PLL + radio_spiWriteReg(RG_TRX_STATE, CMD_PLL_ON); + uint16_t c = 0; + while((radio_spiReadReg(RG_TRX_STATUS) & 0x1F) != PLL_ON) // busy wait until done + ;// if (c++ == 100000) { +// DEBUG("%s: radio_spiReadReg timeout\n", __PRETTY_FUNCTION__); +// break; +// } + + // change state + radio_vars.state = RADIOSTATE_TX_ENABLED; +} + +void radio_txNow(void) { + PORT_TIMER_WIDTH val; + // change state + radio_vars.state = RADIOSTATE_TRANSMITTING; + leds_radio_toggle(); + // send packet by pulsing the SLP_TR_CNTL pin + PORT_PIN_RADIO_SLP_TR_CNTL_HIGH(); + PORT_PIN_RADIO_SLP_TR_CNTL_LOW(); + + // The AT86RF231 does not generate an interrupt when the radio transmits the + // SFD, which messes up the MAC state machine. The danger is that, if we leave + // this funtion like this, any radio watchdog timer will expire. + // Instead, we cheat an mimick a start of frame event by calling + // ieee154e_startOfFrame from here. This also means that software can never catch + // a radio glitch by which #radio_txEnable would not be followed by a packet being + // transmitted (I've never seen that). + if (radio_vars.startFrame_cb!=NULL) { + // call the callback + val=radiotimer_getCapturedTime(); + radio_vars.startFrame_cb(val); + } + DEBUG("SENT"); +} + +//===== RX + +void radio_rxEnable(void) { + // change state + radio_vars.state = RADIOSTATE_ENABLING_RX; + + // put radio in reception mode + radio_spiWriteReg(RG_TRX_STATE, CMD_RX_ON); + + // wiggle debug pin + debugpins_radio_set(); + leds_radio_on(); + + // busy wait until radio really listening + uint16_t c = 0; + while((radio_spiReadReg(RG_TRX_STATUS) & 0x1F) != RX_ON) + ;// if (c++ == 100000) { +// DEBUG("%s: radio_spiReadReg timeout\n",__PRETTY_FUNCTION__); +// break; +// } + + // change state + radio_vars.state = RADIOSTATE_LISTENING; +} + +void radio_rxNow(void) { + // nothing to do +} + +void radio_getReceivedFrame(uint8_t* pBufRead, + uint8_t* pLenRead, + uint8_t maxBufLen, + int8_t* pRssi, + uint8_t* pLqi, + uint8_t* pCrc) { + uint8_t temp_reg_value; + + //===== crc + temp_reg_value = radio_spiReadReg(RG_PHY_RSSI); + *pCrc = (temp_reg_value & 0x80)>>7; // msb is whether packet passed CRC + + //===== rssi + // as per section 8.4.3 of the AT86RF231, the RSSI is calculate as: + // -91 + ED [dBm] + temp_reg_value = radio_spiReadReg(RG_PHY_ED_LEVEL); + *pRssi = -91 + temp_reg_value; + + //===== packet + radio_spiReadRxFifo(pBufRead, + pLenRead, + maxBufLen, + pLqi); +} + +//=========================== private ========================================= + + +uint8_t radio_spiReadRadioInfo(void){ + uint8_t spi_tx_buffer[3]; + uint8_t spi_rx_buffer[3]; + + // prepare buffer to send over SPI + spi_tx_buffer[0] = (0x80 | 0x1E); // [b7] Read/Write: 1 (read) + // [b6] RAM/Register : 1 (register) + // [b5-0] address: 0x1E (Manufacturer ID, Lower 16 Bit) + spi_tx_buffer[1] = 0x00; // send a SNOP strobe just to get the reg value + spi_tx_buffer[2] = 0x00; // send a SNOP strobe just to get the reg value + + // retrieve radio manufacturer ID over SPI + spi_txrx(spi_tx_buffer, + sizeof(spi_tx_buffer), + SPI_BUFFER, + spi_rx_buffer, + sizeof(spi_rx_buffer), + SPI_FIRST, + SPI_LAST); + + return spi_rx_buffer[2]; +} + +void radio_spiWriteReg(uint8_t reg_addr, uint8_t reg_setting) { + uint8_t spi_tx_buffer[2]; + uint8_t spi_rx_buffer[2]; + + spi_tx_buffer[0] = (0xC0 | reg_addr); // turn addess in a 'reg write' address + spi_tx_buffer[1] = reg_setting; + + spi_txrx(spi_tx_buffer, + sizeof(spi_tx_buffer), + SPI_BUFFER, + (uint8_t*)spi_rx_buffer, + sizeof(spi_rx_buffer), + SPI_FIRST, + SPI_LAST); +} + +uint8_t radio_spiReadReg(uint8_t reg_addr) { + uint8_t spi_tx_buffer[2]; + uint8_t spi_rx_buffer[2]; + + spi_tx_buffer[0] = (0x80 | reg_addr); // turn addess in a 'reg read' address + spi_tx_buffer[1] = 0x00; // send a no_operation command just to get the reg value + + spi_txrx(spi_tx_buffer, + sizeof(spi_tx_buffer), + SPI_BUFFER, + (uint8_t*)spi_rx_buffer, + sizeof(spi_rx_buffer), + SPI_FIRST, + SPI_LAST); + + + return spi_rx_buffer[1]; +} + +/** for testing purposes, remove if not needed anymore**/ + +void radio_spiWriteTxFifo(uint8_t* bufToWrite, uint8_t lenToWrite) { + uint8_t spi_tx_buffer[2]; + uint8_t spi_rx_buffer[1+1+127]; // 1B SPI address, 1B length, max. 127B data + + spi_tx_buffer[0] = 0x60; // SPI destination address for TXFIFO + spi_tx_buffer[1] = lenToWrite; // length byte + + spi_txrx(spi_tx_buffer, + sizeof(spi_tx_buffer), + SPI_BUFFER, + spi_rx_buffer, + sizeof(spi_rx_buffer), + SPI_FIRST, + SPI_NOTLAST); + + spi_txrx(bufToWrite, + lenToWrite, + SPI_BUFFER, + spi_rx_buffer, + sizeof(spi_rx_buffer), + SPI_NOTFIRST, + SPI_LAST); +} + + + +void radio_spiReadRxFifo(uint8_t* pBufRead, + uint8_t* pLenRead, + uint8_t maxBufLen, + uint8_t* pLqi) { + // when reading the packet over SPI from the RX buffer, you get the following: + // - *[1B] dummy byte because of SPI + // - *[1B] length byte + // - [0-125B] packet (excluding CRC) + // - *[2B] CRC + // - *[1B] LQI + uint8_t spi_tx_buffer[125]; + uint8_t spi_rx_buffer[3]; + + spi_tx_buffer[0] = 0x20; + + // 2 first bytes + spi_txrx(spi_tx_buffer, + 2, + SPI_BUFFER, + spi_rx_buffer, + sizeof(spi_rx_buffer), + SPI_FIRST, + SPI_NOTLAST); + + *pLenRead = spi_rx_buffer[1]; + + if (*pLenRead>2 && *pLenRead<=127) { + // valid length + + //read packet + spi_txrx(spi_tx_buffer, + *pLenRead, + SPI_BUFFER, + pBufRead, + 125, + SPI_NOTFIRST, + SPI_NOTLAST); + + // CRC (2B) and LQI (1B) + spi_txrx(spi_tx_buffer, + 2+1, + SPI_BUFFER, + spi_rx_buffer, + 3, + SPI_NOTFIRST, + SPI_LAST); + + *pLqi = spi_rx_buffer[2]; + + } else { + // invalid length + + // read a just byte to close spi + spi_txrx(spi_tx_buffer, + 1, + SPI_BUFFER, + spi_rx_buffer, + sizeof(spi_rx_buffer), + SPI_NOTFIRST, + SPI_LAST); + } +} + +//=========================== callbacks ======================================= + +//=========================== interrupt handlers ============================== + +kick_scheduler_t radio_isr(void) { + PORT_TIMER_WIDTH capturedTime; + uint8_t irq_status; + + // capture the time + capturedTime = radiotimer_getCapturedTime(); + + // reading IRQ_STATUS causes radio's IRQ pin to go low + irq_status = radio_spiReadReg(RG_IRQ_STATUS); + + // start of frame event + if (irq_status & AT_IRQ_RX_START) { + DEBUG("Start of frame.\n"); + // change state + radio_vars.state = RADIOSTATE_RECEIVING; + if (radio_vars.startFrame_cb!=NULL) { + // call the callback + radio_vars.startFrame_cb(capturedTime); + // kick the OS + return KICK_SCHEDULER; + } else { + while(1); + } + } + // end of frame event + if (irq_status & AT_IRQ_TRX_END) { + DEBUG("End of Frame.\n"); + // change state + radio_vars.state = RADIOSTATE_TXRX_DONE; + if (radio_vars.endFrame_cb!=NULL) { + // call the callback + radio_vars.endFrame_cb(capturedTime); + // kick the OS + return KICK_SCHEDULER; + } else { + while(1); + } + } + + return DO_NOT_KICK_SCHEDULER; +} diff --git a/sys/net/openwsn_stack/bsp/riot/radiotimer.c b/sys/net/openwsn_stack/bsp/riot/radiotimer.c index c3729511465a..8c7fa23f88c3 100644 --- a/sys/net/openwsn_stack/bsp/riot/radiotimer.c +++ b/sys/net/openwsn_stack/bsp/riot/radiotimer.c @@ -89,19 +89,19 @@ uint16_t radiotimer_getPeriod(void) { //===== compare void radiotimer_schedule(uint16_t offset) { - timer_disable_interrupt(TIMER_1); + timer_irq_disable(TIMER_1); timer_set(TIMER_1, 1, offset); current_period = offset; - timer_enable_interrupt(TIMER_1); + timer_irq_enable(TIMER_1); //set radiotimer irpstatus radiotimer_vars.overflowORcompare = RADIOTIMER_COMPARE; } void radiotimer_cancel(void) { - timer_disable_interrupt(TIMER_1); + timer_irq_disable(TIMER_1); timer_clear(TIMER_1, 1); current_period = 0; - timer_enable_interrupt(TIMER_1); + timer_irq_enable(TIMER_1); //set radiotimer irpstatus radiotimer_vars.overflowORcompare = RADIOTIMER_OVERFLOW; diff --git a/sys/net/openwsn_stack/bsp/riot/spi_ow.c b/sys/net/openwsn_stack/bsp/riot/spi_ow.c new file mode 100644 index 000000000000..8119506695b7 --- /dev/null +++ b/sys/net/openwsn_stack/bsp/riot/spi_ow.c @@ -0,0 +1,258 @@ +#include "stdio.h" +#include "stdint.h" +#include "string.h" +#include "spi_ow.h" +#include "spi.h" +#include "leds.h" +#include "board.h" +#include "radio.h" +#include "periph/gpio.h" +#include "periph_conf.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +//=========================== defines ========================================= + +//=========================== variables ======================================= + +typedef struct { + // information about the current transaction + uint8_t* pNextTxByte; + uint8_t numTxedBytes; + uint8_t txBytesLeft; + spi_return_t returnType; + uint8_t* pNextRxByte; + uint8_t maxRxBytes; + spi_first_t isFirst; + spi_last_t isLast; + // state of the module + uint8_t busy; +#ifdef SPI_IN_INTERRUPT_MODE + // callback when module done + spi_cbt callback; +#endif +} spi_vars_t; + +volatile spi_vars_t spi_vars; + +//=========================== prototypes ====================================== +// inline static void RESET_CLR(void) { GPIOC->BRR = 1<<1; } +// inline static void RESET_SET(void) { GPIOC->BSRR = 1<<1; } +// inline static void CSn_SET(void) { GPIOA->BSRR = 1<<4; } +// inline static void CSn_CLR(void) { GPIOA->BRR = 1<<4; } +// inline static void SLEEP_CLR(void) { GPIOA->BRR = 1<<2; } +static inline void RESET_CLR(void) +{ + SPI_0_RESET_PORT->BRR = (1 << SPI_0_RESET_PIN); +} +static inline void RESET_SET(void) +{ + SPI_0_RESET_PORT->BSRR = (1 << SPI_0_RESET_PIN); +} +static inline void CSn_SET(void) +{ + SPI_0_CS_PORT->BSRR = (1 << SPI_0_CS_PIN); +} +static inline void CSn_CLR(void) +{ + SPI_0_CS_PORT->BRR = (1 << SPI_0_CS_PIN); +} +static inline void SLEEP_CLR(void) +{ + SPI_0_SLEEP_PORT->BRR = (1 << SPI_0_SLEEP_PIN); +} + +//=========================== public ========================================== + +void spi_init_ow(void) { + // clear variables + memset(&spi_vars,0,sizeof(spi_vars_t)); + /* CS */ + gpio_init_out(SPI_0_CS_GPIO, GPIO_NOPULL); + /* SLEEP */ + gpio_init_out(SPI_0_SLEEP_GPIO, GPIO_NOPULL); + /* RESET */ + gpio_init_out(SPI_0_RESET_GPIO, GPIO_NOPULL); + + // force reset + RESET_CLR(); + CSn_SET(); + SLEEP_CLR(); + + for (uint16_t j=0;j<0xFFFF;j++); //small wait + + RESET_SET(); + + /* set up GPIO pins */ + /* SCLK and MOSI*/ + GPIOA->CRL &= ~(0xf << (5 * 4)); + GPIOA->CRL |= (0xb << (5 * 4)); + GPIOA->CRL &= ~(0xf << (7 * 4)); + GPIOA->CRL |= (0xb << (7 * 4)); + /* MISO */ + gpio_init_in(SPI_0_MISO_GPIO, GPIO_NOPULL); + + /* SPI init */ + spi_init_master(SPI_0, SPI_CONF_FIRST_RISING, 4500000); + + spi_poweron(SPI_0); + + /* IRQ0 */ + gpio_init_in(SPI_0_IRQ0_GPIO, GPIO_NOPULL); + gpio_init_int(SPI_0_IRQ0_GPIO, GPIO_NOPULL, GPIO_RISING, radio_isr); + + /* Connect EXTI4 Line to PC4 pin */ + gpio_irq_enable(SPI_0_IRQ0_GPIO); + +} + +#ifdef SPI_IN_INTERRUPT_MODE +void spi_setCallback(spi_cbt cb) { + spi_vars.callback = cb; +} +#endif + +void spi_txrx(uint8_t* bufTx, + uint8_t lenbufTx, + spi_return_t returnType, + uint8_t* bufRx, + uint8_t maxLenBufRx, + spi_first_t isFirst, + spi_last_t isLast) { + +#ifdef SPI_IN_INTERRUPT_MODE + // disable interrupts + NVIC_RESETPRIMASK(); +#endif + + // register spi frame to send + spi_vars.pNextTxByte = bufTx; + spi_vars.numTxedBytes = 0; + spi_vars.txBytesLeft = lenbufTx; + spi_vars.returnType = returnType; + spi_vars.pNextRxByte = bufRx; + spi_vars.maxRxBytes = maxLenBufRx; + spi_vars.isFirst = isFirst; + spi_vars.isLast = isLast; + + // SPI is now busy + spi_vars.busy = 1; + + + // lower CS signal to have slave listening + if (spi_vars.isFirst==SPI_FIRST) { + CSn_CLR(); + } + +#ifdef SPI_IN_INTERRUPT_MODE + // implementation 1. use a callback function when transaction finishes + + // write first byte to TX buffer + SPI_I2S_SendData(SPI1,*spi_vars.pNextTxByte); + + // re-enable interrupts + NVIC_SETPRIMASK(); +#else + // implementation 2. busy wait for each byte to be sent + // send all bytes + while (spi_vars.txBytesLeft>0) { + // write next byte to TX buffer + // SPI_I2S_SendData(SPI1,*spi_vars.pNextTxByte); + spi_transfer_byte(SPI_0, *spi_vars.pNextTxByte, NULL); + + // busy wait on the interrupt flag +// uint16_t c = 0; +// while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET) +// ;// if (c++ == 10000) { +// // //DEBUG("spi_txrx timeout\n"); +// // break; +// // } + +// // clear the interrupt flag +// SPI_I2S_ClearFlag(SPI1, SPI_I2S_FLAG_RXNE); + // save the byte just received in the RX buffer + switch (spi_vars.returnType) { + case SPI_FIRSTBYTE: + if (spi_vars.numTxedBytes==0) { + spi_transfer_byte(SPI_0, 0, spi_vars.pNextRxByte); + // *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI1); + } + break; + case SPI_BUFFER: + spi_transfer_byte(SPI_0, 0, spi_vars.pNextRxByte); + // *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI1); + spi_vars.pNextRxByte++; + break; + case SPI_LASTBYTE: + spi_transfer_byte(SPI_0, 0, spi_vars.pNextRxByte); + // *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI1); + break; + } + // one byte less to go + spi_vars.pNextTxByte++; + spi_vars.numTxedBytes++; + spi_vars.txBytesLeft--; + } + + // put CS signal high to signal end of transmission to slave + if (spi_vars.isLast==SPI_LAST) { + CSn_SET(); + } + + // SPI is not busy anymore + spi_vars.busy = 0; +#endif +} + +//=========================== private ========================================= + +//=========================== interrupt handlers ============================== + +kick_scheduler_t spi_isr(void) { +#ifdef SPI_IN_INTERRUPT_MODE + // save the byte just received in the RX buffer + switch (spi_vars.returnType) { + case SPI_FIRSTBYTE: + if (spi_vars.numTxedBytes==0) { + *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI1); + } + break; + case SPI_BUFFER: + *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI1); + spi_vars.pNextRxByte++; + break; + case SPI_LASTBYTE: + *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI1); + break; + } + + // one byte less to go + spi_vars.pNextTxByte++; + spi_vars.numTxedBytes++; + spi_vars.txBytesLeft--; + + if (spi_vars.txBytesLeft>0) { + // write next byte to TX buffer + SPI_SendData(SPI1,*spi_vars.pNextTxByte); + } else { + // put CS signal high to signal end of transmission to slave + if (spi_vars.isLast==SPI_LAST) { + GPIO_SetBits(GPIOA, GPIO_Pin_4); + } + // SPI is not busy anymore + spi_vars.busy = 0; + + // SPI is done! + if (spi_vars.callback!=NULL) { + // call the callback + spi_vars.callback(); + // kick the OS + return 1; + } + } +#else + while(1);// this should never happen + return 1; +#endif +} diff --git a/sys/net/openwsn_stack/bsp/riot/uart.c b/sys/net/openwsn_stack/bsp/riot/uart.c index b6dd1cf508c1..b390f29b7618 100644 --- a/sys/net/openwsn_stack/bsp/riot/uart.c +++ b/sys/net/openwsn_stack/bsp/riot/uart.c @@ -1,4 +1,4 @@ -#include "uart.h" +#include "uart_ow.h" #include "leds.h" #include "periph/uart.h" diff --git a/sys/net/openwsn_stack/bsp/spi_ow.h b/sys/net/openwsn_stack/bsp/spi_ow.h new file mode 100644 index 000000000000..1181e62d8ee1 --- /dev/null +++ b/sys/net/openwsn_stack/bsp/spi_ow.h @@ -0,0 +1,67 @@ +/** +\brief Cross-platform declaration "spi" bsp module. + +\author Thomas Watteyne , February 2012. +*/ + +#ifndef __SPI_OW_H +#define __SPI_OW_H + +#include "stdint.h" +#include "board_ow.h" + +//=========================== define ========================================== + +/** +The SPI module functions in two modes: +- in "blocking" mode, all calls return only when the module is done. the CPU + is not available while the module is busy. This is the preferred method is + low-RAM system which can not run an RTOS +- in "interrupt" mode, calls are returned after the module has started a + transaction. When the transaction is done, the module uses a callback + function to signal this to the caller. This frees up CPU time, allowing for + other operations to happen concurrently. This is the preferred method when an + RTOS is present. +*/ +//#define SPI_IN_INTERRUPT_MODE + +//=========================== typedef ========================================= + +typedef enum { + SPI_FIRSTBYTE = 0, + SPI_BUFFER = 1, + SPI_LASTBYTE = 2, +} spi_return_t; + +typedef enum { + SPI_NOTFIRST = 0, + SPI_FIRST = 1, +} spi_first_t; + +typedef enum { + SPI_NOTLAST = 0, + SPI_LAST = 1, +} spi_last_t; + +typedef void (*spi_cbt)(void); + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +void spi_init_ow(void); +#ifdef SPI_IN_INTERRUPT_MODE +void spi_setCb(spi_cbt cb); +#endif +void spi_txrx(uint8_t* bufTx, + uint8_t lenbufTx, + spi_return_t returnType, + uint8_t* bufRx, + uint8_t maxLenBufRx, + spi_first_t isFirst, + spi_last_t isLast); + +// interrupt handlers +kick_scheduler_t spi_isr(void); + +#endif diff --git a/sys/net/openwsn_stack/bsp/uart.h b/sys/net/openwsn_stack/bsp/uart_ow.h similarity index 96% rename from sys/net/openwsn_stack/bsp/uart.h rename to sys/net/openwsn_stack/bsp/uart_ow.h index bf279825c115..bd26922faca5 100644 --- a/sys/net/openwsn_stack/bsp/uart.h +++ b/sys/net/openwsn_stack/bsp/uart_ow.h @@ -1,5 +1,5 @@ -#ifndef __UART_H -#define __UART_H +#ifndef __UART_OW_H +#define __UART_OW_H /** \addtogroup BSP diff --git a/sys/net/openwsn_stack/drivers/openserial.c b/sys/net/openwsn_stack/drivers/openserial.c index fca5aebfdf14..b8e9c5201c46 100644 --- a/sys/net/openwsn_stack/drivers/openserial.c +++ b/sys/net/openwsn_stack/drivers/openserial.c @@ -17,7 +17,7 @@ #include "openbridge.h" #include "leds.h" #include "schedule.h" -#include "uart.h" +#include "uart_ow.h" #include "opentimers.h" #include "openhdlc.h" diff --git a/sys/net/openwsn_stack/drivers/opentimers.c b/sys/net/openwsn_stack/drivers/opentimers.c index 9a2738664cb9..d39e831450d7 100644 --- a/sys/net/openwsn_stack/drivers/opentimers.c +++ b/sys/net/openwsn_stack/drivers/opentimers.c @@ -9,7 +9,8 @@ at most MAX_NUM_TIMERS timers. #include "openwsn.h" #include "opentimers.h" -#include "bsp_timer.h" +// #include "bsp_timer.h" +#include "periph/timer.h" #include "leds.h" //=========================== define ========================================== @@ -25,6 +26,11 @@ void opentimers_timer_callback(void); //=========================== public ========================================== +void opentimers_int_handler(int t) { + (void)t; + opentimers_timer_callback(); +} + /** \brief Initialize this module. @@ -45,7 +51,9 @@ void opentimers_init(void){ } // set callback for bsp_timers module - bsp_timer_set_callback(opentimers_timer_callback); + // bsp_timer_set_callback(opentimers_timer_callback); + timer_irq_enable(TIMER_2); + timer_init(TIMER_2, 1, opentimers_int_handler); } /** @@ -121,9 +129,11 @@ opentimer_id_t opentimers_start(uint32_t duration, timer_type_t type, time_type_ ) { opentimers_vars.currentTimeout = opentimers_vars.timersBuf[id].ticks_remaining; if (opentimers_vars.running==FALSE) { - bsp_timer_reset(); + // bsp_timer_reset(); + timer_reset(TIMER_2); } - bsp_timer_scheduleIn(opentimers_vars.timersBuf[id].ticks_remaining); + // bsp_timer_scheduleIn(opentimers_vars.timersBuf[id].ticks_remaining); + timer_set(TIMER_2, 1, opentimers_vars.timersBuf[id].ticks_remaining); } opentimers_vars.running = TRUE; @@ -274,7 +284,8 @@ void opentimers_timer_callback(void) { if (found==TRUE) { // at least one timer pending opentimers_vars.currentTimeout = min_timeout; - bsp_timer_scheduleIn(opentimers_vars.currentTimeout); + // bsp_timer_scheduleIn(opentimers_vars.currentTimeout); + timer_set(TIMER_2, 1, opentimers_vars.currentTimeout); } else { // no more timers pending opentimers_vars.running = FALSE; @@ -355,7 +366,8 @@ void opentimers_sleepTimeCompesation(uint16_t sleepTime) if (found==TRUE) { // at least one timer pending opentimers_vars.currentTimeout = min_timeout; - bsp_timer_scheduleIn(opentimers_vars.currentTimeout); + // bsp_timer_scheduleIn(opentimers_vars.currentTimeout); + timer_set(TIMER_2, 1, opentimers_vars.currentTimeout); } else { // no more timers pending opentimers_vars.running = FALSE; diff --git a/sys/net/openwsn_stack/openwsn/07-App/rleds/Makefile b/sys/net/openwsn_stack/openwsn/07-App/rleds/Makefile new file mode 100644 index 000000000000..b77bd905581b --- /dev/null +++ b/sys/net/openwsn_stack/openwsn/07-App/rleds/Makefile @@ -0,0 +1,12 @@ +MODULE = openwsn_stack + +INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ +INCLUDES += -I../../../drivers +INCLUDES += -I../../02a-MAClow +INCLUDES += -I../../02b-MAChigh +INCLUDES += -I../../03a-IPHC +INCLUDES += -I../../03b-IPv6 +INCLUDES += -I../../04-TRAN +INCLUDES += -I../../cross-layers + +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/openwsn_stack/openwsn/07-App/rleds/rleds.c b/sys/net/openwsn_stack/openwsn/07-App/rleds/rleds.c index f3a55994c0e1..3aea24e25260 100644 --- a/sys/net/openwsn_stack/openwsn/07-App/rleds/rleds.c +++ b/sys/net/openwsn_stack/openwsn/07-App/rleds/rleds.c @@ -30,7 +30,7 @@ void rleds_sendDone( //=========================== public ========================================== -void rleds__init() { +void rleds__init(void) { // prepare the resource descriptor for the /l path rleds_vars.desc.path0len = sizeof(rleds_path0)-1; @@ -123,4 +123,4 @@ owerror_t rleds_receive( */ void rleds_sendDone(OpenQueueEntry_t* msg, owerror_t error) { openqueue_freePacketBuffer(msg); -} \ No newline at end of file +} diff --git a/sys/net/openwsn_stack/openwsn/Makefile b/sys/net/openwsn_stack/openwsn/Makefile index 592c6a8b7e97..f10cb551c1cf 100644 --- a/sys/net/openwsn_stack/openwsn/Makefile +++ b/sys/net/openwsn_stack/openwsn/Makefile @@ -11,7 +11,7 @@ INCLUDES += -I$(CURDIR)/04-TRAN INCLUDES += -I$(CURDIR)/cross-layers INCLUDES += -I$(CURDIR)/07-App/rinfo INCLUDES += -I$(CURDIR)/07-App/rwellknown -#INCLUDES += -I$(CURDIR)/07-App/rleds +INCLUDES += -I$(CURDIR)/07-App/rleds INCLUDES += -I$(CURDIR)/07-App/r6t INCLUDES += -I$(CURDIR)/07-App/ohlone INCLUDES += -I$(CURDIR)/07-App/tcpecho