*** empty log message ***

This commit is contained in:
dak664 2009-07-08 16:17:07 +00:00
parent 49989dbe45
commit 1de298c72a
6 changed files with 2713 additions and 0 deletions

View file

@ -0,0 +1,6 @@
CONTIKI_TARGET_SOURCEFILES += rf230bb.c halbb.c
# timer.c
APPDIRS += $(CONTIKI)/cpu/avr/radio/rf230bb

View file

@ -0,0 +1,351 @@
/**
* @file
* @brief This file contains the register definitions for the AT86RF230.
* $Id: at86rf230_registermap.h,v 1.1 2009/07/08 16:17:07 dak664 Exp $
*/
/* Copyright (c) 2008, Swedish Institute of Computer Science
All rights reserved.
Additional fixes for AVR contributed by:
Colin O'Flynn coflynn@newae.com
Eric Gnoske egnoske@gmail.com
Blake Leverett bleverett@gmail.com
Mike Vidales mavida404@gmail.com
Kevin Brown kbrown3@uccs.edu
Nate Bohlmann nate@elfwerks.com
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
#ifndef PHY230_REGISTERMAP_EXTERNAL_H
#define PHY230_REGISTERMAP_EXTERNAL_H
#define HAVE_REGISTER_MAP (1)
/** Offset for register TRX_STATUS */
#define RG_TRX_STATUS (0x01)
/** Access parameters for sub-register CCA_DONE in register @ref RG_TRX_STATUS */
#define SR_CCA_DONE 0x01, 0x80, 7
/** Access parameters for sub-register CCA_STATUS in register @ref RG_TRX_STATUS */
#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 */
#define SR_TRX_STATUS 0x01, 0x1f, 0
/** Constant P_ON for sub-register @ref SR_TRX_STATUS */
#define P_ON (0)
/** Constant BUSY_RX for sub-register @ref SR_TRX_STATUS */
#define BUSY_RX (1)
/** Constant BUSY_TX for sub-register @ref SR_TRX_STATUS */
#define BUSY_TX (2)
/** Constant RX_ON for sub-register @ref SR_TRX_STATUS */
#define RX_ON (6)
/** Constant TRX_OFF for sub-register @ref SR_TRX_STATUS */
#define TRX_OFF (8)
/** Constant PLL_ON for sub-register @ref SR_TRX_STATUS */
#define PLL_ON (9)
/** Constant SLEEP for sub-register @ref SR_TRX_STATUS */
#define SLEEP (15)
/** Constant BUSY_RX_AACK for sub-register @ref SR_TRX_STATUS */
#define BUSY_RX_AACK (17)
/** Constant BUSY_TX_ARET for sub-register @ref SR_TRX_STATUS */
#define BUSY_TX_ARET (18)
/** Constant RX_AACK_ON for sub-register @ref SR_TRX_STATUS */
#define RX_AACK_ON (22)
/** Constant TX_ARET_ON for sub-register @ref SR_TRX_STATUS */
#define TX_ARET_ON (25)
/** Constant RX_ON_NOCLK for sub-register @ref SR_TRX_STATUS */
#define RX_ON_NOCLK (28)
/** Constant RX_AACK_ON_NOCLK for sub-register @ref SR_TRX_STATUS */
#define RX_AACK_ON_NOCLK (29)
/** Constant BUSY_RX_AACK_NOCLK for sub-register @ref SR_TRX_STATUS */
#define BUSY_RX_AACK_NOCLK (30)
/** Offset for register TRX_STATE */
#define RG_TRX_STATE (0x02)
/** Access parameters for sub-register TRAC_STATUS in register @ref RG_TRX_STATE */
#define SR_TRAC_STATUS 0x02, 0xe0, 5
/** Access parameters for sub-register TRX_CMD in register @ref RG_TRX_STATE */
#define SR_TRX_CMD 0x02, 0x1f, 0
/** Constant CMD_NOP for sub-register @ref SR_TRX_CMD */
#define CMD_NOP (0)
/** Constant CMD_TX_START for sub-register @ref SR_TRX_CMD */
#define CMD_TX_START (2)
/** Constant CMD_FORCE_TRX_OFF for sub-register @ref SR_TRX_CMD */
#define CMD_FORCE_TRX_OFF (3)
/** Constant CMD_RX_ON for sub-register @ref SR_TRX_CMD */
#define CMD_RX_ON (6)
/** Constant CMD_TRX_OFF for sub-register @ref SR_TRX_CMD */
#define CMD_TRX_OFF (8)
/** Constant CMD_PLL_ON for sub-register @ref SR_TRX_CMD */
#define CMD_PLL_ON (9)
/** Constant CMD_RX_AACK_ON for sub-register @ref SR_TRX_CMD */
#define CMD_RX_AACK_ON (22)
/** Constant CMD_TX_ARET_ON for sub-register @ref SR_TRX_CMD */
#define CMD_TX_ARET_ON (25)
/** Offset for register TRX_CTRL_0 */
#define RG_TRX_CTRL_0 (0x03)
/** Offset for register TRX_CTRL_1 */
#define RG_TRX_CTRL_1 (0x04)
/** Access parameters for sub-register PAD_IO in register @ref RG_TRX_CTRL_0 */
#define SR_PAD_IO 0x03, 0xc0, 6
/** Access parameters for sub-register PAD_IO_CLKM in register @ref RG_TRX_CTRL_0 */
#define SR_PAD_IO_CLKM 0x03, 0x30, 4
/** Constant CLKM_2mA for sub-register @ref SR_PAD_IO_CLKM */
#define CLKM_2mA (0)
/** Constant CLKM_4mA for sub-register @ref SR_PAD_IO_CLKM */
#define CLKM_4mA (1)
/** Constant CLKM_6mA for sub-register @ref SR_PAD_IO_CLKM */
#define CLKM_6mA (2)
/** Constant CLKM_8mA for sub-register @ref SR_PAD_IO_CLKM */
#define CLKM_8mA (3)
/** Access parameters for sub-register CLKM_SHA_SEL in register @ref RG_TRX_CTRL_0 */
#define SR_CLKM_SHA_SEL 0x03, 0x08, 3
/** Access parameters for sub-register CLKM_CTRL in register @ref RG_TRX_CTRL_0 */
#define SR_CLKM_CTRL 0x03, 0x07, 0
/** Constant CLKM_no_clock for sub-register @ref SR_CLKM_CTRL */
#define CLKM_no_clock (0)
/** Constant CLKM_1MHz for sub-register @ref SR_CLKM_CTRL */
#define CLKM_1MHz (1)
/** Constant CLKM_2MHz for sub-register @ref SR_CLKM_CTRL */
#define CLKM_2MHz (2)
/** Constant CLKM_4MHz for sub-register @ref SR_CLKM_CTRL */
#define CLKM_4MHz (3)
/** Constant CLKM_8MHz for sub-register @ref SR_CLKM_CTRL */
#define CLKM_8MHz (4)
/** Constant CLKM_16MHz for sub-register @ref SR_CLKM_CTRL */
#define CLKM_16MHz (5)
/** Offset for register PHY_TX_PWR */
#define RG_PHY_TX_PWR (0x05)
/** Access parameters for sub-register TX_AUTO_CRC_ON in register @ref RG_PHY_TX_PWR */
#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 */
#define SR_TX_PWR 0x05, 0x0f, 0
/** Offset for register PHY_RSSI */
#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 */
#define SR_RSSI 0x06, 0x1f, 0
/** Offset for register PHY_ED_LEVEL */
#define RG_PHY_ED_LEVEL (0x07)
/** Access parameters for sub-register ED_LEVEL in register @ref RG_PHY_ED_LEVEL */
#define SR_ED_LEVEL 0x07, 0xff, 0
/** Offset for register PHY_CC_CCA */
#define RG_PHY_CC_CCA (0x08)
/** Access parameters for sub-register CCA_REQUEST in register @ref RG_PHY_CC_CCA */
#define SR_CCA_REQUEST 0x08, 0x80, 7
/** Access parameters for sub-register CCA_MODE in register @ref RG_PHY_CC_CCA */
#define SR_CCA_MODE 0x08, 0x60, 5
/** Access parameters for sub-register CHANNEL in register @ref RG_PHY_CC_CCA */
#define SR_CHANNEL 0x08, 0x1f, 0
/** Offset for register CCA_THRES */
#define RG_CCA_THRES (0x09)
/** Access parameters for sub-register CCA_CS_THRES in register @ref RG_CCA_THRES */
#define SR_CCA_CS_THRES 0x09, 0xf0, 4
/** Access parameters for sub-register CCA_ED_THRES in register @ref RG_CCA_THRES */
#define SR_CCA_ED_THRES 0x09, 0x0f, 0
/** Offset for register IRQ_MASK */
#define RG_IRQ_MASK (0x0e)
/** Access parameters for sub-register IRQ_MASK in register @ref RG_IRQ_MASK */
#define SR_IRQ_MASK 0x0e, 0xff, 0
/** Offset for register IRQ_STATUS */
#define RG_IRQ_STATUS (0x0f)
/** Access parameters for sub-register IRQ_7_BAT_LOW in register @ref RG_IRQ_STATUS */
#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7
/** Access parameters for sub-register IRQ_6_TRX_UR in register @ref RG_IRQ_STATUS */
#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6
/** Access parameters for sub-register IRQ_5 in register @ref RG_IRQ_STATUS */
#define SR_IRQ_5 0x0f, 0x20, 5
/** Access parameters for sub-register IRQ_4 in register @ref RG_IRQ_STATUS */
#define SR_IRQ_4 0x0f, 0x10, 4
/** Access parameters for sub-register IRQ_3_TRX_END in register @ref RG_IRQ_STATUS */
#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3
/** Access parameters for sub-register IRQ_2_RX_START in register @ref RG_IRQ_STATUS */
#define SR_IRQ_2_RX_START 0x0f, 0x04, 2
/** Access parameters for sub-register IRQ_1_PLL_UNLOCK in register @ref RG_IRQ_STATUS */
#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1
/** Access parameters for sub-register IRQ_0_PLL_LOCK in register @ref RG_IRQ_STATUS */
#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0
/** Offset for register VREG_CTRL */
#define RG_VREG_CTRL (0x10)
/** Access parameters for sub-register AVREG_EXT in register @ref RG_VREG_CTRL */
#define SR_AVREG_EXT 0x10, 0x80, 7
/** Access parameters for sub-register AVDD_OK in register @ref RG_VREG_CTRL */
#define SR_AVDD_OK 0x10, 0x40, 6
/** Access parameters for sub-register AVREG_TRIM in register @ref RG_VREG_CTRL */
#define SR_AVREG_TRIM 0x10, 0x30, 4
/** Constant AVREG_1_80V for sub-register @ref SR_AVREG_TRIM */
#define AVREG_1_80V (0)
/** Constant AVREG_1_75V for sub-register @ref SR_AVREG_TRIM */
#define AVREG_1_75V (1)
/** Constant AVREG_1_84V for sub-register @ref SR_AVREG_TRIM */
#define AVREG_1_84V (2)
/** Constant AVREG_1_88V for sub-register @ref SR_AVREG_TRIM */
#define AVREG_1_88V (3)
/** Access parameters for sub-register DVREG_EXT in register @ref RG_VREG_CTRL */
#define SR_DVREG_EXT 0x10, 0x08, 3
/** Access parameters for sub-register DVDD_OK in register @ref RG_VREG_CTRL */
#define SR_DVDD_OK 0x10, 0x04, 2
/** Access parameters for sub-register DVREG_TRIM in register @ref RG_VREG_CTRL */
#define SR_DVREG_TRIM 0x10, 0x03, 0
/** Constant DVREG_1_80V for sub-register @ref SR_DVREG_TRIM */
#define DVREG_1_80V (0)
/** Constant DVREG_1_75V for sub-register @ref SR_DVREG_TRIM */
#define DVREG_1_75V (1)
/** Constant DVREG_1_84V for sub-register @ref SR_DVREG_TRIM */
#define DVREG_1_84V (2)
/** Constant DVREG_1_88V for sub-register @ref SR_DVREG_TRIM */
#define DVREG_1_88V (3)
/** Offset for register BATMON */
#define RG_BATMON (0x11)
#define SR_reserved_11_1 0x11, 0xc0, 6
/** Access parameters for sub-register BATMON_OK in register @ref RG_BATMON */
#define SR_BATMON_OK 0x11, 0x20, 5
/** Access parameters for sub-register BATMON_HR in register @ref RG_BATMON */
#define SR_BATMON_HR 0x11, 0x10, 4
/** Access parameters for sub-register BATMON_VTH in register @ref RG_BATMON */
#define SR_BATMON_VTH 0x11, 0x0f, 0
/** Offset for register XOSC_CTRL */
#define RG_XOSC_CTRL (0x12)
/** Offset for register RX_SYN */
#define RG_RX_SYN 0x15
/** Offset for register XAH_CTRL_1 */
#define RG_XAH_CTRL_1 0x17
/** Access parameters for sub-register XTAL_MODE in register @ref RG_XOSC_CTRL */
#define SR_XTAL_MODE 0x12, 0xf0, 4
/** Access parameters for sub-register XTAL_TRIM in register @ref RG_XOSC_CTRL */
#define SR_XTAL_TRIM 0x12, 0x0f, 0
/** Offset for register FTN_CTRL */
#define RG_FTN_CTRL (0x18)
/** Access parameters for sub-register FTN_START in register @ref RG_FTN_CTRL */
#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 */
#define SR_FTNV 0x18, 0x3f, 0
/** Offset for register PLL_CF */
#define RG_PLL_CF (0x1a)
/** Access parameters for sub-register PLL_CF_START in register @ref RG_PLL_CF */
#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 */
#define SR_PLL_CF 0x1a, 0x0f, 0
/** Offset for register PLL_DCU */
#define RG_PLL_DCU (0x1b)
/** Access parameters for sub-register PLL_DCU_START in register @ref RG_PLL_DCU */
#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 */
#define SR_PLL_DCUW 0x1b, 0x3f, 0
/** Offset for register PART_NUM */
#define RG_PART_NUM (0x1c)
/** Access parameters for sub-register PART_NUM in register @ref RG_PART_NUM */
#define SR_PART_NUM 0x1c, 0xff, 0
/** Constant RF230 for sub-register @ref SR_PART_NUM */
#define RF230 (2)
/** Offset for register VERSION_NUM */
#define RG_VERSION_NUM (0x1d)
/** Access parameters for sub-register VERSION_NUM in register @ref RG_VERSION_NUM */
#define SR_VERSION_NUM 0x1d, 0xff, 0
/** Offset for register MAN_ID_0 */
#define RG_MAN_ID_0 (0x1e)
/** Access parameters for sub-register MAN_ID_0 in register @ref RG_MAN_ID_0 */
#define SR_MAN_ID_0 0x1e, 0xff, 0
/** Offset for register MAN_ID_1 */
#define RG_MAN_ID_1 (0x1f)
/** Access parameters for sub-register MAN_ID_1 in register @ref RG_MAN_ID_1 */
#define SR_MAN_ID_1 0x1f, 0xff, 0
/** Offset for register SHORT_ADDR_0 */
#define RG_SHORT_ADDR_0 (0x20)
/** Access parameters for sub-register SHORT_ADDR_0 in register @ref RG_SHORT_ADDR_0 */
#define SR_SHORT_ADDR_0 0x20, 0xff, 0
/** Offset for register SHORT_ADDR_1 */
#define RG_SHORT_ADDR_1 (0x21)
/** Access parameters for sub-register SHORT_ADDR_1 in register @ref RG_SHORT_ADDR_1 */
#define SR_SHORT_ADDR_1 0x21, 0xff, 0
/** Offset for register PAN_ID_0 */
#define RG_PAN_ID_0 (0x22)
/** Access parameters for sub-register PAN_ID_0 in register @ref RG_PAN_ID_0 */
#define SR_PAN_ID_0 0x22, 0xff, 0
/** Offset for register PAN_ID_1 */
#define RG_PAN_ID_1 (0x23)
/** Access parameters for sub-register PAN_ID_1 in register @ref RG_PAN_ID_1 */
#define SR_PAN_ID_1 0x23, 0xff, 0
/** Offset for register IEEE_ADDR_0 */
#define RG_IEEE_ADDR_0 (0x24)
/** Access parameters for sub-register IEEE_ADDR_0 in register @ref RG_IEEE_ADDR_0 */
#define SR_IEEE_ADDR_0 0x24, 0xff, 0
/** Offset for register IEEE_ADDR_1 */
#define RG_IEEE_ADDR_1 (0x25)
/** Access parameters for sub-register IEEE_ADDR_1 in register @ref RG_IEEE_ADDR_1 */
#define SR_IEEE_ADDR_1 0x25, 0xff, 0
/** Offset for register IEEE_ADDR_2 */
#define RG_IEEE_ADDR_2 (0x26)
/** Access parameters for sub-register IEEE_ADDR_2 in register @ref RG_IEEE_ADDR_2 */
#define SR_IEEE_ADDR_2 0x26, 0xff, 0
/** Offset for register IEEE_ADDR_3 */
#define RG_IEEE_ADDR_3 (0x27)
/** Access parameters for sub-register IEEE_ADDR_3 in register @ref RG_IEEE_ADDR_3 */
#define SR_IEEE_ADDR_3 0x27, 0xff, 0
/** Offset for register IEEE_ADDR_4 */
#define RG_IEEE_ADDR_4 (0x28)
/** Access parameters for sub-register IEEE_ADDR_4 in register @ref RG_IEEE_ADDR_4 */
#define SR_IEEE_ADDR_4 0x28, 0xff, 0
/** Offset for register IEEE_ADDR_5 */
#define RG_IEEE_ADDR_5 (0x29)
/** Access parameters for sub-register IEEE_ADDR_5 in register @ref RG_IEEE_ADDR_5 */
#define SR_IEEE_ADDR_5 0x29, 0xff, 0
/** Offset for register IEEE_ADDR_6 */
#define RG_IEEE_ADDR_6 (0x2a)
/** Access parameters for sub-register IEEE_ADDR_6 in register @ref RG_IEEE_ADDR_6 */
#define SR_IEEE_ADDR_6 0x2a, 0xff, 0
/** Offset for register IEEE_ADDR_7 */
#define RG_IEEE_ADDR_7 (0x2b)
/** Access parameters for sub-register IEEE_ADDR_7 in register @ref RG_IEEE_ADDR_7 */
#define SR_IEEE_ADDR_7 0x2b, 0xff, 0
/** Offset for register XAH_CTRL */
#define RG_XAH_CTRL_0 (0x2c)
/** Access parameters for sub-register MAX_FRAME_RETRIES in register @ref RG_XAH_CTRL_0 */
#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4
/** Access parameters for sub-register MAX_CSMA_RETRIES in register @ref RG_XAH_CTRL_0 */
#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1
#define SR_reserved_2c_3 0x2c, 0x01, 0
/** Offset for register CSMA_SEED_0 */
#define RG_CSMA_SEED_0 (0x2d)
/** Access parameters for sub-register CSMA_SEED_0 in register @ref RG_CSMA_SEED_0 */
#define SR_CSMA_SEED_0 0x2d, 0xff, 0
/** Offset for register CSMA_SEED_1 */
#define RG_CSMA_SEED_1 (0x2e)
/** Offset for register CSMA_BE */
#define RG_CSMA_BE 0x2f
/** Access parameters for sub-register MIN_BE in register @ref RG_CSMA_SEED_1 */
#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 */
#define SR_I_AM_COORD 0x2e, 0x08, 3
/** Access parameters for sub-register CSMA_SEED_1 in register @ref RG_CSMA_SEED_1 */
#define SR_CSMA_SEED_1 0x2e, 0x07, 0
#endif /* PHY230_REGISTERMAP_EXTERNAL_H */

