*** empty log message ***
This commit is contained in:
parent
49989dbe45
commit
1de298c72a
6
cpu/avr/radio/rf230bb/Makefile.rf230bb
Normal file
6
cpu/avr/radio/rf230bb/Makefile.rf230bb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
CONTIKI_TARGET_SOURCEFILES += rf230bb.c halbb.c
|
||||||
|
# timer.c
|
||||||
|
|
||||||
|
APPDIRS += $(CONTIKI)/cpu/avr/radio/rf230bb
|
||||||
|
|
351
cpu/avr/radio/rf230bb/at86rf230_registermap.h
Normal file
351
cpu/avr/radio/rf230bb/at86rf230_registermap.h
Normal 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
374
cpu/avr/radio/rf230bb/hal.h
Normal 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*/
|
770
cpu/avr/radio/rf230bb/halbb.c
Normal file
770
cpu/avr/radio/rf230bb/halbb.c
Normal 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*/
|
979
cpu/avr/radio/rf230bb/rf230bb.c
Normal file
979
cpu/avr/radio/rf230bb/rf230bb.c
Normal 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,×tamp,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);
|
||||||
|
}
|
233
cpu/avr/radio/rf230bb/rf230bb.h
Normal file
233
cpu/avr/radio/rf230bb/rf230bb.h
Normal 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*/
|
Loading…
Reference in a new issue