374
cpu/avr/radio/rf230bb/hal.h Normal file
View file

@ -0,0 +1,374 @@
/* Copyright (c) 2008, Swedish Institute of Computer Science
* All rights reserved.
*
* Additional fixes for AVR contributed by:
*
* Colin O'Flynn coflynn@newae.com
* Eric Gnoske egnoske@gmail.com
* Blake Leverett bleverett@gmail.com
* Mike Vidales mavida404@gmail.com
* Kevin Brown kbrown3@uccs.edu
* Nate Bohlmann nate@elfwerks.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/**
* \addtogroup hal
* @{
*/
/**
* \file
* \brief This file contains low-level radio driver code.
*
* $Id: hal.h,v 1.1 2009/07/08 16:17:07 dak664 Exp $
*/
#ifndef HAL_AVR_H
#define HAL_AVR_H
/*============================ INCLUDE =======================================*/
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/crc16.h>
#include "contiki-conf.h"
/*============================ MACROS ========================================*/
// TEST CODE
#define TRIG1 DDRB |= 0x04, PINB |= 0x04
#define TRIG2 DDRD |= 0x80, PIND |= 0x80
/** \name This is the list of pin configurations needed for a given platform.
* \brief Change these values to port to other platforms.
* \{
*/
/* Define all possible revisions here */
// RAVEN_D : Raven kit with LCD display
// RAVENUSB_C : used for USB key or Raven card
// RCB_B : RZ200 kit from Atmel based on 1281V
// ZIGBIT : Zigbit module from Meshnetics
#define RAVEN_D 0
#define RAVENUSB_C 1
#define RCB_B 2
#define ZIGBIT 3
#if RCB_REVISION == RCB_B
/* 1281 rcb */
# define SSPORT B
# define SSPIN (0x00)
# define SPIPORT B
# define MOSIPIN (0x02)
# define MISOPIN (0x03)
# define SCKPIN (0x01)
# define RSTPORT B
# define RSTPIN (0x05)
# define IRQPORT D
# define IRQPIN (0x04)
# define SLPTRPORT B
# define SLPTRPIN (0x04)
# define USART 1
# define USARTVECT USART1_RX_vect
# define TICKTIMER 3
# define HAS_SPARE_TIMER
#elif HARWARE_REVISION == ZIGBIT
/* 1281V Zigbit */
# define SSPORT B
# define SSPIN (0x00)
# define SPIPORT B
# define MOSIPIN (0x02)
# define MISOPIN (0x03)
# define SCKPIN (0x01)
# define RSTPORT A
# define RSTPIN (0x07)
# define IRQPORT E
# define IRQPIN (0x05)
# define SLPTRPORT B
# define SLPTRPIN (0x04)
# define TXCWPORT B
# define TXCWPIN (0x07)
# define USART 1
# define USARTVECT USART1_RX_vect
//# define TICKTIMER 3
//# define HAS_SPARE_TIMER // Not used
#elif RAVEN_REVISION == RAVEN_D
/* 1284 raven */
# define SSPORT B
# define SSPIN (0x04)
# define SPIPORT B
# define MOSIPIN (0x05)
# define MISOPIN (0x06)
# define SCKPIN (0x07)
# define RSTPORT B
# define RSTPIN (0x01)
# define IRQPORT D
# define IRQPIN (0x06)
# define SLPTRPORT B
# define SLPTRPIN (0x03)
# define TXCWPORT B
# define TXCWPIN (0x00)
# define USART 1
# define USARTVECT USART1_RX_vect
# define TICKTIMER 3
# define HAS_CW_MODE
# define HAS_SPARE_TIMER
#elif RAVEN_REVISION == RAVENUSB_C
/* 1287USB raven */
# define SSPORT B
# define SSPIN (0x00)
# define SPIPORT B
# define MOSIPIN (0x02)
# define MISOPIN (0x03)
# define SCKPIN (0x01)
# define RSTPORT B
# define RSTPIN (0x05)
# define IRQPORT D
# define IRQPIN (0x04)
# define SLPTRPORT B
# define SLPTRPIN (0x04)
# define TXCWPORT B
# define TXCWPIN (0x07)
# define USART 1
# define USARTVECT USART1_RX_vect
# define TICKTIMER 3
# define HAS_CW_MODE
# define HAS_SPARE_TIMER
#else
#error "Platform undefined in hal.h"
#endif
/** \} */
/**
* \name Macros used to generate read register names from platform-specific definitions of ports.
* \brief The various CAT macros (DDR, PORT, and PIN) are used to
* assign port/pin/DDR names to various macro variables. The
* variables are assigned based on the specific connections made in
* the hardware. For example TCCR(TICKTIMER,A) can be used in place of TCCR0A
* if TICKTIMER is defined as 0.
* \{
*/
#define CAT(x, y) x##y
#define CAT2(x, y, z) x##y##z
#define DDR(x) CAT(DDR, x)
#define PORT(x) CAT(PORT, x)
#define PIN(x) CAT(PIN, x)
#define UCSR(num, let) CAT2(UCSR,num,let)
#define RXEN(x) CAT(RXEN,x)
#define TXEN(x) CAT(TXEN,x)
#define TXC(x) CAT(TXC,x)
#define RXC(x) CAT(RXC,x)
#define RXCIE(x) CAT(RXCIE,x)
#define UCSZ(x,y) CAT2(UCSZ,x,y)
#define UBRR(x,y) CAT2(UBRR,x,y)
#define UDRE(x) CAT(UDRE,x)
#define UDRIE(x) CAT(UDRIE,x)
#define UDR(x) CAT(UDR,x)
#define TCNT(x) CAT(TCNT,x)
#define TIMSK(x) CAT(TIMSK,x)
#define TCCR(x,y) CAT2(TCCR,x,y)
#define COM(x,y) CAT2(COM,x,y)
#define OCR(x,y) CAT2(OCR,x,y)
#define CS(x,y) CAT2(CS,x,y)
#define WGM(x,y) CAT2(WGM,x,y)
#define OCIE(x,y) CAT2(OCIE,x,y)
#define COMPVECT(x) CAT2(TIMER,x,_COMPA_vect)
#define UDREVECT(x) CAT2(USART,x,_UDRE_vect)
#define RXVECT(x) CAT2(USART,x,_RX_vect)
/** \} */
/**
* \name Pin macros
* \brief These macros convert the platform-specific pin defines into names and functions
* that the source code can directly use.
* \{
*/
#define SLP_TR SLPTRPIN /**< Pin number that corresponds to the SLP_TR pin. */
#define DDR_SLP_TR DDR( SLPTRPORT ) /**< Data Direction Register that corresponds to the port where SLP_TR is connected. */
#define PORT_SLP_TR PORT( SLPTRPORT ) /**< Port (Write Access) where SLP_TR is connected. */
#define PIN_SLP_TR PIN( SLPTRPORT ) /**< Pin (Read Access) where SLP_TR is connected. */
#define hal_set_slptr_high( ) ( PORT_SLP_TR |= ( 1 << SLP_TR ) ) /**< This macro pulls the SLP_TR pin high. */
#define hal_set_slptr_low( ) ( PORT_SLP_TR &= ~( 1 << SLP_TR ) ) /**< This macro pulls the SLP_TR pin low. */
#define hal_get_slptr( ) ( ( PIN_SLP_TR & ( 1 << SLP_TR ) ) >> SLP_TR ) /**< Read current state of the SLP_TR pin (High/Low). */
#define RST RSTPIN /**< Pin number that corresponds to the RST pin. */
#define DDR_RST DDR( RSTPORT ) /**< Data Direction Register that corresponds to the port where RST is */
#define PORT_RST PORT( RSTPORT ) /**< Port (Write Access) where RST is connected. */
#define PIN_RST PIN( RSTPORT ) /**< Pin (Read Access) where RST is connected. */
#define hal_set_rst_high( ) ( PORT_RST |= ( 1 << RST ) ) /**< This macro pulls the RST pin high. */
#define hal_set_rst_low( ) ( PORT_RST &= ~( 1 << RST ) ) /**< This macro pulls the RST pin low. */
#define hal_get_rst( ) ( ( PIN_RST & ( 1 << RST ) ) >> RST ) /**< Read current state of the RST pin (High/Low). */
#define HAL_SS_PIN SSPIN /**< The slave select pin. */
#define HAL_PORT_SPI PORT( SPIPORT ) /**< The SPI module is located on PORTB. */
#define HAL_DDR_SPI DDR( SPIPORT ) /**< Data Direction Register for PORTB. */
#define HAL_DD_SS SSPIN /**< Data Direction bit for SS. */
#define HAL_DD_SCK SCKPIN /**< Data Direction bit for SCK. */
#define HAL_DD_MOSI MOSIPIN /**< Data Direction bit for MOSI. */
#define HAL_DD_MISO MISOPIN /**< Data Direction bit for MISO. */
/** \} */
#define HAL_SS_HIGH( ) (HAL_PORT_SPI |= ( 1 << HAL_SS_PIN )) /**< MACRO for pulling SS high. */
#define HAL_SS_LOW( ) (HAL_PORT_SPI &= ~( 1 << HAL_SS_PIN )) /**< MACRO for pulling SS low. */
/** \brief Macros defined for HAL_TIMER1.
*
* These macros are used to define the correct setupt of the AVR's Timer1, and
* to ensure that the hal_get_system_time function returns the system time in
* symbols (16 us ticks).
*/
#if ( F_CPU == 16000000UL )
#define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS12 ) )
#define HAL_US_PER_SYMBOL ( 1 )
#define HAL_SYMBOL_MASK ( 0xFFFFffff )
#elif ( F_CPU == 8000000UL )
#define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) )
#define HAL_US_PER_SYMBOL ( 2 )
#define HAL_SYMBOL_MASK ( 0x7FFFffff )
#elif ( F_CPU == 4000000UL )
#define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) )
#define HAL_US_PER_SYMBOL ( 1 )
#define HAL_SYMBOL_MASK ( 0xFFFFffff )
#elif ( F_CPU == 1000000UL )
#define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) )
#define HAL_US_PER_SYMBOL ( 2 )
#define HAL_SYMBOL_MASK ( 0x7FFFffff )
#else
#error "Clock speed not supported."
#endif
#if HARWARE_REVISION == ZIGBIT
// IRQ E5 for Zigbit example
#define RADIO_VECT INT5_vect
#define HAL_ENABLE_RADIO_INTERRUPT( ) { ( EIMSK |= ( 1 << INT5 ) ) ; EICRB |= 0x0C ; PORTE &= ~(1<<PE5); DDRE &= ~(1<<DDE5); }
#define HAL_DISABLE_RADIO_INTERRUPT( ) ( EIMSK &= ~( 1 << INT5 ) )
#else
#define RADIO_VECT TIMER1_CAPT_vect
#define HAL_ENABLE_RADIO_INTERRUPT( ) ( TIMSK1 |= ( 1 << ICIE1 ) )
#define HAL_DISABLE_RADIO_INTERRUPT( ) ( TIMSK1 &= ~( 1 << ICIE1 ) )
#endif
#define HAL_ENABLE_OVERFLOW_INTERRUPT( ) ( TIMSK1 |= ( 1 << TOIE1 ) )
#define HAL_DISABLE_OVERFLOW_INTERRUPT( ) ( TIMSK1 &= ~( 1 << TOIE1 ) )
/** This macro will protect the following code from interrupts.*/
#define AVR_ENTER_CRITICAL_REGION( ) {uint8_t volatile saved_sreg = SREG; cli( )
/** This macro must always be used in conjunction with AVR_ENTER_CRITICAL_REGION
so that interrupts are enabled again.*/
#define AVR_LEAVE_CRITICAL_REGION( ) SREG = saved_sreg;}
/** \brief Enable the interrupt from the radio transceiver.
*/
#define hal_enable_trx_interrupt( ) HAL_ENABLE_RADIO_INTERRUPT( )
/** \brief Disable the interrupt from the radio transceiver.
*
* \retval 0 if the pin is low, 1 if the pin is high.
*/
#define hal_disable_trx_interrupt( ) HAL_DISABLE_RADIO_INTERRUPT( )
/*============================ TYPDEFS =======================================*/
/*============================ PROTOTYPES ====================================*/
/*============================ MACROS ========================================*/
/** \name Macros for radio operation.
* \{
*/
#define HAL_BAT_LOW_MASK ( 0x80 ) /**< Mask for the BAT_LOW interrupt. */
#define HAL_TRX_UR_MASK ( 0x40 ) /**< Mask for the TRX_UR interrupt. */
#define HAL_TRX_END_MASK ( 0x08 ) /**< Mask for the TRX_END interrupt. */
#define HAL_RX_START_MASK ( 0x04 ) /**< Mask for the RX_START interrupt. */
#define HAL_PLL_UNLOCK_MASK ( 0x02 ) /**< Mask for the PLL_UNLOCK interrupt. */
#define HAL_PLL_LOCK_MASK ( 0x01 ) /**< Mask for the PLL_LOCK interrupt. */
#define HAL_MIN_FRAME_LENGTH ( 0x03 ) /**< A frame should be at least 3 bytes. */
#define HAL_MAX_FRAME_LENGTH ( 0x7F ) /**< A frame should no more than 127 bytes. */
/** \} */
/*============================ TYPDEFS =======================================*/
/** \struct hal_rx_frame_t
* \brief This struct defines the rx data container.
*
* \see hal_frame_read
*/
typedef struct{
uint8_t length; /**< Length of frame. */
uint8_t data[ HAL_MAX_FRAME_LENGTH ]; /**< Actual frame data. */
uint8_t lqi; /**< LQI value for received frame. */
bool crc; /**< Flag - did CRC pass for received frame? */
} hal_rx_frame_t;
/** RX_START event handler callback type. Is called with timestamp in IEEE 802.15.4 symbols and frame length. See hal_set_rx_start_event_handler(). */
typedef void (*hal_rx_start_isr_event_handler_t)(uint32_t const isr_timestamp, uint8_t const frame_length);
/** RRX_END event handler callback type. Is called with timestamp in IEEE 802.15.4 symbols and frame length. See hal_set_trx_end_event_handler(). */
typedef void (*hal_trx_end_isr_event_handler_t)(uint32_t const isr_timestamp);
typedef void (*rx_callback_t) (uint16_t data);
/*============================ PROTOTYPES ====================================*/
void hal_init( void );
void hal_reset_flags( void );
uint8_t hal_get_bat_low_flag( void );
void hal_clear_bat_low_flag( void );
hal_trx_end_isr_event_handler_t hal_get_trx_end_event_handler( void );
void hal_set_trx_end_event_handler( hal_trx_end_isr_event_handler_t trx_end_callback_handle );
void hal_clear_trx_end_event_handler( void );
hal_rx_start_isr_event_handler_t hal_get_rx_start_event_handler( void );
void hal_set_rx_start_event_handler( hal_rx_start_isr_event_handler_t rx_start_callback_handle );
void hal_clear_rx_start_event_handler( void );
uint8_t hal_get_pll_lock_flag( void );
void hal_clear_pll_lock_flag( void );
uint8_t hal_register_read( uint8_t address );
void hal_register_write( uint8_t address, uint8_t value );
uint8_t hal_subregister_read( uint8_t address, uint8_t mask, uint8_t position );
void hal_subregister_write( uint8_t address, uint8_t mask, uint8_t position,
uint8_t value );
void hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback);
void hal_frame_write( uint8_t *write_buffer, uint8_t length );
void hal_sram_read( uint8_t address, uint8_t length, uint8_t *data );
void hal_sram_write( uint8_t address, uint8_t length, uint8_t *data );
#endif
/** @} */
/*EOF*/

View file

@ -0,0 +1,770 @@
/* Copyright (c) 2009, Swedish Institute of Computer Science
* All rights reserved.
*
* Additional fixes for AVR contributed by:
*
* Colin O'Flynn coflynn@newae.com
* Eric Gnoske egnoske@gmail.com
* Blake Leverett bleverett@gmail.com
* Mike Vidales mavida404@gmail.com
* Kevin Brown kbrown3@uccs.edu
* Nate Bohlmann nate@elfwerks.com
* David Kopf dak664@embarqmail.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*
*
*/
/**
* \addtogroup wireless
* @{
*/
/**
* \defgroup hal RF230 hardware level drivers
* @{
*/
/**
* \file
* This file contains low-level radio driver code.
* This version is optimized for use with the "barebones" RF230bb driver,
* which communicates directly with the contiki core MAC layer.
*/
/*============================ INCLUDE =======================================*/
#include <stdlib.h>
#include "hal.h"
#include "at86rf230_registermap.h"
/*============================ MACROS ========================================*/
/*
* Macros defined for the radio transceiver's access modes.
*
* These functions are implemented as macros since they are used very often.
*/
#define HAL_DUMMY_READ (0x00) /**< Dummy value for the SPI. */
#define HAL_TRX_CMD_RW (0xC0) /**< Register Write (short mode). */
#define HAL_TRX_CMD_RR (0x80) /**< Register Read (short mode). */
#define HAL_TRX_CMD_FW (0x60) /**< Frame Transmit Mode (long mode). */
#define HAL_TRX_CMD_FR (0x20) /**< Frame Receive Mode (long mode). */
#define HAL_TRX_CMD_SW (0x40) /**< SRAM Write. */
#define HAL_TRX_CMD_SR (0x00) /**< SRAM Read. */
#define HAL_TRX_CMD_RADDRM (0x7F) /**< Register Address Mask. */
#define HAL_CALCULATED_CRC_OK (0) /**< CRC calculated over the frame including the CRC field should be 0. */
/*============================ TYPDEFS =======================================*/
/*============================ VARIABLES =====================================*/
/** \brief This is a file internal variable that contains the 16 MSB of the
* system time.
*
* The system time (32-bit) is the current time in microseconds. For the
* AVR microcontroller implementation this is solved by using a 16-bit
* timer (Timer1) with a clock frequency of 1MHz. The hal_system_time is
* incremented when the 16-bit timer overflows, representing the 16 MSB.
* The timer value it self (TCNT1) is then the 16 LSB.
*
* \see hal_get_system_time
*/
static uint16_t hal_system_time = 0;
/*Flag section.*/
//static uint8_t volatile hal_bat_low_flag; /**< BAT_LOW flag. */
//static uint8_t volatile hal_pll_lock_flag; /**< PLL_LOCK flag. */
/*Callbacks.*/
/** \brief This function is called when a rx_start interrupt is signaled.
*
* If this function pointer is set to something else than NULL, it will
* be called when a RX_START event is signaled. The function takes two
* parameters: timestamp in IEEE 802.15.4 symbols (16 us resolution) and
* frame length. The event handler will be called in the interrupt domain,
* so the function must be kept short and not be blocking! Otherwise the
* system performance will be greatly degraded.
*
* \see hal_set_rx_start_event_handler
*/
//static hal_rx_start_isr_event_handler_t rx_start_callback;
/** \brief This function is called when a trx_end interrupt is signaled.
*
* If this function pointer is set to something else than NULL, it will
* be called when a TRX_END event is signaled. The function takes one
* parameter: timestamp in IEEE 802.15.4 symbols (16 us resolution).
* The event handler will be called in the interrupt domain,
* so the function must not block!
*
* \see hal_set_trx_end_event_handler
*/
//static hal_trx_end_isr_event_handler_t trx_end_callback;
/*============================ PROTOTYPES ====================================*/
/*============================ IMPLEMENTATION ================================*/
/** \brief This function initializes the Hardware Abstraction Layer.
*/
void
hal_init(void)
{
/*Reset variables used in file.*/
hal_system_time = 0;
// hal_reset_flags();
/*IO Specific Initialization.*/
DDR_SLP_TR |= (1 << SLP_TR); /* Enable SLP_TR as output. */
DDR_RST |= (1 << RST); /* Enable RST as output. */
/*SPI Specific Initialization.*/
/* Set SS, CLK and MOSI as output. */
HAL_DDR_SPI |= (1 << HAL_DD_SS) | (1 << HAL_DD_SCK) | (1 << HAL_DD_MOSI);
HAL_PORT_SPI |= (1 << HAL_DD_SS) | (1 << HAL_DD_SCK); /* Set SS and CLK high */
/* Run SPI at max speed */
SPCR = (1 << SPE) | (1 << MSTR); /* Enable SPI module and master operation. */
SPSR = (1 << SPI2X); /* Enable doubled SPI speed in master mode. */
/*TIMER1 Specific Initialization.*/
TCCR1B = HAL_TCCR1B_CONFIG; /* Set clock prescaler */
TIFR1 |= (1 << ICF1); /* Clear Input Capture Flag. */
HAL_ENABLE_OVERFLOW_INTERRUPT(); /* Enable Timer1 overflow interrupt. */
hal_enable_trx_interrupt(); /* Enable interrupts from the radio transceiver. */
}
/*----------------------------------------------------------------------------*/
/** \brief This function reset the interrupt flags and interrupt event handlers
* (Callbacks) to their default value.
*/
//void
//hal_reset_flags(void)
//{
// AVR_ENTER_CRITICAL_REGION();
/* Reset Flags. */
// hal_bat_low_flag = 0;
// hal_pll_lock_flag = 0;
/* Reset Associated Event Handlers. */
// rx_start_callback = NULL;
// trx_end_callback = NULL;
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/** \brief This function returns the current value of the BAT_LOW flag.
*
* The BAT_LOW flag is incremented each time a BAT_LOW event is signaled from the
* radio transceiver. This way it is possible for the end user to poll the flag
* for new event occurances.
*/
//uint8_t
//hal_get_bat_low_flag(void)
//{
// return hal_bat_low_flag;
//}
/*----------------------------------------------------------------------------*/
/** \brief This function clears the BAT_LOW flag.
*/
//void
//hal_clear_bat_low_flag(void)
//{
// AVR_ENTER_CRITICAL_REGION();
// hal_bat_low_flag = 0;
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/** \brief This function is used to set new TRX_END event handler, overriding
* old handler reference.
*/
//hal_trx_end_isr_event_handler_t
//hal_get_trx_end_event_handler(void)
//{
// return trx_end_callback;
//}
/*----------------------------------------------------------------------------*/
/** \brief This function is used to set new TRX_END event handler, overriding
* old handler reference.
*/
//void
//hal_set_trx_end_event_handler(hal_trx_end_isr_event_handler_t trx_end_callback_handle)
//{
// AVR_ENTER_CRITICAL_REGION();
// trx_end_callback = trx_end_callback_handle;
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/** \brief Remove event handler reference.
*/
//void
//hal_clear_trx_end_event_handler(void)
//{
// AVR_ENTER_CRITICAL_REGION();
// trx_end_callback = NULL;
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/** \brief This function returns the active RX_START event handler
*
* \return Current RX_START event handler registered.
*/
//hal_rx_start_isr_event_handler_t
//hal_get_rx_start_event_handler(void)
//{
// return rx_start_callback;
//}
/*----------------------------------------------------------------------------*/
/** \brief This function is used to set new RX_START event handler, overriding
* old handler reference.
*/
//void
//hal_set_rx_start_event_handler(hal_rx_start_isr_event_handler_t rx_start_callback_handle)
//{
// AVR_ENTER_CRITICAL_REGION();
// rx_start_callback = rx_start_callback_handle;
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/** \brief Remove event handler reference.
*/
//void
//hal_clear_rx_start_event_handler(void)
//{
// AVR_ENTER_CRITICAL_REGION();
// rx_start_callback = NULL;
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/** \brief This function returns the current value of the PLL_LOCK flag.
*
* The PLL_LOCK flag is incremented each time a PLL_LOCK event is signaled from the
* radio transceiver. This way it is possible for the end user to poll the flag
* for new event occurances.
*/
//uint8_t
//hal_get_pll_lock_flag(void)
//{
// return hal_pll_lock_flag;
//}
/*----------------------------------------------------------------------------*/
/** \brief This function clears the PLL_LOCK flag.
*/
//void
//hal_clear_pll_lock_flag(void)
//{
// AVR_ENTER_CRITICAL_REGION();
// hal_pll_lock_flag = 0;
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/** \brief This function reads data from one of the radio transceiver's registers.
*
* \param address Register address to read from. See datasheet for register
* map.
*
* \see Look at the at86rf230_registermap.h file for register address definitions.
*
* \returns The actual value of the read register.
*/
uint8_t
hal_register_read(uint8_t address)
{
/* Add the register read command to the register address. */
address &= HAL_TRX_CMD_RADDRM;
address |= HAL_TRX_CMD_RR;
uint8_t register_value = 0;
AVR_ENTER_CRITICAL_REGION();
HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */
/*Send Register address and read register content.*/
SPDR = address;
while ((SPSR & (1 << SPIF)) == 0) {;}
register_value = SPDR;
SPDR = register_value;
while ((SPSR & (1 << SPIF)) == 0) {;}
register_value = SPDR;
HAL_SS_HIGH(); /* End the transaction by pulling the Slave Select High. */
AVR_LEAVE_CRITICAL_REGION();
return register_value;
}
/*----------------------------------------------------------------------------*/
/** \brief This function writes a new value to one of the radio transceiver's
* registers.
*
* \see Look at the at86rf230_registermap.h file for register address definitions.
*
* \param address Address of register to write.
* \param value Value to write.
*/
void
hal_register_write(uint8_t address, uint8_t value)
{
/* Add the Register Write command to the address. */
address = HAL_TRX_CMD_RW | (HAL_TRX_CMD_RADDRM & address);
AVR_ENTER_CRITICAL_REGION();
HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */
/*Send Register address and write register content.*/
SPDR = address;
while ((SPSR & (1 << SPIF)) == 0) {;}
uint8_t dummy_read = SPDR;
SPDR = value;
while ((SPSR & (1 << SPIF)) == 0) {;}
dummy_read = SPDR;
HAL_SS_HIGH(); /* End the transaction by pulling the Slave Slect High. */
AVR_LEAVE_CRITICAL_REGION();
}
/*----------------------------------------------------------------------------*/
/** \brief This function reads the value of a specific subregister.
*
* \see Look at the at86rf230_registermap.h file for register and subregister
* definitions.
*
* \param address Main register's address.
* \param mask Bit mask of the subregister.
* \param position Bit position of the subregister
* \retval Value of the read subregister.
*/
uint8_t
hal_subregister_read(uint8_t address, uint8_t mask, uint8_t position)
{
/* Read current register value and mask out subregister. */
uint8_t register_value = hal_register_read(address);
register_value &= mask;
register_value >>= position; /* Align subregister value. */
return register_value;
}
/*----------------------------------------------------------------------------*/
/** \brief This function writes a new value to one of the radio transceiver's
* subregisters.
*
* \see Look at the at86rf230_registermap.h file for register and subregister
* definitions.
*
* \param address Main register's address.
* \param mask Bit mask of the subregister.
* \param position Bit position of the subregister
* \param value Value to write into the subregister.
*/
void
hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position,
uint8_t value)
{
/* Read current register value and mask area outside the subregister. */
uint8_t register_value = hal_register_read(address);
register_value &= ~mask;
/* Start preparing the new subregister value. shift in place and mask. */
value <<= position;
value &= mask;
value |= register_value; /* Set the new subregister value. */
/* Write the modified register value. */
hal_register_write(address, value);
}
/*----------------------------------------------------------------------------*/
/** \brief This function will upload a frame from the radio transceiver's frame
* buffer.
*
* If the frame currently available in the radio transceiver's frame buffer
* is out of the defined bounds. Then the frame length, lqi value and crc
* be set to zero. This is done to indicate an error.
* This version is optimized for use with contiki RF230BB driver
*
* \param rx_frame Pointer to the data structure where the frame is stored.
* \param rx_callback Pointer to callback function for receiving one byte at a time.
*/
void
hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback)
{
uint8_t *rx_data=0;
/* check that we have either valid frame pointer or callback pointer */
// if (!rx_frame && !rx_callback)
// return;
AVR_ENTER_CRITICAL_REGION();
HAL_SS_LOW();
/*Send frame read command.*/
SPDR = HAL_TRX_CMD_FR;
while ((SPSR & (1 << SPIF)) == 0) {;}
uint8_t frame_length = SPDR;
/*Read frame length.*/
SPDR = frame_length;
while ((SPSR & (1 << SPIF)) == 0) {;}
frame_length = SPDR;
/*Check for correct frame length.*/
if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)){
uint16_t crc = 0;
// if (rx_frame){
rx_data = (rx_frame->data);
rx_frame->length = frame_length;
// } else {
// rx_callback(frame_length);
// }
/*Upload frame buffer to data pointer. Calculate CRC.*/
SPDR = frame_length;
while ((SPSR & (1 << SPIF)) == 0) {;}
do{
uint8_t tempData = SPDR;
SPDR = 0; /* dummy write */
// if (rx_frame){
*rx_data++ = tempData;
// } else {
// rx_callback(tempData);
// }
crc = _crc_ccitt_update(crc, tempData);
while ((SPSR & (1 << SPIF)) == 0) {;}
} while (--frame_length > 0);
/*Read LQI value for this frame.*/
// if (rx_frame){
rx_frame->lqi = SPDR;
// } else {
// rx_callback(SPDR);
// }
HAL_SS_HIGH();
/*Check calculated crc, and set crc field in hal_rx_frame_t accordingly.*/
// if (rx_frame){
rx_frame->crc = (crc == HAL_CALCULATED_CRC_OK);
// } else {
// rx_callback(crc != HAL_CALCULATED_CRC_OK);
// }
} else {
HAL_SS_HIGH();
// if (rx_frame){
rx_frame->length = 0;
rx_frame->lqi = 0;
rx_frame->crc = false;
// }
}
AVR_LEAVE_CRITICAL_REGION();
}
/*----------------------------------------------------------------------------*/
/** \brief This function will download a frame to the radio transceiver's frame
* buffer.
*
* \param write_buffer Pointer to data that is to be written to frame buffer.
* \param length Length of data. The maximum length is 127 bytes.
*/
void
hal_frame_write(uint8_t *write_buffer, uint8_t length)
{
length &= HAL_TRX_CMD_RADDRM; /* Truncate length to maximum frame length. */
AVR_ENTER_CRITICAL_REGION();
HAL_SS_LOW(); /* Initiate the SPI transaction. */
/*SEND FRAME WRITE COMMAND AND FRAME LENGTH.*/
SPDR = HAL_TRX_CMD_FW;
while ((SPSR & (1 << SPIF)) == 0) {;}
uint8_t dummy_read = SPDR;
SPDR = length;
while ((SPSR & (1 << SPIF)) == 0) {;}
dummy_read = SPDR;
/* Download to the Frame Buffer. */
do{
SPDR = *write_buffer++;
--length;
while ((SPSR & (1 << SPIF)) == 0) {;}
dummy_read = SPDR;
} while (length > 0);
HAL_SS_HIGH(); /* Terminate SPI transaction. */
AVR_LEAVE_CRITICAL_REGION();
}
/*----------------------------------------------------------------------------*/
/** \brief Read SRAM
*
* This function reads from the SRAM of the radio transceiver.
*
* \param address Address in the TRX's SRAM where the read burst should start
* \param length Length of the read burst
* \param data Pointer to buffer where data is stored.
*/
//void
//hal_sram_read(uint8_t address, uint8_t length, uint8_t *data)
//{
// AVR_ENTER_CRITICAL_REGION();
// HAL_SS_LOW(); /* Initiate the SPI transaction. */
/*Send SRAM read command.*/
// SPDR = HAL_TRX_CMD_SR;
// while ((SPSR & (1 << SPIF)) == 0) {;}
// uint8_t dummy_read = SPDR;
/*Send address where to start reading.*/
// SPDR = address;
// while ((SPSR & (1 << SPIF)) == 0) {;}
// dummy_read = SPDR;
/*Upload the chosen memory area.*/
// do{
// SPDR = HAL_DUMMY_READ;
// while ((SPSR & (1 << SPIF)) == 0) {;}
// *data++ = SPDR;
// } while (--length > 0);
// HAL_SS_HIGH();
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/** \brief Write SRAM
*
* This function writes into the SRAM of the radio transceiver.
*
* \param address Address in the TRX's SRAM where the write burst should start
* \param length Length of the write burst
* \param data Pointer to an array of bytes that should be written
*/
//void
//hal_sram_write(uint8_t address, uint8_t length, uint8_t *data)
//{
// AVR_ENTER_CRITICAL_REGION();
// HAL_SS_LOW();
/*Send SRAM write command.*/
// SPDR = HAL_TRX_CMD_SW;
// while ((SPSR & (1 << SPIF)) == 0) {;}
// uint8_t dummy_read = SPDR;
/*Send address where to start writing to.*/
// SPDR = address;
// while ((SPSR & (1 << SPIF)) == 0) {;}
// dummy_read = SPDR;
/*Upload the chosen memory area.*/
// do{
// SPDR = *data++;
// while ((SPSR & (1 << SPIF)) == 0) {;}
// dummy_read = SPDR;
// } while (--length > 0);
// HAL_SS_HIGH();
// AVR_LEAVE_CRITICAL_REGION();
//}
/*----------------------------------------------------------------------------*/
/* This #if compile switch is used to provide a "standard" function body for the */
/* doxygen documentation. */
#if defined(DOXYGEN)
/** \brief ISR for the radio IRQ line, triggered by the input capture.
* This is the interrupt service routine for timer1.ICIE1 input capture.
* It is triggered of a rising edge on the radio transceivers IRQ line.
*/
void RADIO_VECT(void);
#else /* !DOXYGEN */
/* These link to the RF230BB driver in rf230.c */
void rf230_interrupt(void);
extern hal_rx_frame_t rxframe;
#define DEBUG 0
#if DEBUG
volatile int rf230_interrupt_flag=0;
#define INTERRUPTDEBUG(arg) rf230_interrupt_flag=arg
#else
#define INTERRUPTDEBUG(arg)
#endif
ISR(RADIO_VECT)
{
/*The following code reads the current system time. This is done by first
reading the hal_system_time and then adding the 16 LSB directly from the
TCNT1 register.
*/
uint32_t isr_timestamp = hal_system_time;
isr_timestamp <<= 16;
isr_timestamp |= TCNT1;
volatile uint8_t state;
INTERRUPTDEBUG(1);
/*Read Interrupt source.*/
HAL_SS_LOW();
/*Send Register address and read register content.*/
SPDR = RG_IRQ_STATUS | HAL_TRX_CMD_RR;
/* This is the second part of the convertion of system time to a 16 us time
base. The division is moved here so we can spend less time waiting for SPI
data.
*/
isr_timestamp /= HAL_US_PER_SYMBOL; /* Divide so that we get time in 16us resolution. */
isr_timestamp &= HAL_SYMBOL_MASK;
while ((SPSR & (1 << SPIF)) == 0) {;}
uint8_t interrupt_source = SPDR; /* The interrupt variable is used as a dummy read. */
SPDR = interrupt_source;
while ((SPSR & (1 << SPIF)) == 0) {;}
interrupt_source = SPDR; /* The interrupt source is read. */
HAL_SS_HIGH();
/*Handle the incomming interrupt. Prioritized.*/
if ((interrupt_source & HAL_RX_START_MASK)){
INTERRUPTDEBUG(10);
// if(rx_start_callback != NULL){
// /* Read Frame length and call rx_start callback. */
// HAL_SS_LOW();
// SPDR = HAL_TRX_CMD_FR;
// while ((SPSR & (1 << SPIF)) == 0) {;}
// uint8_t frame_length = SPDR;
// SPDR = frame_length; /* frame_length used for dummy data */
// while ((SPSR & (1 << SPIF)) == 0) {;}
// frame_length = SPDR;
// HAL_SS_HIGH();
// rx_start_callback(isr_timestamp, frame_length);
// }
} else if (interrupt_source & HAL_TRX_END_MASK){
INTERRUPTDEBUG(11);
// if(trx_end_callback != NULL){
// INTERRUPTDEBUG(12);
// trx_end_callback(isr_timestamp);
// }
state = hal_subregister_read(SR_TRX_STATUS);
if((state == BUSY_RX_AACK) || (state == RX_ON) || (state == BUSY_RX) || (state == RX_AACK_ON)){
/* Received packet interrupt */
/* Buffer the frame and call rf230_interrupt to schedule poll for rf230 receive process */
// if (rxframe.length) break; //toss packet if last one not processed yet
hal_frame_read(&rxframe, NULL);
rf230_interrupt();
// trx_end_callback(isr_timestamp);
/* Enable reception of next packet */
hal_subregister_write(SR_TRX_CMD, RX_AACK_ON);
}
} else if (interrupt_source & HAL_TRX_UR_MASK){
INTERRUPTDEBUG(13);
;
} else if (interrupt_source & HAL_PLL_UNLOCK_MASK){
INTERRUPTDEBUG(14);
;
} else if (interrupt_source & HAL_PLL_LOCK_MASK){
INTERRUPTDEBUG(15);
// hal_pll_lock_flag++;
;
} else if (interrupt_source & HAL_BAT_LOW_MASK){
/* Disable BAT_LOW interrupt to prevent endless interrupts. The interrupt */
/* will continously be asserted while the supply voltage is less than the */
/* user-defined voltage threshold. */
uint8_t trx_isr_mask = hal_register_read(RG_IRQ_MASK);
trx_isr_mask &= ~HAL_BAT_LOW_MASK;
hal_register_write(RG_IRQ_MASK, trx_isr_mask);
// hal_bat_low_flag++; /* Increment BAT_LOW flag. */
INTERRUPTDEBUG(16);
;
} else {
INTERRUPTDEBUG(99);
;
}
}
# endif /* defined(DOXYGEN) */
/*----------------------------------------------------------------------------*/
/* This #if compile switch is used to provide a "standard" function body for the */
/* doxygen documentation. */
#if defined(DOXYGEN)
/** \brief Timer Overflow ISR
* This is the interrupt service routine for timer1 overflow.
*/
void TIMER1_OVF_vect(void);
#else /* !DOXYGEN */
ISR(TIMER1_OVF_vect)
{
hal_system_time++;
}
#endif
/** @} */
/** @} */
/*EOF*/

View file

@ -0,0 +1,979 @@
/*
* 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.
*
*
* $Id: rf230bb.c,v 1.1 2009/07/08 16:17:07 dak664 Exp $
*/
/**
* \brief This module contains radio driver code for the Atmel
* AT86RF230. It is modified to use the contiki core MAC layer.
*
* \author Blake Leverett <bleverett@gmail.com>
* Mike Vidales <mavida404@gmail.com>
* Eric Gnoske <egnoske@gmail.com>
* David Kopf <dak664@embarqmail.com>
*
*/
/** \addtogroup wireless
* @{
*/
/**
* \defgroup radiorf230 RF230 interface
* @{
*/
/**
* \file
* This file contains "barebones" radio driver code for use with the
* contiki core MAC layer.
*
*/
#include <stdio.h>
#include <string.h>
#include "contiki.h"
//#if defined(__AVR__)
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
//#elif defined(__MSP430__)
//#include <io.h>
//#endif
#include "dev/leds.h"
#include "dev/spi.h"
#include "rf230bb.h"
#include "hal.h"
//#include "frame.h"
#include "radio.h"
#include "net/rime/packetbuf.h"
#include "net/rime/rimestats.h"
#include "sys/timetable.h"
#define WITH_SEND_CCA 0
#if RF230_CONF_TIMESTAMPS
#include "net/rime/timesynch.h"
#define TIMESTAMP_LEN 3
#else /* RF230_CONF_TIMESTAMPS */
#define TIMESTAMP_LEN 0
#endif /* RF230_CONF_TIMESTAMPS */
#define FOOTER_LEN 2
#ifndef RF230_CONF_CHECKSUM
#define RF230_CONF_CHECKSUM 0
#endif /* RF230_CONF_CHECKSUM */
#if RF230_CONF_CHECKSUM
#include "lib/crc16.h"
#define CHECKSUM_LEN 2
#else
#define CHECKSUM_LEN 0
#endif /* RF230_CONF_CHECKSUM */
#define AUX_LEN (CHECKSUM_LEN + TIMESTAMP_LEN + FOOTER_LEN)
struct timestamp {
uint16_t time;
uint8_t authority_level;
};
#define FOOTER1_CRC_OK 0x80
#define FOOTER1_CORRELATION 0x7f
#define DEBUG 0
#if DEBUG
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTF(...) do {} while (0)
#endif
/* XXX hack: these will be made as Chameleon packet attributes */
rtimer_clock_t rf230_time_of_arrival, rf230_time_of_departure;
int rf230_authority_level_of_sender;
#if RF230_CONF_TIMESTAMPS
static rtimer_clock_t setup_time_for_transmission;
static unsigned long total_time_for_transmission, total_transmission_len;
static int num_transmissions;
#endif /* RF230_CONF_TIMESTAMPS */
/* RF230 hardware delay times, from datasheet */
typedef enum{
TIME_TO_ENTER_P_ON = 510, /**< Transition time from VCC is applied to P_ON. */
TIME_P_ON_TO_TRX_OFF = 510, /**< Transition time from P_ON to TRX_OFF. */
TIME_SLEEP_TO_TRX_OFF = 880, /**< Transition time from SLEEP to TRX_OFF. */
TIME_RESET = 6, /**< Time to hold the RST pin low during reset */
TIME_ED_MEASUREMENT = 140, /**< Time it takes to do a ED measurement. */
TIME_CCA = 140, /**< Time it takes to do a CCA. */
TIME_PLL_LOCK = 150, /**< Maximum time it should take for the PLL to lock. */
TIME_FTN_TUNING = 25, /**< Maximum time it should take to do the filter tuning. */
TIME_NOCLK_TO_WAKE = 6, /**< Transition time from *_NOCLK to being awake. */
TIME_CMD_FORCE_TRX_OFF = 1, /**< Time it takes to execute the FORCE_TRX_OFF command. */
TIME_TRX_OFF_TO_PLL_ACTIVE = 180, /**< Transition time from TRX_OFF to: RX_ON, PLL_ON, TX_ARET_ON and RX_AACK_ON. */
TIME_STATE_TRANSITION_PLL_ACTIVE = 1, /**< Transition time from PLL active state to another. */
}radio_trx_timing_t;
/*---------------------------------------------------------------------------*/
PROCESS(rf230_process, "RF230 receiver");
/*---------------------------------------------------------------------------*/
int rf230_send(const void *data, unsigned short len);
int rf230_read(void *buf, unsigned short bufsize);
void rf230_set_receiver(void (* recv)(const struct radio_driver *d));
int rf230_on(void);
int rf230_off(void);
const struct radio_driver rf230_driver =
{
rf230_send,
rf230_read,
rf230_set_receiver,
rf230_on,
rf230_off,
};
static void (* receiver_callback)(const struct radio_driver *);
//signed char rf230_last_rssi;
//uint8_t rf230_last_correlation;
static uint8_t receive_on;
//static uint8_t rssi_val;
uint8_t rx_mode;
/* Radio stuff in network byte order. */
//static uint16_t pan_id;
//static int channel;
/*----------------------------------------------------------------------------*/
/** \brief This function return the Radio Transceivers current state.
*
* \retval P_ON When the external supply voltage (VDD) is
* first supplied to the transceiver IC, the
* system is in the P_ON (Poweron) mode.
* \retval BUSY_RX The radio transceiver is busy receiving a
* frame.
* \retval BUSY_TX The radio transceiver is busy transmitting a
* frame.
* \retval RX_ON The RX_ON mode enables the analog and digital
* receiver blocks and the PLL frequency
* synthesizer.
* \retval TRX_OFF In this mode, the SPI module and crystal
* oscillator are active.
* \retval PLL_ON Entering the PLL_ON mode from TRX_OFF will
* first enable the analog voltage regulator. The
* transceiver is ready to transmit a frame.
* \retval BUSY_RX_AACK The radio was in RX_AACK_ON mode and received
* the Start of Frame Delimiter (SFD). State
* transition to BUSY_RX_AACK is done if the SFD
* is valid.
* \retval BUSY_TX_ARET The radio transceiver is busy handling the
* auto retry mechanism.
* \retval RX_AACK_ON The auto acknowledge mode of the radio is
* enabled and it is waiting for an incomming
* frame.
* \retval TX_ARET_ON The auto retry mechanism is enabled and the
* radio transceiver is waiting for the user to
* send the TX_START command.
* \retval RX_ON_NOCLK The radio transceiver is listening for
* incomming frames, but the CLKM is disabled so
* that the controller could be sleeping.
* However, this is only true if the controller
* is run from the clock output of the radio.
* \retval RX_AACK_ON_NOCLK Same as the RX_ON_NOCLK state, but with the
* auto acknowledge module turned on.
* \retval BUSY_RX_AACK_NOCLK Same as BUSY_RX_AACK, but the controller
* could be sleeping since the CLKM pin is
* disabled.
* \retval STATE_TRANSITION The radio transceiver's state machine is in
* transition between two states.
*/
uint8_t
radio_get_trx_state(void)
{
return hal_subregister_read(SR_TRX_STATUS);
}
/*----------------------------------------------------------------------------*/
/** \brief This function checks if the radio transceiver is sleeping.
*
* \retval true The radio transceiver is in SLEEP or one of the *_NOCLK
* states.
* \retval false The radio transceiver is not sleeping.
*/
bool radio_is_sleeping(void)
{
bool sleeping = false;
/* The radio transceiver will be at SLEEP or one of the *_NOCLK states only if */
/* the SLP_TR pin is high. */
if (hal_get_slptr() != 0){
sleeping = true;
}
return sleeping;
}
/*----------------------------------------------------------------------------*/
/** \brief This function will reset the state machine (to TRX_OFF) from any of
* its states, except for the SLEEP state.
*/
void
radio_reset_state_machine(void)
{
hal_set_slptr_low();
delay_us(TIME_NOCLK_TO_WAKE);
hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF);
delay_us(TIME_CMD_FORCE_TRX_OFF);
}
/*----------------------------------------------------------------------------*/
/** \brief This function will change the current state of the radio
* transceiver's internal state machine.
*
* \param new_state Here is a list of possible states:
* - RX_ON Requested transition to RX_ON state.
* - TRX_OFF Requested transition to TRX_OFF state.
* - PLL_ON Requested transition to PLL_ON state.
* - RX_AACK_ON Requested transition to RX_AACK_ON state.
* - TX_ARET_ON Requested transition to TX_ARET_ON state.
*
* \retval RADIO_SUCCESS Requested state transition completed
* successfully.
* \retval RADIO_INVALID_ARGUMENT Supplied function parameter out of bounds.
* \retval RADIO_WRONG_STATE Illegal state to do transition from.
* \retval RADIO_BUSY_STATE The radio transceiver is busy.
* \retval RADIO_TIMED_OUT The state transition could not be completed
* within resonable time.
*/
radio_status_t
radio_set_trx_state(uint8_t new_state)
{
uint8_t original_state;
/*Check function paramter and current state of the radio transceiver.*/
if (!((new_state == TRX_OFF) ||
(new_state == RX_ON) ||
(new_state == PLL_ON) ||
(new_state == RX_AACK_ON) ||
(new_state == TX_ARET_ON))){
return RADIO_INVALID_ARGUMENT;
}
if (radio_is_sleeping() == true){
return RADIO_WRONG_STATE;
}
// Wait for radio to finish previous operation
for(;;)
{
original_state = radio_get_trx_state();
if (original_state != BUSY_TX_ARET &&
original_state != BUSY_RX_AACK &&
original_state != BUSY_RX &&
original_state != BUSY_TX)
break;
}
if (new_state == original_state){
return RADIO_SUCCESS;
}
/* At this point it is clear that the requested new_state is: */
/* TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON. */
/* The radio transceiver can be in one of the following states: */
/* TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON, TX_ARET_ON. */
if(new_state == TRX_OFF){
radio_reset_state_machine(); /* Go to TRX_OFF from any state. */
} else {
/* It is not allowed to go from RX_AACK_ON or TX_AACK_ON and directly to */
/* TX_AACK_ON or RX_AACK_ON respectively. Need to go via RX_ON or PLL_ON. */
if ((new_state == TX_ARET_ON) &&
(original_state == RX_AACK_ON)){
/* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */
/* The final state transition to TX_ARET_ON is handled after the if-else if. */
hal_subregister_write(SR_TRX_CMD, PLL_ON);
delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE);
} else if ((new_state == RX_AACK_ON) &&
(original_state == TX_ARET_ON)){
/* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */
/* The final state transition to RX_AACK_ON is handled after the if-else if. */
hal_subregister_write(SR_TRX_CMD, RX_ON);
delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE);
}
/* Any other state transition can be done directly. */
hal_subregister_write(SR_TRX_CMD, new_state);
/* When the PLL is active most states can be reached in 1us. However, from */
/* TRX_OFF the PLL needs time to activate. */
if (original_state == TRX_OFF){
delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE);
} else {
delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE);
}
} /* end: if(new_state == TRX_OFF) ... */
/*Verify state transition.*/
radio_status_t set_state_status = RADIO_TIMED_OUT;
if (radio_get_trx_state() == new_state){
set_state_status = RADIO_SUCCESS;
/* set rx_mode flag based on mode we're changing to */
if (new_state == RX_ON ||
new_state == RX_AACK_ON){
rx_mode = true;
} else {
rx_mode = false;
}
}
return set_state_status;
}
/*---------------------------------------------------------------------------*/
void
rf230_waitidle(void)
{
// PRINTF("rf230_waitidle");
uint8_t radio_state;
for(;;)
{
radio_state = hal_subregister_read(SR_TRX_STATUS);
if (radio_state != BUSY_TX_ARET &&
radio_state != BUSY_RX_AACK &&
radio_state != BUSY_RX &&
radio_state != BUSY_TX)
break;
PRINTF(".");
}
}
/*---------------------------------------------------------------------------*/
static uint8_t locked, lock_on, lock_off;
static void
on(void)
{
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
PRINTF("rf230 internal on\n");
receive_on = 1;
hal_set_slptr_low();
//radio_is_waking=1;//can test this before tx instead of delaying
delay_us(TIME_SLEEP_TO_TRX_OFF);
delay_us(TIME_SLEEP_TO_TRX_OFF);//extra delay for now
radio_set_trx_state(RX_AACK_ON);
// flushrx();
}
static void
off(void)
{
PRINTF("rf230 internal off\n");
receive_on = 0;
/* Wait for transmission to end before turning radio off. */
rf230_waitidle();
/* Force the device into TRX_OFF. */
radio_reset_state_machine();
/* Sleep Radio */
hal_set_slptr_high();
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
}
/*---------------------------------------------------------------------------*/
#define GET_LOCK() locked = 1
static void RELEASE_LOCK(void) {
if(lock_on) {
on();
lock_on = 0;
}
if(lock_off) {
off();
lock_off = 0;
}
locked = 0;
}
/*---------------------------------------------------------------------------*/
void
rf230_set_receiver(void (* recv)(const struct radio_driver *))
{
//PRINTF("rf230_set receiver\n");
receiver_callback = recv;
}
/*---------------------------------------------------------------------------*/
int
rf230_off(void)
{
// PRINTF("rf230_off\n");
/* Don't do anything if we are already turned off. */
if(receive_on == 0) {
return 1;
}
/* If we are called when the driver is locked, we indicate that the
radio should be turned off when the lock is unlocked. */
if(locked) {
lock_off = 1;
return 1;
}
off();
return 1;
}
/*---------------------------------------------------------------------------*/
int
rf230_on(void)
{
//PRINTF("rf230_on\n");
if(receive_on) {
return 1;
}
if(locked) {
lock_on = 1;
return 1;
}
on();
return 1;
}
/*---------------------------------------------------------------------------*/
int
rf230_get_channel(void)
{
return hal_subregister_read(SR_CHANNEL);
// return channel;
}
/*---------------------------------------------------------------------------*/
void
rf230_set_channel(int c)
{
/* Wait for any transmission to end. */
rf230_waitidle();
//channel=c;
hal_subregister_write(SR_CHANNEL, c);
}
/*---------------------------------------------------------------------------*/
void
rf230_set_pan_addr(uint16_t pan,uint16_t addr,uint8_t *ieee_addr)
{
PRINTF("rf230: PAN=%x Short Addr=%x\n",pan,addr);
uint8_t abyte;
abyte = pan & 0xFF;
hal_register_write(RG_PAN_ID_0,abyte);
abyte = (pan >> 8*1) & 0xFF;
hal_register_write(RG_PAN_ID_1, abyte);
abyte = addr & 0xFF;
hal_register_write(RG_SHORT_ADDR_0, abyte);
abyte = (addr >> 8*1) & 0xFF;
hal_register_write(RG_SHORT_ADDR_1, abyte);
if (ieee_addr != NULL) {
PRINTF("MAC=%x",*ieee_addr);
hal_register_write(RG_IEEE_ADDR_7, *ieee_addr++);
PRINTF(":%x",*ieee_addr);
hal_register_write(RG_IEEE_ADDR_6, *ieee_addr++);
PRINTF(":%x",*ieee_addr);
hal_register_write(RG_IEEE_ADDR_5, *ieee_addr++);
PRINTF(":%x",*ieee_addr);
hal_register_write(RG_IEEE_ADDR_4, *ieee_addr++);
PRINTF(":%x",*ieee_addr);
hal_register_write(RG_IEEE_ADDR_3, *ieee_addr++);
PRINTF(":%x",*ieee_addr);
hal_register_write(RG_IEEE_ADDR_2, *ieee_addr++);
PRINTF(":%x",*ieee_addr);
hal_register_write(RG_IEEE_ADDR_1, *ieee_addr++);
PRINTF(":%x",*ieee_addr);
hal_register_write(RG_IEEE_ADDR_0, *ieee_addr);
PRINTF("\n");
}
}
/*---------------------------------------------------------------------------*/
/* Process to handle input packets
* Receive interrupts cause this process to be polled
* It calls the core MAC layer which calls rf230_read to get the packet
*/
PROCESS_THREAD(rf230_process, ev, data)
{
PROCESS_BEGIN();
while(1) {
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
#if RF230_TIMETABLE_PROFILING
TIMETABLE_TIMESTAMP(rf230_timetable, "poll");
#endif /* RF230_TIMETABLE_PROFILING */
if(receiver_callback != NULL) {
receiver_callback(&rf230_driver);
#if RF230_TIMETABLE_PROFILING
TIMETABLE_TIMESTAMP(rf230_timetable, "end");
timetable_aggregate_compute_detailed(&aggregate_time,
&rf230_timetable);
timetable_clear(&rf230_timetable);
#endif /* RF230_TIMETABLE_PROFILING */
} else {
PRINTF("rf230_process not receiving function\n");
// flushrx();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/*
* This routine is called by the radio receive interrupt in hal.c
* It just sets the poll flag for the rf230 process.
*/
#if RF230_CONF_TIMESTAMPS
static volatile rtimer_clock_t interrupt_time;
static volatile int interrupt_time_set;
#endif /* RF230_CONF_TIMESTAMPS */
#if RF230_TIMETABLE_PROFILING
#define rf230_timetable_size 16
TIMETABLE(rf230_timetable);
TIMETABLE_AGGREGATE(aggregate_time, 10);
#endif /* RF230_TIMETABLE_PROFILING */
void
rf230_interrupt(void)
{
#if RF230_CONF_TIMESTAMPS
interrupt_time = timesynch_time();
interrupt_time_set = 1;
#endif /* RF230_CONF_TIMESTAMPS */
process_poll(&rf230_process);
#if RF230_TIMETABLE_PROFILING
timetable_clear(&rf230_timetable);
TIMETABLE_TIMESTAMP(rf230_timetable, "interrupt");
#endif /* RF230_TIMETABLE_PROFILING */
return;
}
/* The frame is buffered to rxframe in the interrupt routine in hal.c */
hal_rx_frame_t rxframe;
/*---------------------------------------------------------------------------*/
int
rf230_read(void *buf, unsigned short bufsize)
{
uint8_t *framep;
// uint8_t footer[2];
uint8_t len;
#if RF230_CONF_CHECKSUM
uint16_t checksum;
#endif /* RF230_CONF_CHECKSUM */
#if RF230_CONF_TIMESTAMPS
struct timestamp t;
#endif /* RF230_CONF_TIMESTAMPS */
PRINTF("rf230_read: %u bytes lqi %u crc %u\n",rxframe.length,rxframe.lqi,rxframe.crc);
#if DEBUG>1
for (len=0;len<rxframe.length;len++) PRINTF(" %x",rxframe.data[len]);PRINTF("\n");
#endif
if (rxframe.length==0) {
return 0;
}
#if RF230_CONF_TIMESTAMPS
bomb
if(interrupt_time_set) {
rf230_time_of_arrival = interrupt_time;
interrupt_time_set = 0;
} else {
rf230_time_of_arrival = 0;
}
rf230_time_of_departure = 0;
#endif /* RF230_CONF_TIMESTAMPS */
GET_LOCK();
// if(rxframe.length > RF230_MAX_PACKET_LEN) {
// // Oops, we must be out of sync.
// flushrx();
// RIMESTATS_ADD(badsynch);
// RELEASE_LOCK();
// return 0;
// }
//hal returns two extra bytes containing the checksum
//below works because auxlen is 2
len = rxframe.length;
if(len <= AUX_LEN) {
// flushrx();
RIMESTATS_ADD(tooshort);
RELEASE_LOCK();
return 0;
}
if(len - AUX_LEN > bufsize) {
// flushrx();
RIMESTATS_ADD(toolong);
RELEASE_LOCK();
return 0;
}
/* Transfer the frame, stripping the checksum */
framep=&(rxframe.data[0]);
memcpy(buf,framep,len-2);
/* Clear the length field to allow buffering of the next packet */
rxframe.length=0;
// framep+=len-AUX_LEN+2;
#if RF230_CONF_CHECKSUM
bomb
memcpy(&checksum,framep,CHECKSUM_LEN);
framep+=CHECKSUM_LEN;
#endif /* RF230_CONF_CHECKSUM */
#if RF230_CONF_TIMESTAMPS
bomb
memcpy(&t,framep,TIMESTAMP_LEN);
framep+=TIMESTAMP_LEN;
#endif /* RF230_CONF_TIMESTAMPS */
// memcpy(&footer,framep,FOOTER_LEN);
#if RF230_CONF_CHECKSUM
bomb
if(checksum != crc16_data(buf, len - AUX_LEN, 0)) {
PRINTF("rf230: checksum failed 0x%04x != 0x%04x\n",
checksum, crc16_data(buf, len - AUX_LEN, 0));
}
if(footer[1] & FOOTER1_CRC_OK &&
checksum == crc16_data(buf, len - AUX_LEN, 0)) {
#else
if (rxframe.crc) {
#endif /* RF230_CONF_CHECKSUM */
/*
packetbuf_copyfrom(parsed_frame->payload, parsed_frame->payload_length);
packetbuf_set_datalen(parsed_frame->payload_length);
memcpy(dest_reversed, (uint8_t *)parsed_frame->dest_addr, UIP_LLADDR_LEN);
memcpy(src_reversed, (uint8_t *)parsed_frame->src_addr, UIP_LLADDR_LEN);
//Change addresses to expected byte order
byte_reverse((uint8_t *)dest_reversed, UIP_LLADDR_LEN);
byte_reverse((uint8_t *)src_reversed, UIP_LLADDR_LEN);
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)dest_reversed);
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)src_reversed);
*/
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, hal_subregister_read( SR_RSSI ));
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rxframe.lqi);
RIMESTATS_ADD(llrx);
#if RF230_CONF_TIMESTAMPS
bomb
rf230_time_of_departure =
t.time +
setup_time_for_transmission +
(total_time_for_transmission * (len - 2)) / total_transmission_len;
rf230_authority_level_of_sender = t.authority_level;
packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, t.time);
#endif /* RF230_CONF_TIMESTAMPS */
} else {
PRINTF("rf230: Bad CRC\n");
RIMESTATS_ADD(badcrc);
len = AUX_LEN;
}
// if (?)
/* Another packet has been received and needs attention. */
// process_poll(&rf230_process);
// }
RELEASE_LOCK();
if(len < AUX_LEN) {
return 0;
}
return len - AUX_LEN;
}
/*---------------------------------------------------------------------------*/
void
rf230_set_txpower(uint8_t power)
{
if (power > TX_PWR_17_2DBM){
power=TX_PWR_17_2DBM;
}
if (radio_is_sleeping() ==true) {
PRINTF("rf230_set_txpower:Sleeping");
} else {
hal_subregister_write(SR_TX_PWR, power);
}
}
/*---------------------------------------------------------------------------*/
int
rf230_get_txpower(void)
{
if (radio_is_sleeping() ==true) {
PRINTF("rf230_get_txpower:Sleeping");
return 0;
} else {
return hal_subregister_read(SR_TX_PWR);
}
}
/*---------------------------------------------------------------------------*/
int
rf230_rssi(void)
{
int rssi;
int radio_was_off = 0;
/*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/
if(!receive_on) {
radio_was_off = 1;
rf230_on();
}
rssi = (int)((signed char)hal_subregister_read(SR_RSSI));
if(radio_was_off) {
rf230_off();
}
return rssi;
}
/*---------------------------------------------------------------------------*/
int
rf230_send(const void *payload, unsigned short payload_len)
{
// int i;
uint8_t total_len,buffer[RF230_MAX_TX_FRAME_LENGTH],*pbuf;
#if RF230_CONF_TIMESTAMPS
struct timestamp timestamp;
#endif /* RF230_CONF_TIMESTAMPS */
#if RF230_CONF_CHECKSUM
uint16_t checksum;
#endif /* RF230_CONF_CHECKSUM */
GET_LOCK();
if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
rf230_set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1);
} else {
rf230_set_txpower(TX_PWR_17_2DBM);
}
RIMESTATS_ADD(lltx);
#if RF230_CONF_CHECKSUM
checksum = crc16_data(payload, payload_len, 0);
#endif /* RF230_CONF_CHECKSUM */
total_len = payload_len + AUX_LEN;
/*Check function parameters and current state.*/
if (total_len > RF230_MAX_TX_FRAME_LENGTH){
return -1;
}
pbuf=&buffer[0];
memcpy(pbuf,payload,payload_len);
pbuf+=payload_len;
#if RF230_CONF_CHECKSUM
memcpy(pbuf,&checksum,CHECKSUM_LEN);
pbuf+=CHECKSUM_LEN;
#endif /* RF230_CONF_CHECKSUM */
#if RF230_CONF_TIMESTAMPS
timestamp.authority_level = timesynch_authority_level();
timestamp.time = timesynch_time();
memcpy(pbuf,&timestamp,TIMESTAMP_LEN);
pbuf+=TIMESTAMP_LEN;
#endif /* RF230_CONF_TIMESTAMPS */
/*Below comments were for cc240 radio, don't know how they apply to rf230 - DAK */
/* The TX FIFO can only hold one packet. Make sure to not overrun
* FIFO by waiting for transmission to start here and synchronizing
* with the RF230_TX_ACTIVE check in rf230_send.
*
* Note that we may have to wait up to 320 us (20 symbols) before
* transmission starts.
*/
//#ifdef TMOTE_SKY
//#define LOOP_20_SYMBOLS 400 /* 326us (msp430 @ 2.4576MHz) */
//#elif __AVR__
//#define LOOP_20_SYMBOLS 500 /* XXX */
//#endif
#define LOOP_20_SYMBOLS 500
/* Wait for any previous transmission to finish. */
rf230_waitidle();
hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF);
delay_us(TIME_P_ON_TO_TRX_OFF);
radio_set_trx_state(TX_ARET_ON); //enable auto ack
//#if WITH_SEND_CCA
// radio_set_trx_state(TX_ARET_ON); //enable auto ack
//#endif /* WITH_SEND_CCA */
/* Toggle the SLP_TR pin to initiate the frame transmission. */
PRINTF("rf230: sending %d bytes\n", payload_len);
hal_set_slptr_high();
hal_set_slptr_low();
hal_frame_write(buffer, total_len);
// for(i = LOOP_20_SYMBOLS; i > 0; i--) {//dak was working with this
if(1) {
#if RF230_CONF_TIMESTAMPS
rtimer_clock_t txtime = timesynch_time();
#endif /* RF230_CONF_TIMESTAMPS */
if(receive_on) {
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
}
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
/* We wait until transmission has ended so that we get an
accurate measurement of the transmission time.*/
rf230_waitidle();
radio_set_trx_state(RX_AACK_ON);//Re-enable receive mode
#if RF230_CONF_TIMESTAMPS
setup_time_for_transmission = txtime - timestamp.time;
if(num_transmissions < 10000) {
total_time_for_transmission += timesynch_time() - txtime;
total_transmission_len += total_len;
num_transmissions++;
}
#endif /* RF230_CONF_TIMESTAMPS */
#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS
ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,rf230_get_txpower());
#endif
ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
if(receive_on) {
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
}
RELEASE_LOCK();
return 0;
}
// }
/* If we are using WITH_SEND_CCA, we get here if the packet wasn't
transmitted because of other channel activity. */
RIMESTATS_ADD(contentiondrop);
PRINTF("rf230: do_send() transmission never started\n");
RELEASE_LOCK();
return -3; /* Transmission never started! */
}/*---------------------------------------------------------------------------*/
void
rf230_init(void)
{
/* Wait in case VCC just applied */
delay_us(TIME_TO_ENTER_P_ON);
/* Calibrate oscillator */
// calibrate_rc_osc_32k();
/* Initialize Hardware Abstraction Layer. */
hal_init();
/* Do full rf230 Reset */
hal_set_rst_low();
hal_set_slptr_low();
delay_us(TIME_RESET);
hal_set_rst_high();
/* Force transition to TRX_OFF. */
hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF);
delay_us(TIME_P_ON_TO_TRX_OFF);
/* Verify that it is a supported version */
uint8_t tvers = hal_register_read(RG_VERSION_NUM);
uint8_t tmanu = hal_register_read(RG_MAN_ID_0);
if ((tvers != RF230_REVA) && (tvers != RF230_REVB))
PRINTF("rf230: Unsupported version %u\n",tvers);
if (tmanu != SUPPORTED_MANUFACTURER_ID)
PRINTF("rf230: Unsupported manufacturer ID %u\n",tmanu);
PRINTF("rf230: Version %u, ID %u\n",tvers,tmanu);
hal_register_write(RG_IRQ_MASK, RF230_SUPPORTED_INTERRUPT_MASK);
/* Turn off address decoding. */
// reg = getreg(RF230_MDMCTRL0);
// reg &= ~ADR_DECODE;
// setreg(RF230_MDMCTRL0, reg);
/* Change default values as recomended in the data sheet, */
/* correlation threshold = 20, RX bandpass filter = 1.3uA. */
// setreg(RF230_MDMCTRL1, CORR_THR(20));
// reg = getreg(RF230_RXCTRL1);
// reg |= RXBPF_LOCUR;
// setreg(RF230_RXCTRL1, reg);
/* Set the FIFOP threshold to maximum. */
// setreg(RF230_IOCFG0, FIFOP_THR(127));
/* Turn off "Security enable" (page 32). */
// reg = getreg(RF230_SECCTRL0);
// reg &= ~RXFIFO_PROTECTION;
// setreg(RF230_SECCTRL0, reg);
// rf230_set_pan_addr(0xffff, 0x0000, NULL);
// rf230_set_channel(24);
/* Set up the radio for auto mode operation. */
hal_subregister_write(SR_MAX_FRAME_RETRIES, 2 );
hal_subregister_write(SR_TX_AUTO_CRC_ON, 1);
hal_subregister_write(SR_TRX_CMD, CMD_RX_AACK_ON);
/* Start the packet receive process */
process_start(&rf230_process, NULL);
}

View file

@ -0,0 +1,233 @@
/* Copyright (c) 2008, Swedish Institute of Computer Science
* All rights reserved.
*
* Additional fixes for AVR contributed by:
*
* Colin O'Flynn coflynn@newae.com
* Eric Gnoske egnoske@gmail.com
* Blake Leverett bleverett@gmail.com
* Mike Vidales mavida404@gmail.com
* Kevin Brown kbrown3@uccs.edu
* Nate Bohlmann nate@elfwerks.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/**
* \addtogroup radiorf230
* @{
*/
/**
* \file
* \brief This file contains radio driver code.
*
* $Id: rf230bb.h,v 1.1 2009/07/08 16:17:07 dak664 Exp $
*/
#ifndef RADIO_H
#define RADIO_H
/*============================ INCLUDE =======================================*/
#include <stdint.h>
#include <stdbool.h>
#include "at86rf230_registermap.h"
#include "hal.h"
/*============================ MACROS ========================================*/
#define SUPPORTED_PART_NUMBER ( 2 )
#define RF230_REVA ( 1 )
#define RF230_REVB ( 2 )
#define SUPPORTED_MANUFACTURER_ID ( 31 )
#define RF230_SUPPORTED_INTERRUPT_MASK ( 0x0C )
#define RF230_MIN_CHANNEL ( 11 )
#define RF230_MAX_CHANNEL ( 26 )
#define RF230_MIN_ED_THRESHOLD ( 0 )
#define RF230_MAX_ED_THRESHOLD ( 15 )
#define RF230_MAX_TX_FRAME_LENGTH ( 127 ) /**< 127 Byte PSDU. */
#define TX_PWR_3DBM ( 0 )
#define TX_PWR_17_2DBM ( 15 )
#define BATTERY_MONITOR_HIGHEST_VOLTAGE ( 15 )
#define BATTERY_MONITOR_VOLTAGE_UNDER_THRESHOLD ( 0 )
#define BATTERY_MONITOR_HIGH_VOLTAGE ( 1 )
#define BATTERY_MONITOR_LOW_VOLTAGE ( 0 )
#define FTN_CALIBRATION_DONE ( 0 )
#define PLL_DCU_CALIBRATION_DONE ( 0 )
#define PLL_CF_CALIBRATION_DONE ( 0 )
#define RC_OSC_REFERENCE_COUNT_MAX (1.005*F_CPU*31250UL/8000000UL)
#define RC_OSC_REFERENCE_COUNT_MIN (0.995*F_CPU*31250UL/8000000UL)
#ifndef RF_CHANNEL
#define RF_CHANNEL 26
#endif
/*============================ TYPEDEFS ======================================*/
/** \brief This macro defines the start value for the RADIO_* status constants.
*
* It was chosen to have this macro so that the user can define where
* the status returned from the TAT starts. This can be useful in a
* system where numerous drivers are used, and some range of status codes
* are occupied.
*
* \see radio_status_t
*/
#define RADIO_STATUS_START_VALUE ( 0x40 )
/** \brief This enumeration defines the possible return values for the TAT API
* functions.
*
* These values are defined so that they should not collide with the
* return/status codes defined in the IEEE 802.15.4 standard.
*
*/
typedef enum{
RADIO_SUCCESS = RADIO_STATUS_START_VALUE, /**< The requested service was performed successfully. */
RADIO_UNSUPPORTED_DEVICE, /**< The connected device is not an Atmel AT86RF230. */
RADIO_INVALID_ARGUMENT, /**< One or more of the supplied function arguments are invalid. */
RADIO_TIMED_OUT, /**< The requested service timed out. */
RADIO_WRONG_STATE, /**< The end-user tried to do an invalid state transition. */
RADIO_BUSY_STATE, /**< The radio transceiver is busy receiving or transmitting. */
RADIO_STATE_TRANSITION_FAILED, /**< The requested state transition could not be completed. */
RADIO_CCA_IDLE, /**< Channel is clear, available to transmit a new frame. */
RADIO_CCA_BUSY, /**< Channel busy. */
RADIO_TRX_BUSY, /**< Transceiver is busy receiving or transmitting data. */
RADIO_BAT_LOW, /**< Measured battery voltage is lower than voltage threshold. */
RADIO_BAT_OK, /**< Measured battery voltage is above the voltage threshold. */
RADIO_CRC_FAILED, /**< The CRC failed for the actual frame. */
RADIO_CHANNEL_ACCESS_FAILURE, /**< The channel access failed during the auto mode. */
RADIO_NO_ACK, /**< No acknowledge frame was received. */
}radio_status_t;
/**
* \name Transaction status codes
* \{
*/
#define TRAC_SUCCESS 0
#define TRAC_SUCCESS_DATA_PENDING 1
#define TRAC_SUCCESS_WAIT_FOR_ACK 2
#define TRAC_CHANNEL_ACCESS_FAILURE 3
#define TRAC_NO_ACK 5
#define TRAC_INVALID 7
/** \} */
/** \brief This enumeration defines the possible modes available for the
* Clear Channel Assessment algorithm.
*
* These constants are extracted from the datasheet.
*
*/
typedef enum{
CCA_ED = 0, /**< Use energy detection above threshold mode. */
CCA_CARRIER_SENSE = 1, /**< Use carrier sense mode. */
CCA_CARRIER_SENSE_WITH_ED = 2 /**< Use a combination of both energy detection and carrier sense. */
}radio_cca_mode_t;
/** \brief This enumeration defines the possible CLKM speeds.
*
* These constants are extracted from the RF230 datasheet.
*
*/
typedef enum{
CLKM_DISABLED = 0,
CLKM_1MHZ = 1,
CLKM_2MHZ = 2,
CLKM_4MHZ = 3,
CLKM_8MHZ = 4,
CLKM_16MHZ = 5
}radio_clkm_speed_t;
typedef void (*radio_rx_callback) (uint16_t data);
extern uint8_t rxMode;
/*============================ PROTOTYPES ====================================*/
const struct radio_driver rf230_driver;
void rf230_init(void);
int rf230_get_channel(void);
void rf230_set_channel(int c);
void rf230_set_pan_addr(uint16_t pan,uint16_t addr,uint8_t *ieee_addr);
void rf230_set_txpower(uint8_t power);
int rf230_get_txpower(void);
//radio_status_t radio_init(bool cal_rc_osc,
// hal_rx_start_isr_event_handler_t rx_event,
// hal_trx_end_isr_event_handler_t trx_end_event,
// radio_rx_callback rx_callback);
//uint8_t radio_get_saved_rssi_value(void);
//uint8_t radio_get_operating_channel( void );
//radio_status_t radio_set_operating_channel( uint8_t channel );
//uint8_t radio_get_tx_power_level( void );
//radio_status_t radio_set_tx_power_level( uint8_t power_level );
//uint8_t radio_get_cca_mode( void );
//uint8_t radio_get_ed_threshold( void );
//radio_status_t radio_set_cca_mode( uint8_t mode, uint8_t ed_threshold );
//radio_status_t radio_do_cca( void );
//radio_status_t radio_get_rssi_value( uint8_t *rssi );
//uint8_t radio_batmon_get_voltage_threshold( void );
//uint8_t radio_batmon_get_voltage_range( void );
//radio_status_t radio_batmon_configure( bool range, uint8_t voltage_threshold );
//radio_status_t radio_batmon_get_status( void );
//uint8_t radio_get_clock_speed( void );
//radio_status_t radio_set_clock_speed( bool direct, uint8_t clock_speed );
//radio_status_t radio_calibrate_filter( void );
//radio_status_t radio_calibrate_pll( void );
//uint8_t radio_get_trx_state( void );
//radio_status_t radio_set_trx_state( uint8_t new_state );
//radio_status_t radio_enter_sleep_mode( void );
//radio_status_t radio_leave_sleep_mode( void );
//void radio_reset_state_machine( void );
//void radio_reset_trx( void );
//void radio_use_auto_tx_crc( bool auto_crc_on );
//radio_status_t radio_send_data( uint8_t data_length, uint8_t *data );
//uint8_t radio_get_device_role( void );
//void radio_set_device_role( bool i_am_coordinator );
//uint16_t radio_get_pan_id( void );
//void radio_set_pan_id( uint16_t new_pan_id );
//uint16_t radio_get_short_address( void );
//void radio_set_short_address( uint16_t new_short_address );
//void radio_get_extended_address( uint8_t *extended_address );
//void radio_set_extended_address( uint8_t *extended_address );
//radio_status_t radio_configure_csma( uint8_t seed0, uint8_t be_csma_seed1 );
//bool calibrate_rc_osc_clkm(void);
//void calibrate_rc_osc_32k(void);
//uint8_t * radio_frame_data(void);
//uint8_t radio_frame_length(void);
#define delay_us( us ) ( _delay_loop_2( ( F_CPU / 4000000UL ) * ( us ) ) )
#endif
/** @} */
/*EOF*/