mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-09-09 23:54:32 +00:00
Radio and 802.15.4 MAC code for the Atmel AVR Raven board
This commit is contained in:
parent
2e8264010b
commit
db7d9bb131
5
cpu/avr/radio/ieee-manager/Makefile.ieee-manager
Normal file
5
cpu/avr/radio/ieee-manager/Makefile.ieee-manager
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
CONTIKI_TARGET_SOURCEFILES += ieee-15-4-manager.c
|
||||
|
||||
APPDIRS += $(CONTIKI)/cpu/avr/radio/ieee-manager
|
||||
|
237
cpu/avr/radio/ieee-manager/ieee-15-4-manager.c
Normal file
237
cpu/avr/radio/ieee-manager/ieee-15-4-manager.c
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* $Id: ieee-15-4-manager.c,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* \addtogroup rf230mac
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief Interfaces the 802.15.4 MAC to upper network layers.
|
||||
*
|
||||
* \author
|
||||
* Mike Vidales <mavida404@gmail.com>
|
||||
*/
|
||||
|
||||
#include "mac.h"
|
||||
#include "radio.h"
|
||||
#include "ieee-15-4-manager.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
wake(void)
|
||||
{
|
||||
/* Wake the radio. */
|
||||
return radio_leave_sleep_mode();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
sleep(void)
|
||||
{
|
||||
/* Sleep the radio. */
|
||||
return radio_enter_sleep_mode();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_channel(int channel)
|
||||
{
|
||||
/* Set the channel. */
|
||||
phyCurrentChannel = channel;
|
||||
radio_set_operating_channel(phyCurrentChannel);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
get_channel(void)
|
||||
{
|
||||
/* Reads the current channel. */
|
||||
phyCurrentChannel = radio_get_operating_channel();
|
||||
return phyCurrentChannel;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_dst_panid(int panid)
|
||||
{
|
||||
macDstPANId = panid;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
get_dst_panid(void)
|
||||
{
|
||||
return macDstPANId;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_src_panid(int panid)
|
||||
{
|
||||
/* Writes the PAN_ID to the radio. */
|
||||
macSrcPANId = panid;
|
||||
radio_set_pan_id(macSrcPANId);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
get_src_panid(void)
|
||||
{
|
||||
/* Gets the PAN_ID from the radio. */
|
||||
macSrcPANId = radio_get_pan_id();
|
||||
return macSrcPANId;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_auto_mode(bool mode)
|
||||
{
|
||||
autoModes = mode;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
get_auto_mode(void)
|
||||
{
|
||||
return autoModes;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_long_addr(uint64_t address)
|
||||
{
|
||||
/* Set the Long address in the radio. */
|
||||
macLongAddr = address;
|
||||
radio_set_extended_address((uint8_t *)&macLongAddr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint64_t
|
||||
get_long_addr(void)
|
||||
{
|
||||
/* Get the Long address from the radio. */
|
||||
radio_get_extended_address((uint8_t *)&macLongAddr);
|
||||
return macLongAddr;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_short_addr(int address)
|
||||
{
|
||||
/* Set the Short address in the radio. */
|
||||
macShortAddress = address;
|
||||
radio_set_short_address(macShortAddress);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
get_short_addr(void)
|
||||
{
|
||||
/* Get the Short address from the radio. */
|
||||
macShortAddress = radio_get_short_address();
|
||||
return macShortAddress;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_iamcoord_bit(bool iamcoord)
|
||||
{
|
||||
/** Set the iAmCoord bit. */
|
||||
iAmCoord = iamcoord;
|
||||
radio_set_device_role(iAmCoord);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
get_iamcoord_bit(void)
|
||||
{
|
||||
/** Get the iAmCoord bit. */
|
||||
iAmCoord = radio_get_device_role();
|
||||
return iAmCoord;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_coord_long_addr(uint64_t address)
|
||||
{
|
||||
macCoordExtendedAddress = address;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint64_t
|
||||
get_coord_long_addr(void)
|
||||
{
|
||||
return macCoordExtendedAddress;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_coord_short_addr(int address)
|
||||
{
|
||||
macCoordShortAddress = address;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
get_coord_short_addr(void)
|
||||
{
|
||||
return macCoordShortAddress;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_dest_long_addr(uint64_t address)
|
||||
{
|
||||
macDestAddress = address;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint64_t
|
||||
get_dest_long_addr(void)
|
||||
{
|
||||
return macDestAddress;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief initializes the 802.15.4 manager layer.
|
||||
* \param pieee_15_4_manager Pointer to \ref ieee_15_4_manager
|
||||
*/
|
||||
void ieee_15_4_init(ieee_15_4_manager_t *pieee_15_4_manager)
|
||||
{
|
||||
/* Initialize the IEEE 15.4 manager. */
|
||||
pieee_15_4_manager->wake = wake;
|
||||
pieee_15_4_manager->sleep = sleep;
|
||||
pieee_15_4_manager->set_channel = set_channel;
|
||||
pieee_15_4_manager->get_channel = get_channel;
|
||||
pieee_15_4_manager->set_dst_panid = set_dst_panid;
|
||||
pieee_15_4_manager->get_dst_panid = get_dst_panid;
|
||||
pieee_15_4_manager->set_src_panid = set_src_panid;
|
||||
pieee_15_4_manager->get_src_panid = get_src_panid;
|
||||
pieee_15_4_manager->set_auto_mode = set_auto_mode;
|
||||
pieee_15_4_manager->get_auto_mode = get_auto_mode;
|
||||
pieee_15_4_manager->set_long_addr = set_long_addr;
|
||||
pieee_15_4_manager->get_long_addr = get_long_addr;
|
||||
pieee_15_4_manager->set_short_addr = set_short_addr;
|
||||
pieee_15_4_manager->get_short_addr = get_short_addr;
|
||||
pieee_15_4_manager->set_iamcoord_bit = set_iamcoord_bit;
|
||||
pieee_15_4_manager->get_iamcoord_bit = get_iamcoord_bit;
|
||||
pieee_15_4_manager->set_coord_long_addr = set_coord_long_addr;
|
||||
pieee_15_4_manager->get_coord_long_addr = get_coord_long_addr;
|
||||
pieee_15_4_manager->set_coord_short_addr = set_coord_short_addr;
|
||||
pieee_15_4_manager->get_coord_short_addr = get_coord_short_addr;
|
||||
pieee_15_4_manager->set_dest_long_addr = set_dest_long_addr;
|
||||
pieee_15_4_manager->get_dest_long_addr = get_dest_long_addr;
|
||||
}
|
||||
|
||||
/** \} */
|
115
cpu/avr/radio/ieee-manager/ieee-15-4-manager.h
Normal file
115
cpu/avr/radio/ieee-manager/ieee-15-4-manager.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* $Id: ieee-15-4-manager.h,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*/
|
||||
/**
|
||||
* \addtogroup rf230mac
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief Example glue code between the existing MAC code and the
|
||||
* Contiki mac interface
|
||||
*
|
||||
* \author
|
||||
* Mike Vidales <mavida404@gmail.com>
|
||||
*
|
||||
* \ingroup ieee_15_4
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __IEEEMANAGER_H__
|
||||
#define __IEEEMANAGER_H__
|
||||
|
||||
/** \brief The interface structure for the 802.15.4 quasi-MAC. */
|
||||
typedef struct ieee_15_4_manager{
|
||||
/** Turn the MAC layer on. */
|
||||
int (* wake)(void);
|
||||
/** Turn the MAC layer off. */
|
||||
int (* sleep)(void);
|
||||
|
||||
/** Set the operating channel. */
|
||||
void (* set_channel)(int channel);
|
||||
/** Get the operating channel. */
|
||||
int (* get_channel)(void);
|
||||
|
||||
/** Set the Destination PAN_ID. */
|
||||
void (* set_dst_panid)(int panid);
|
||||
/** Get the Destination PAN_ID. */
|
||||
int (* get_dst_panid)(void);
|
||||
|
||||
/** Set the Source PAN_ID. */
|
||||
void (* set_src_panid)(int panid);
|
||||
/** Get the Source PAN_ID. */
|
||||
int (* get_src_panid)(void);
|
||||
|
||||
/** Set the Automatic TRX modes. */
|
||||
void (* set_auto_mode)(bool mode);
|
||||
/** Get the current state of Automatic TRX modes. */
|
||||
bool (* get_auto_mode)(void);
|
||||
|
||||
/** Set the Long Address. */
|
||||
void (* set_long_addr)(uint64_t address);
|
||||
/** Get the Long Address. */
|
||||
uint64_t (* get_long_addr)(void);
|
||||
|
||||
/** Set the Short Address. */
|
||||
void (* set_short_addr)(int address);
|
||||
/** Get the short Address. */
|
||||
int (* get_short_addr)(void);
|
||||
|
||||
/** Set the iAmCoord bit. */
|
||||
void (* set_iamcoord_bit)(bool iamcoord);
|
||||
/** Get the iAmCoord bit. */
|
||||
bool (* get_iamcoord_bit)(void);
|
||||
|
||||
/** Set the Coordinator Long address. */
|
||||
void (* set_coord_long_addr)(uint64_t address);
|
||||
/** Get the Coordinator Long address. */
|
||||
uint64_t (* get_coord_long_addr)(void);
|
||||
|
||||
/** Set the Coordinator Long address. */
|
||||
void (* set_coord_short_addr)(int address);
|
||||
/** Get the Coordinator Long address. */
|
||||
int (* get_coord_short_addr)(void);
|
||||
|
||||
/** Set the Destination address. */
|
||||
void (* set_dest_long_addr)(uint64_t address);
|
||||
/** Get the Destination address. */
|
||||
uint64_t (* get_dest_long_addr)(void);
|
||||
} ieee_15_4_manager_t;
|
||||
|
||||
|
||||
void ieee_15_4_init(struct ieee_15_4_manager *pieee_15_4_manager);
|
||||
|
||||
#endif /* __IEEEMANAGER_H__ */
|
||||
/** \} */
|
4
cpu/avr/radio/mac/Makefile.mac
Normal file
4
cpu/avr/radio/mac/Makefile.mac
Normal file
@ -0,0 +1,4 @@
|
||||
CONTIKI_TARGET_SOURCEFILES += mac.c sicslowmac.c
|
||||
|
||||
APPDIRS += $(CONTIKI)/cpu/avr/radio/mac
|
||||
|
193
cpu/avr/radio/mac/mac.c
Normal file
193
cpu/avr/radio/mac/mac.c
Normal file
@ -0,0 +1,193 @@
|
||||
/* 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 wireless
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \defgroup rf230mac RF230 MAC
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* \brief The IEEE 802.15.4 (2003/2006) MAC utility functions.
|
||||
*
|
||||
* $Id: mac.c,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \author
|
||||
* Eric Gnoske <egnoske@gmail.com>
|
||||
* Blake Leverett <bleverett@gmail.com>
|
||||
* Mike Vidales <mavida404@gmail.com>
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mac.h"
|
||||
#include "radio.h"
|
||||
#include "hal.h"
|
||||
#include "tcpip.h"
|
||||
#include "uip.h"
|
||||
#include "sicslowpan.h"
|
||||
#include "sicslowmac.h"
|
||||
|
||||
/* Globals */
|
||||
/** \brief Interface structure for this module */
|
||||
ieee_15_4_manager_t ieee15_4ManagerAddress;
|
||||
|
||||
//dataRequest_t dataRequestStructAddress;
|
||||
|
||||
/* Macros & Defines */
|
||||
|
||||
uint8_t msduHandle;
|
||||
bool iAmCoord;
|
||||
bool autoModes;
|
||||
|
||||
|
||||
/** \brief The RF channel to use for all following transmissions and
|
||||
* receptions (see 6.1.2). Allowable values are 0-26
|
||||
*/
|
||||
uint8_t phyCurrentChannel;
|
||||
|
||||
/** \brief The 64-bit address of the coordinator/router through which
|
||||
* the network layer wishes to communicate.
|
||||
*/
|
||||
uint64_t macCoordExtendedAddress;
|
||||
|
||||
/** \brief The 16-bit short address assigned to the coordinator
|
||||
* through which the network layer wishes to communicate. A value
|
||||
* of 0xfffe indicates th the coordinator is only using it's 64-bit
|
||||
* extended address. A value of 0xffff indicates that this value is
|
||||
* unknown. The default value is 0xfff.
|
||||
*/
|
||||
uint16_t macCoordShortAddress;
|
||||
|
||||
/** \brief This address is the 64-bit address that will be used as
|
||||
* the mechanism to provide a destination to the upper layers. The
|
||||
* default value is 0xfff.
|
||||
*/
|
||||
uint64_t macDestAddress;
|
||||
|
||||
/** \brief The sequence number (0x00 - 0xff) added to the transmitted
|
||||
* data or MAC command frame. The default is a random value within
|
||||
* the range.
|
||||
*/
|
||||
uint8_t macDSN;
|
||||
|
||||
/** \brief The 16-bit identifier of the PAN on which the device is
|
||||
* sending to. If this value is 0xffff, the device is not
|
||||
* associated. The default value is 0xffff.
|
||||
*/
|
||||
uint16_t macDstPANId;
|
||||
|
||||
/** \brief The 16-bit identifier of the PAN on which the device is
|
||||
* operating. If this value is 0xffff, the device is not
|
||||
* associated. The default value is 0xffff.
|
||||
*/
|
||||
uint16_t macSrcPANId;
|
||||
|
||||
/** \brief The 16-bit address that the device uses to communicate in
|
||||
* the PAN. If the device is the PAN coordinator, this value shall
|
||||
* be chosen before a PAN is started. Otherwise, the address is
|
||||
* allocated by a coordinator during association. A value of 0xfffe
|
||||
* indicates that the device has associated but has not been
|
||||
* allocated an address. A value of 0xffff indicates that the
|
||||
* device does not have a short address. The default value is
|
||||
* 0xffff.
|
||||
*/
|
||||
uint16_t macShortAddress;
|
||||
|
||||
|
||||
/** \brief Our own long address. This needs to be read from EEPROM or
|
||||
* other secure memory storage.
|
||||
*/
|
||||
uint64_t macLongAddr;
|
||||
|
||||
/* Implementation */
|
||||
|
||||
/** \brief Initializes the (quasi) 802.15.4 MAC. This function should
|
||||
* be called only once on startup.
|
||||
*/
|
||||
void
|
||||
mac_init(void)
|
||||
{
|
||||
volatile uint8_t buf[8];
|
||||
|
||||
sicslowmac_resetRequest(true);
|
||||
|
||||
/* Set up the radio for auto mode operation. */
|
||||
hal_subregister_write( SR_MAX_FRAME_RETRIES, 2 );
|
||||
|
||||
/* Need to laod PANID for auto modes */
|
||||
radio_set_pan_id(DEST_PAN_ID);
|
||||
|
||||
/* Buffer the uint64_t address for easy loading and debug. */
|
||||
/** \todo Find a better location to load the IEEE address. */
|
||||
buf[0] = macLongAddr & 0xFF;
|
||||
buf[1] = (macLongAddr >> 8) & 0xFF;
|
||||
buf[2] = (macLongAddr >> 16) & 0xFF;
|
||||
buf[3] = (macLongAddr >> 24) & 0xFF;
|
||||
buf[4] = (macLongAddr >> 32) & 0xFF;
|
||||
buf[5] = (macLongAddr >> 40) & 0xFF;
|
||||
buf[6] = (macLongAddr >> 48) & 0xFF;
|
||||
buf[7] = (macLongAddr >> 56) & 0xFF;
|
||||
/* Load the long address into the radio. This is required for auto mode */
|
||||
/* operation. */
|
||||
radio_set_extended_address((uint8_t *)&macLongAddr);
|
||||
|
||||
srand(1234 );
|
||||
msduHandle = rand();
|
||||
|
||||
/* Ping6 debug */
|
||||
memcpy(uip_lladdr.addr, &macLongAddr, 8);
|
||||
|
||||
/* Convert expected byte order */
|
||||
byte_reverse((uint8_t *)uip_lladdr.addr, 8);
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
241
cpu/avr/radio/mac/mac.h
Normal file
241
cpu/avr/radio/mac/mac.h
Normal file
@ -0,0 +1,241 @@
|
||||
/* 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.
|
||||
*/
|
||||
/**
|
||||
* \brief The equivalent IEEE 802.15.4 (2003/2006) header file for
|
||||
* the mac primitives.
|
||||
*
|
||||
* $Id: mac.h,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \addtogroup rf230mac
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* \brief The IEEE 802.15.4 (2003/2006) MAC utility functions.
|
||||
*/
|
||||
|
||||
#ifndef MAC_H
|
||||
#define MAC_H
|
||||
|
||||
/* Includes */
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "frame.h"
|
||||
#include "ieee-15-4-manager.h"
|
||||
|
||||
#define EEPROMMACADDRESS ((void*)0)
|
||||
#define EEPROMDSTADDRESS ((void*)8)
|
||||
#define EEPROMCHANADDRESS ((void*)16)
|
||||
#define EEPROMPANIDADDRESS ((void*)17)
|
||||
#define EEPROMROLEADDRESS ((void*)19)
|
||||
#define SUCCESS (0)
|
||||
#define CHANNEL_PAGE_0 (0)
|
||||
|
||||
|
||||
|
||||
|
||||
/* MAC command frames codes */
|
||||
|
||||
/* MAC enumerations */
|
||||
/** \brief Pre-defined data frame control field (FCF) values.
|
||||
* \name FCF Values
|
||||
* @{
|
||||
*/
|
||||
#define FCF_NO_ACK (0x8841)
|
||||
#define FCF_ACK_REQ (0x8861)
|
||||
/** @} */
|
||||
|
||||
/** \brief Hardcoded various "network" addresses, for use when testing.
|
||||
* \name Pre-defined network addresses
|
||||
* @{
|
||||
*/
|
||||
#define DEST_PAN_ID (0xABCD)
|
||||
#define SOURCE_PAN_ID (0xABCD)
|
||||
#define LONG_ADDR_1 (0xFFEEDDCCBBAA1100LL)
|
||||
#define LONG_ADDR_2 (0x1122334455667788LL)
|
||||
#define LONG_ADDR_3 (0xDDEEAADDBBEEEEFFLL)
|
||||
#define LONG_ADDR_4 (0x0123456789ABCDEFLL)
|
||||
#define SOURCE_ADDR (0x1234)
|
||||
#define FCF_ACK (0x0002)
|
||||
#define TX_OPTION_NOACK (0)
|
||||
#define TX_OPTION_ACK (1)
|
||||
#define LONG_ADDR_LEN (8)
|
||||
/** @} */
|
||||
|
||||
#define MPDU_OVERHEAD (11) /**< This overhead includes FCF, DSN, DEST_PAN_ID, DEST_ADDR, SOURCE_ADDR, & FCS */
|
||||
|
||||
|
||||
/** \brief These are some definitions of values used in the FCF. See the 802.15.4 spec for details.
|
||||
* \name FCF element values definitions
|
||||
* @{
|
||||
*/
|
||||
#define BEACONFRAME (0x00)
|
||||
#define DATAFRAME (0x01)
|
||||
#define ACKFRAME (0x02)
|
||||
#define CMDFRAME (0x03)
|
||||
|
||||
#define BEACONREQ (0x07)
|
||||
|
||||
#define IEEERESERVED (0x00)
|
||||
#define NOADDR (0x00) /**< Only valid for ACK or Beacon frames. */
|
||||
#define SHORTADDRMODE (0x02)
|
||||
#define LONGADDRMODE (0x03)
|
||||
|
||||
#define NOBEACONS (0x0F)
|
||||
|
||||
#define BROADCASTADDR (0xFFFF)
|
||||
#define BROADCASTPANDID (0xFFFF)
|
||||
|
||||
#define IEEE802154_2003 (0x00)
|
||||
#define IEEE802154_2006 (0x01)
|
||||
|
||||
#define SECURITY_LEVEL_NONE (0)
|
||||
#define SECURITY_LEVEL_128 (3)
|
||||
|
||||
#define PSDULEN (127)
|
||||
/** @} */
|
||||
|
||||
|
||||
/* typedef enum {TRUE, FALSE} bool; */
|
||||
|
||||
typedef struct dataRequest {
|
||||
uint8_t srcAddrMode;
|
||||
uint8_t dstAddrMode;
|
||||
uint16_t dstPANId;
|
||||
addr_t dstAddr;
|
||||
uint8_t msduLength;
|
||||
uint8_t *msdu;
|
||||
uint8_t msduHandle;
|
||||
uint8_t txOptions;
|
||||
uint8_t securityLevel;
|
||||
uint8_t keyIdMode;
|
||||
uint8_t *keySource;
|
||||
uint8_t keyIndex;
|
||||
} dataRequest_t;
|
||||
|
||||
|
||||
/* Macros & Defines */
|
||||
extern ieee_15_4_manager_t ieee15_4ManagerAddress;
|
||||
extern dataRequest_t dataRequestStructAddress;
|
||||
#define ieee15_4Struct (&ieee15_4ManagerAddress)
|
||||
#define dataRequestStruct (&dataRequestStructAddress)
|
||||
|
||||
|
||||
/**
|
||||
* \name Scan variables
|
||||
* \brief Global variables and defines for scan.
|
||||
* \{
|
||||
*/
|
||||
extern uint8_t msduHandle;
|
||||
extern bool iAmCoord;
|
||||
extern bool autoModes;
|
||||
extern uint16_t macShortAddr;
|
||||
extern uint64_t macLongAddr;
|
||||
/** @} */
|
||||
|
||||
/* PHY PIB Attributes */
|
||||
|
||||
/* uint8_t phyCurrentChannel Integer 0-26
|
||||
* The RF channel to use for all following transmissions and receptions (see6.1.2).
|
||||
*/
|
||||
extern uint8_t phyCurrentChannel;
|
||||
|
||||
/* uint64_t macCoordExtendedAddress -- no default
|
||||
*
|
||||
* The 64-bit address of the coordinator/router through which the network layer wishes to communicate
|
||||
*/
|
||||
extern uint64_t macCoordExtendedAddress;
|
||||
|
||||
/* uint16_t macCoordShortAddress -- default 0xffff
|
||||
*
|
||||
* The 16-bit short address assigned to the coordinator through which the network layer wishes
|
||||
* to communicate. A value of 0xfffe indicates th the coordinator is only using it's 64-bit
|
||||
* extended address. A value of 0xffff indicates that this value is unknown.
|
||||
*/
|
||||
extern uint16_t macCoordShortAddress;
|
||||
|
||||
/* uint64_t macDestAddress -- default 0xffff
|
||||
*
|
||||
* This address is the 64-bit address that will be used as the mechanism to
|
||||
* provide a destination to the upper layers.
|
||||
*/
|
||||
extern uint64_t macDestAddress;
|
||||
|
||||
/* uint8_t macDSN -- default is random value within the range
|
||||
*
|
||||
* The sequence number (0x00 - 0xff) added to the transmitted data or MAC command frame.
|
||||
*/
|
||||
extern uint8_t macDSN;
|
||||
|
||||
/* uint16_t macDstPANId -- default 0xffff
|
||||
*
|
||||
* The 16-bit identifier of the PAN on which the device is sending to. If this value
|
||||
* is 0xffff, the device is not associated.
|
||||
*/
|
||||
extern uint16_t macDstPANId;
|
||||
|
||||
/* uint16_t macSrcPANId -- default 0xffff
|
||||
*
|
||||
* The 16-bit identifier of the PAN on which the device is operating. If this value
|
||||
* is 0xffff, the device is not associated.
|
||||
*/
|
||||
extern uint16_t macSrcPANId;
|
||||
|
||||
/* uint16_t macShortAddress -- default 0xffff
|
||||
*
|
||||
* The 16-bit address that the device uses to communicate in the PAN. If the device is the
|
||||
* PAN coordinator, this value shall be chosen before a PAN is started. Otherwise, the
|
||||
* address is allocated by a coordinator during association. A value of 0xfffe indicates
|
||||
* that the device has associated but has not been allocated an address. A value of 0xffff
|
||||
* indicates that the device does not have a short address.
|
||||
*/
|
||||
extern uint16_t macShortAddress;
|
||||
|
||||
/* Scan defines */
|
||||
|
||||
|
||||
/* Protoypes */
|
||||
void mac_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
488
cpu/avr/radio/mac/sicslowmac.c
Normal file
488
cpu/avr/radio/mac/sicslowmac.c
Normal file
@ -0,0 +1,488 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* $Id: sicslowmac.c,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Example glue code between the existing MAC code and the
|
||||
* Contiki mac interface
|
||||
*
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
* Eric Gnoske <egnoske@gmail.com>
|
||||
* Blake Leverett <bleverett@gmail.com>
|
||||
*
|
||||
* \addtogroup rf230mac
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <util/delay.h>
|
||||
#include "net/rime/rimebuf.h"
|
||||
#include "mac.h"
|
||||
#include "frame.h"
|
||||
#include "radio.h"
|
||||
#include "tcpip.h"
|
||||
#include "sicslowmac.h"
|
||||
#include "sicslowpan.h"
|
||||
#include "ieee-15-4-manager.h"
|
||||
|
||||
/* Macros */
|
||||
#define DEBUG 0
|
||||
#define MAX_EVENTS 10
|
||||
|
||||
#if DEBUG
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
|
||||
/* Globals */
|
||||
static mac_driver_t mac_driver;
|
||||
static mac_driver_t *pmac_driver = &mac_driver;
|
||||
extern ieee_15_4_manager_t ieee15_4ManagerAddress;
|
||||
static parsed_frame_t *parsed_frame;
|
||||
|
||||
|
||||
const mac_driver_t sicslowmac_driver = {
|
||||
sicslowmac_dataRequest,
|
||||
/* read_packet, */
|
||||
/* set_receive_function, */
|
||||
/* on, */
|
||||
/* off, */
|
||||
};
|
||||
|
||||
static struct {
|
||||
uint8_t head;
|
||||
uint8_t tail;
|
||||
event_object_t event_object[MAX_EVENTS];
|
||||
} event_queue;
|
||||
|
||||
/* Prototypes */
|
||||
static void setinput(void (*r)(const mac_driver_t *d));
|
||||
static void (*pinput)(const mac_driver_t *r);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Checks for any pending events in the queue.
|
||||
*
|
||||
* \return True if there is a pending event, else false.
|
||||
*/
|
||||
uint8_t
|
||||
mac_event_pending(void)
|
||||
{
|
||||
return (event_queue.head != event_queue.tail);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Puts an event into the queue of events.
|
||||
*
|
||||
* \param object is a pointer to the event to add to queue.
|
||||
*/
|
||||
void
|
||||
mac_put_event(event_object_t *object)
|
||||
{
|
||||
uint8_t newhead;
|
||||
|
||||
if ((event_queue.head + 1) % MAX_EVENTS == event_queue.tail){
|
||||
/* queue full, get outta here */
|
||||
return;
|
||||
}
|
||||
|
||||
newhead = event_queue.head;
|
||||
|
||||
/* store in queue */
|
||||
event_queue.event_object[newhead] = *object;
|
||||
|
||||
/* calculate new head index */
|
||||
newhead++;
|
||||
if (newhead >= MAX_EVENTS){
|
||||
newhead = 0;
|
||||
}
|
||||
event_queue.head = newhead;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Pulls an event from the event queue.
|
||||
* Assumes that there is an event in the queue. See mac_event_pending().
|
||||
*
|
||||
* \return Pointer to the event object, or NULL in the event of empty queue.
|
||||
*/
|
||||
event_object_t
|
||||
*mac_get_event(void)
|
||||
{
|
||||
event_object_t *object = NULL;
|
||||
volatile uint8_t newtail;
|
||||
|
||||
newtail = event_queue.tail;
|
||||
|
||||
object = &(event_queue.event_object[newtail]);
|
||||
|
||||
/* calculate new tail */
|
||||
newtail++;
|
||||
if (newtail >= MAX_EVENTS){
|
||||
newtail = 0;
|
||||
}
|
||||
|
||||
event_queue.tail = newtail;
|
||||
|
||||
return(object);
|
||||
}
|
||||
|
||||
void mac_pollhandler(void)
|
||||
{
|
||||
mac_task(NULL, NULL);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief This is the main loop task for the MAC. Called by the
|
||||
* main application loop.
|
||||
*/
|
||||
void
|
||||
mac_task(process_event_t ev, process_data_t data)
|
||||
{
|
||||
/* check for event in queue */
|
||||
event_object_t *event;
|
||||
|
||||
if(mac_event_pending()){
|
||||
|
||||
event = mac_get_event();
|
||||
|
||||
/* Handle events from radio */
|
||||
if (event){
|
||||
if (event->event == MAC_EVENT_RX){
|
||||
/* got a frame, find out with kind of frame */
|
||||
parsed_frame = (parsed_frame_t *)event->data;
|
||||
if (parsed_frame->fcf->frameType == DATAFRAME){
|
||||
sicslowmac_dataIndication();
|
||||
}
|
||||
|
||||
/* Frame no longer in use */
|
||||
parsed_frame->in_use = false;
|
||||
}
|
||||
|
||||
if (event->event == MAC_EVENT_DROPPED){
|
||||
/* Frame was dropped */
|
||||
printf("sicslowmac: Frame Dropped!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
setinput(void (*r)(const mac_driver_t *d))
|
||||
{
|
||||
pinput = r;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
sicslowmac_dataIndication(void)
|
||||
{
|
||||
rimebuf_clear();
|
||||
|
||||
/* Finally, get the stuff into the rime buffer.... */
|
||||
rimebuf_copyfrom(parsed_frame->payload, parsed_frame->payload_length);
|
||||
rimebuf_set_datalen(parsed_frame->payload_length);
|
||||
|
||||
/* Change addresses to expected byte order */
|
||||
byte_reverse((uint8_t *)parsed_frame->dest_addr, 8);
|
||||
byte_reverse((uint8_t *)parsed_frame->src_addr, 8);
|
||||
|
||||
rimebuf_set_addr(RIMEBUF_ADDR_RECEIVER, (const rimeaddr_t *)parsed_frame->dest_addr);
|
||||
rimebuf_set_addr(RIMEBUF_ADDR_SENDER, (const rimeaddr_t *)parsed_frame->src_addr);
|
||||
|
||||
PRINTF("sicslowmac: hand off frame to sicslowpan \n");
|
||||
pinput(pmac_driver);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief This is the implementation of the 15.4 MAC Data Request
|
||||
* primitive.
|
||||
*
|
||||
* \return Integer denoting success or failure.
|
||||
* \retval 0 Failure.
|
||||
* \retval 1 Success.
|
||||
*
|
||||
* The data request primitive creates the frame header based
|
||||
* on static and dynamic data. The static data will be refined
|
||||
* in phase II of the project. The frame payload and length are
|
||||
* retrieved from the rime buffer and rime length respectively.
|
||||
*
|
||||
* When the header and payload are assembled into the
|
||||
* frame_create_params structure, the frame is created
|
||||
* by a call to frame_tx_create and then transmited via
|
||||
* radio_send_data.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sicslowmac_dataRequest(void)
|
||||
{
|
||||
|
||||
/* create structure to store result. */
|
||||
frame_create_params_t params;
|
||||
frame_result_t result;
|
||||
|
||||
/* Save the msduHandle in a global variable. */
|
||||
msduHandle = rimebuf_attr(RIMEBUF_ATTR_PACKET_ID);
|
||||
|
||||
/* Build the FCF. */
|
||||
params.fcf.frameType = DATAFRAME;
|
||||
params.fcf.securityEnabled = false;
|
||||
params.fcf.framePending = false;
|
||||
params.fcf.ackRequired = rimebuf_attr(RIMEBUF_ATTR_RELIABLE);
|
||||
params.fcf.panIdCompression = false;
|
||||
|
||||
/* Insert IEEE 802.15.4 (2003) version bit. */
|
||||
params.fcf.frameVersion = IEEE802154_2003;
|
||||
|
||||
/* Increment and set the data sequence number. */
|
||||
params.seq = macDSN++;
|
||||
|
||||
/* Complete the addressing fields. */
|
||||
/**
|
||||
\todo For phase 1 the addresses are all long. We'll need a mechanism
|
||||
in the rime attributes to tell the mac to use long or short for phase 2.
|
||||
*/
|
||||
params.fcf.srcAddrMode = LONGADDRMODE;
|
||||
params.dest_pid = ieee15_4ManagerAddress.get_dst_panid();
|
||||
|
||||
/*
|
||||
* If the output address is NULL in the Rime buf, then it is broadcast
|
||||
* on the 802.15.4 network.
|
||||
*/
|
||||
if(rimeaddr_cmp(rimebuf_addr(RIMEBUF_ADDR_RECEIVER), &rimeaddr_null) ) {
|
||||
/* Broadcast requires short address mode. */
|
||||
params.fcf.destAddrMode = SHORTADDRMODE;
|
||||
params.dest_pid = BROADCASTPANDID;
|
||||
params.dest_addr.addr16 = BROADCASTADDR;
|
||||
|
||||
} else {
|
||||
|
||||
/* Phase 1.5 - end nodes send to anyone? */
|
||||
memcpy(¶ms.dest_addr, (uint8_t *)rimebuf_addr(RIMEBUF_ADDR_RECEIVER), LONG_ADDR_LEN);
|
||||
|
||||
/* Hack to allow Ethernet to send us data, we have to limit addresses to have zero in upper */
|
||||
/* two bytes */
|
||||
/* params.dest_addr.addr64 &= 0x0000ffffffffffffUL; */
|
||||
|
||||
/* Phase 1 - end nodes only sends to pan coordinator node. */
|
||||
/* params.dest_addr.addr64 = ieee15_4ManagerAddress.get_coord_long_addr(); */
|
||||
params.fcf.destAddrMode = LONGADDRMODE;
|
||||
}
|
||||
|
||||
/* Set the source PAN ID to the global variable. */
|
||||
params.src_pid = ieee15_4ManagerAddress.get_src_panid();
|
||||
|
||||
/*
|
||||
* Set up the source address using only the long address mode for
|
||||
* phase 1.
|
||||
*/
|
||||
params.src_addr.addr64 = ieee15_4ManagerAddress.get_long_addr();
|
||||
|
||||
/* Copy the payload data. */
|
||||
params.payload_len = rimebuf_datalen();
|
||||
params.payload = rimebuf_dataptr();
|
||||
|
||||
/* Create transmission frame. */
|
||||
frame_tx_create(¶ms, &result);
|
||||
|
||||
/* Retry up to this many times to send the packet if radio is busy */
|
||||
uint8_t retry_count = 3;
|
||||
|
||||
while(retry_count) {
|
||||
|
||||
PRINTF("sicslowmac: sending packet of length %d to radio, result:", result.length);
|
||||
|
||||
/* Send data to radio. */
|
||||
radio_status_t rv = radio_send_data(result.length, result.frame);
|
||||
|
||||
if (rv == RADIO_SUCCESS) {
|
||||
PRINTF(" Success\n");
|
||||
|
||||
return 1; /* True says that the packet could be sent */
|
||||
}
|
||||
|
||||
|
||||
if (rv != RADIO_WRONG_STATE) {
|
||||
PRINTF(" Failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRINTF(" Radio busy, retrying\n");
|
||||
|
||||
_delay_ms(10); //We have blocking delay here, it is safest this way
|
||||
|
||||
retry_count--;
|
||||
}
|
||||
|
||||
PRINTF("sicslowmac: Unable to send packet, dropped\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Stub function that will be implemented in phase 2 to cause
|
||||
* end nodes to sleep.
|
||||
*/
|
||||
int
|
||||
mac_wake(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Stub function that will be implemented in phase 2 to cause
|
||||
* end nodes to sleep.
|
||||
*/
|
||||
int
|
||||
mac_sleep(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const mac_driver_t *
|
||||
sicslowmac_init(const struct radio_driver *d)
|
||||
{
|
||||
/* AD: commented out the radio_driver code for now.*/
|
||||
/* radio = d;
|
||||
radio->set_receive_function(input_packet);
|
||||
radio->on();*/
|
||||
|
||||
return &sicslowmac_driver;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief This is the implementation of the 15.4 MAC Reset Request
|
||||
* primitive.
|
||||
* \param setDefaultPIB True if the default PIB values should be set.
|
||||
* \return Integer denoting success or failure.
|
||||
* \retval 0 Failure.
|
||||
* \retval 1 Success.
|
||||
*
|
||||
* Sets all PIB values to default.
|
||||
*/
|
||||
void
|
||||
sicslowmac_resetRequest (bool setDefaultPIB)
|
||||
{
|
||||
if(setDefaultPIB){
|
||||
/* initialize all of the MAC PIB variables to their default values */
|
||||
macCoordShortAddress = 0xffff;
|
||||
macDSN = rand() % 256;
|
||||
macSrcPANId = SOURCE_PAN_ID;
|
||||
macDstPANId = DEST_PAN_ID;
|
||||
macShortAddress = 0xffff;
|
||||
/* Setup the address of this device by reading a stored address from eeprom. */
|
||||
/** \todo This might be read from the serial eeprom onboard Raven. */
|
||||
AVR_ENTER_CRITICAL_REGION();
|
||||
eeprom_read_block ((void *)&macLongAddr, EEPROMMACADDRESS, 8);
|
||||
|
||||
byte_reverse((uint8_t *) &macLongAddr, 8);
|
||||
|
||||
|
||||
AVR_LEAVE_CRITICAL_REGION();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(mac_process, "802.15.4 MAC process");
|
||||
PROCESS_THREAD(mac_process, ev, data)
|
||||
{
|
||||
|
||||
PROCESS_POLLHANDLER(mac_pollhandler());
|
||||
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
radio_status_t return_value;
|
||||
|
||||
/* init radio */
|
||||
/** \todo: this screws up if calosc is set to TRUE, find out why? */
|
||||
return_value = radio_init(false, NULL, NULL, NULL);
|
||||
|
||||
#if DEBUG
|
||||
if (return_value == RADIO_SUCCESS) {
|
||||
printf("Radio init successful.\n");
|
||||
} else {
|
||||
printf("Radio init failed with return: %d\n", return_value);
|
||||
}
|
||||
#endif
|
||||
|
||||
radio_set_operating_channel(24);
|
||||
radio_use_auto_tx_crc(true);
|
||||
radio_set_trx_state(TRX_OFF);
|
||||
|
||||
mac_init();
|
||||
|
||||
/* Set up MAC function pointers and sicslowpan callback. */
|
||||
pmac_driver->set_receive_function = setinput;
|
||||
pmac_driver->send = sicslowmac_dataRequest;
|
||||
pmac_driver->wake = mac_wake;
|
||||
pmac_driver->sleep = mac_sleep;
|
||||
sicslowpan_init(pmac_driver);
|
||||
|
||||
ieee_15_4_init(&ieee15_4ManagerAddress);
|
||||
|
||||
radio_set_trx_state(RX_AACK_ON);
|
||||
|
||||
while(1) {
|
||||
PROCESS_YIELD();
|
||||
mac_task(ev, data);
|
||||
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
void byte_reverse(uint8_t * bytes, uint8_t num)
|
||||
{
|
||||
uint8_t tempbyte;
|
||||
|
||||
uint8_t i, j;
|
||||
|
||||
i = 0;
|
||||
j = num - 1;
|
||||
|
||||
while(i < j) {
|
||||
tempbyte = bytes[i];
|
||||
bytes[i] = bytes[j];
|
||||
bytes[j] = tempbyte;
|
||||
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
112
cpu/avr/radio/mac/sicslowmac.h
Normal file
112
cpu/avr/radio/mac/sicslowmac.h
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* $Id: sicslowmac.h,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Example glue code between the existing MAC code and the
|
||||
* Contiki mac interface
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
* Eric Gnoske <egnoske@gmail.com>
|
||||
* Blake Leverett <bleverett@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup rf230mac
|
||||
*/
|
||||
|
||||
#ifndef __SICSLOWMAC_H__
|
||||
#define __SICSLOWMAC_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "contiki.h"
|
||||
#include "dev/radio.h"
|
||||
|
||||
/**
|
||||
* The structure of a device driver for a radio in Contiki.
|
||||
*/
|
||||
typedef struct mac_driver_s{
|
||||
/** Send a packet from the Rime buffer */
|
||||
int (* send)(void);
|
||||
|
||||
/** Read a received packet into the Rime buffer. */
|
||||
/* int (* read)(void); */
|
||||
|
||||
/** Set a function to be called when a packet has been received. */
|
||||
void (* set_receive_function)(void (*f)(const struct mac_driver_s *d));
|
||||
|
||||
/** Wake the radio up. */
|
||||
int (* wake)(void);
|
||||
|
||||
/** Put the radio to sleep. */
|
||||
int (* sleep)(void);
|
||||
}mac_driver_t;
|
||||
|
||||
/* Macros & Defines */
|
||||
|
||||
typedef enum {
|
||||
MAC_EVENT_RX=0x10,
|
||||
MAC_EVENT_ACK,
|
||||
MAC_EVENT_NACK,
|
||||
MAC_EVENT_SCAN,
|
||||
MAC_EVENT_BEACON_REQ,
|
||||
MAC_EVENT_DROPPED,
|
||||
MAC_EVENT_TX
|
||||
/* MAC_EVENT_TIMER */
|
||||
} event_t;
|
||||
|
||||
typedef struct {
|
||||
event_t event; /**< Event type, see event_t for details. */
|
||||
uint8_t *data; /**< Associated data that goes with the event. Depends on event type. */
|
||||
} event_object_t;
|
||||
|
||||
extern const mac_driver_t sicslowmac_driver;
|
||||
|
||||
/* Prototypes */
|
||||
PROCESS_NAME(mac_process);
|
||||
|
||||
uint8_t mac_event_pending(void);
|
||||
void mac_put_event(event_object_t *object);
|
||||
event_object_t *mac_get_event(void);
|
||||
void mac_task(process_event_t ev, process_data_t data);
|
||||
uint8_t nwk_dataIndication(void);
|
||||
const mac_driver_t *sicslowmac_init(const struct radio_driver *r);
|
||||
/* void sicslowmac_input_packet(const struct radio_driver *d); */
|
||||
int sicslowmac_dataRequest(void);
|
||||
void sicslowmac_dataIndication(void);
|
||||
void sicslowmac_resetRequest (bool setDefaultPIB);
|
||||
int sicsloread(void);
|
||||
void byte_reverse(uint8_t * bytes, uint8_t num);
|
||||
|
||||
#endif /* __SICSLOWMAC_H__ */
|
6
cpu/avr/radio/rf230/Makefile.rf230
Normal file
6
cpu/avr/radio/rf230/Makefile.rf230
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
CONTIKI_TARGET_SOURCEFILES += radio.c hal.c frame.c
|
||||
# timer.c
|
||||
|
||||
APPDIRS += $(CONTIKI)/cpu/avr/radio/rf230
|
||||
|
351
cpu/avr/radio/rf230/at86rf230_registermap.h
Normal file
351
cpu/avr/radio/rf230/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 2008/10/14 09:43:40 adamdunkels 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 */
|
337
cpu/avr/radio/rf230/frame.c
Normal file
337
cpu/avr/radio/rf230/frame.c
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id: frame.c,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*/
|
||||
/*
|
||||
* \brief This file is where the main functions that relate to frame
|
||||
* manipulation will reside.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup wireless
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \defgroup frame RF230 Frame handling
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* \brief 802.15.4 frame creation and parsing functions
|
||||
*
|
||||
* This file converts to and from a structure to a packed 802.15.4
|
||||
* frame.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#if defined( __GNUC__ )
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#else /* IAR */
|
||||
#include <iom1284.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "at86rf230_registermap.h"
|
||||
#include "radio.h"
|
||||
#include "frame.h"
|
||||
//#include "mac_event.h"
|
||||
#include "mac.h"
|
||||
#include "process.h"
|
||||
#include "sicslowmac.h"
|
||||
|
||||
|
||||
|
||||
/* Macros & Defines */
|
||||
|
||||
/* Some version of radio chip need this set to 2, so define it in Makefile */
|
||||
#ifndef AUTO_CRC_PADDING
|
||||
#define AUTO_CRC_PADDING 0
|
||||
#endif
|
||||
|
||||
|
||||
/* Protoypes */
|
||||
|
||||
/* Globals */
|
||||
|
||||
/* Frame handling global variables. */
|
||||
//FRAME_t rx_frame; /**< Structure that holds received frames. */
|
||||
static uint8_t tx_frame_buffer[130];
|
||||
|
||||
/* Implementation */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Creates a frame for transmission over the air. This function is
|
||||
* meant to be called by a higher level function, that interfaces to a MAC.
|
||||
*
|
||||
* \param p Pointer to frame_create_params_t struct, which specifies the
|
||||
* frame to send.
|
||||
*
|
||||
* \param frame_result Pointer to frame_result_t struct, which will
|
||||
* receive the results of this function, a pointer to the frame
|
||||
* created, and the length of the frame.
|
||||
*
|
||||
* \return Nothing directly, though the frame_result structure will be filled
|
||||
* in with a pointer to the frame and the frame length.
|
||||
*/
|
||||
void
|
||||
frame_tx_create(frame_create_params_t *p,frame_result_t *frame_result)
|
||||
{
|
||||
field_length_t flen;
|
||||
uint8_t index=0;
|
||||
|
||||
/* init flen to zeros */
|
||||
memset(&flen, 0, sizeof(field_length_t));
|
||||
|
||||
/* Determine lengths of each field based on fcf and other args */
|
||||
if (p->fcf.destAddrMode){
|
||||
flen.dest_pid_len = 2;
|
||||
}
|
||||
if (p->fcf.srcAddrMode){
|
||||
flen.src_pid_len = 2;
|
||||
}
|
||||
/* Set PAN ID compression bit it src pan if matches dest pan id. */
|
||||
if(p->fcf.destAddrMode == p->fcf.srcAddrMode){
|
||||
p->fcf.panIdCompression = 1;
|
||||
}
|
||||
if (p->fcf.panIdCompression){
|
||||
/* compressed header, only do dest pid */
|
||||
flen.src_pid_len = 0;
|
||||
}
|
||||
/* determine address lengths */
|
||||
switch (p->fcf.destAddrMode){
|
||||
case 2: /* 16-bit address */
|
||||
flen.dest_addr_len = 2;
|
||||
break;
|
||||
case 3: /* 64-bit address */
|
||||
flen.dest_addr_len = 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (p->fcf.srcAddrMode){
|
||||
case 2: /* 16-bit address */
|
||||
flen.src_addr_len = 2;
|
||||
break;
|
||||
case 3: /* 64-bit address */
|
||||
flen.src_addr_len = 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Aux security header */
|
||||
if (p->fcf.securityEnabled){
|
||||
switch (p->aux_hdr.security_control.key_id_mode){
|
||||
case 0:
|
||||
flen.aux_sec_len = 5; /* minimum value */
|
||||
break;
|
||||
case 1:
|
||||
flen.aux_sec_len = 6;
|
||||
break;
|
||||
case 2:
|
||||
flen.aux_sec_len = 10;
|
||||
break;
|
||||
case 3:
|
||||
flen.aux_sec_len = 14;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* OK, now we have field lengths. Time to actually construct */
|
||||
/* the outgoing frame, and store it in tx_frame_buffer */
|
||||
*(uint16_t *)tx_frame_buffer = p->fcf.word_val; /* FCF */
|
||||
index = 2;
|
||||
tx_frame_buffer[index++] = p->seq; /* sequence number */
|
||||
/* Destination PAN ID */
|
||||
if (flen.dest_pid_len == 2){
|
||||
*(uint16_t *)&tx_frame_buffer[index] = p->dest_pid;
|
||||
index += 2;
|
||||
}
|
||||
/* Destination address */
|
||||
switch (flen.dest_addr_len){
|
||||
case 2: /* two-byte address */
|
||||
*(uint16_t *)&tx_frame_buffer[index] = p->dest_addr.addr16;
|
||||
index += 2;
|
||||
break;
|
||||
case 8: /* 8-byte address */
|
||||
*(uint64_t *)&tx_frame_buffer[index] = p->dest_addr.addr64;
|
||||
index += 8;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Source PAN ID */
|
||||
if (flen.src_pid_len == 2){
|
||||
*(uint16_t *)&tx_frame_buffer[index] = p->src_pid;
|
||||
index += 2;
|
||||
}
|
||||
/* Source address */
|
||||
switch (flen.src_addr_len){
|
||||
case 2: /* two-byte address */
|
||||
*(uint16_t *)&tx_frame_buffer[index] = p->src_addr.addr16;
|
||||
index += 2;
|
||||
break;
|
||||
case 8: /* 8-byte address */
|
||||
*(uint64_t *)&tx_frame_buffer[index] = p->src_addr.addr64;
|
||||
index += 8;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Aux header */
|
||||
if (flen.aux_sec_len){
|
||||
memcpy((char *)&tx_frame_buffer[index],
|
||||
(char *)&p->aux_hdr,
|
||||
flen.aux_sec_len);
|
||||
index += flen.aux_sec_len;
|
||||
}
|
||||
/* Frame payload */
|
||||
memcpy((char *)&tx_frame_buffer[index],
|
||||
(char *)p->payload,
|
||||
p->payload_len);
|
||||
index += p->payload_len;
|
||||
|
||||
/* return results */
|
||||
frame_result->length = index + AUTO_CRC_PADDING;
|
||||
frame_result->frame = tx_frame_buffer;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Parses an input frame. Scans the input frame to find each
|
||||
* section, and stores the resulting addresses of each section in a
|
||||
* parsed_frame_t structure.
|
||||
*
|
||||
* \param rx_frame The input data from the radio chip.
|
||||
* \param pf The parsed_frame_t struct that stores a pointer to each
|
||||
* section of the frame payload.
|
||||
*/
|
||||
void rx_frame_parse(hal_rx_frame_t *rx_frame, parsed_frame_t *pf)
|
||||
{
|
||||
/* Pointer to start of AT86RF2xx frame */
|
||||
uint8_t *p = rx_frame->data;
|
||||
fcf_t *fcf = (fcf_t *)&rx_frame->data;
|
||||
static uint8_t frame_dropped = 0;
|
||||
|
||||
/* Uh-oh... please don't overwrite me! */
|
||||
if (pf->in_use) {
|
||||
|
||||
/* Only post this once when buffer is busy, otherwise you get many postings... */
|
||||
if (!frame_dropped) {
|
||||
event_object_t event;
|
||||
event.event = MAC_EVENT_DROPPED;
|
||||
event.data = NULL;
|
||||
mac_put_event(&event);
|
||||
process_post(&mac_process, event.event, event.data);
|
||||
}
|
||||
frame_dropped = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (fcf->frameType == ACKFRAME)
|
||||
return; /* Don't bother with ACK frames */
|
||||
|
||||
pf->fcf = (fcf_t *)p;
|
||||
pf->seqNum = p+2;
|
||||
p += 3; /* Skip first three bytes */
|
||||
/* Destination PID, if any */
|
||||
if (fcf->frameType != BEACONFRAME){ /* No destination addresses in Beacon frame */
|
||||
pf->dest_pid = (uint16_t *)p;
|
||||
p += 2;
|
||||
/* Destination address */
|
||||
pf->dest_addr = 0;
|
||||
if (fcf->destAddrMode == SHORTADDRMODE ||
|
||||
fcf->destAddrMode == LONGADDRMODE){
|
||||
pf->dest_addr = (addr_t *)p;
|
||||
/* Update pointer to account for possible missing addr field */
|
||||
if (fcf->destAddrMode == SHORTADDRMODE){
|
||||
p += 2;
|
||||
}
|
||||
if (fcf->destAddrMode == LONGADDRMODE){
|
||||
p += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Source PANID */
|
||||
pf->src_pid = 0;
|
||||
if (!fcf->panIdCompression){
|
||||
pf->src_pid = (uint16_t *)p;
|
||||
p += 2;
|
||||
}
|
||||
/* Source address */
|
||||
pf->src_addr = (addr_t *)p;
|
||||
if (fcf->srcAddrMode == SHORTADDRMODE){
|
||||
p += 2;
|
||||
}
|
||||
if (fcf->srcAddrMode == LONGADDRMODE){
|
||||
p += 8;
|
||||
}
|
||||
/* aux security header, not yet implemented */
|
||||
pf->aux_sec_hdr = 0;
|
||||
/* payload length */
|
||||
pf->payload_length = rx_frame->length - (p - (uint8_t*)&rx_frame->data) - 2;
|
||||
/* payload */
|
||||
pf->payload = p;
|
||||
|
||||
pf->lqi = rx_frame->lqi;
|
||||
pf->fcs = rx_frame->crc;
|
||||
|
||||
/* pass frame to sicslowmac layer */
|
||||
event_object_t event;
|
||||
event.event = MAC_EVENT_RX;
|
||||
event.data = (uint8_t*)pf;
|
||||
pf->in_use = 1;
|
||||
mac_put_event(&event);
|
||||
process_poll(&mac_process);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
226
cpu/avr/radio/rf230/frame.h
Normal file
226
cpu/avr/radio/rf230/frame.h
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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 frame
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* \brief 802.15.4 frame creation and parsing functions
|
||||
*
|
||||
* This file converts to and from a structure to a packed 802.15.4
|
||||
* frame.
|
||||
*
|
||||
* $Id: frame.h,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Includes */
|
||||
#ifndef FRAME_UTILS_H
|
||||
#define FRAME_UTILS_H
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/* Macros & Defines */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Defines the bitfields of the frame control field (FCF).
|
||||
*/
|
||||
typedef union{
|
||||
/** \brief Structure of bitfields for the FCF */
|
||||
struct{
|
||||
uint8_t frameType : 3; /**< Frame type field, see 802.15.4 */
|
||||
bool securityEnabled : 1; /**< True if security is used in this frame */
|
||||
bool framePending : 1; /**< True if sender has more data to send */
|
||||
bool ackRequired : 1; /**< Is an ack frame required? */
|
||||
bool panIdCompression : 1; /**< Is this a compressed header? */
|
||||
uint8_t reserved : 3; /**< Unused bits */
|
||||
uint8_t destAddrMode : 2; /**< Destination address mode, see 802.15.4 */
|
||||
uint8_t frameVersion : 2; /**< 802.15.4 frame version */
|
||||
uint8_t srcAddrMode : 2; /**< Source address mode, see 802.15.4 */
|
||||
};
|
||||
uint16_t word_val; /**< A word-wide value for the entire FCF */
|
||||
}fcf_t;
|
||||
|
||||
/**
|
||||
* \brief Structure that contains the lengths of the various addressing and security fields
|
||||
* in the 802.15.4 header. This structure is used in \ref frame_tx_create()
|
||||
*/
|
||||
typedef struct{
|
||||
uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */
|
||||
uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */
|
||||
uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */
|
||||
uint8_t src_addr_len; /**< Length (in bytes) of source address field */
|
||||
uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */
|
||||
} field_length_t;
|
||||
|
||||
/** \brief 802.15.4 security control bitfield. See section 7.6.2.2.1 in 802.15.4 specification */
|
||||
typedef struct{
|
||||
uint8_t security_level : 3; /**< security level */
|
||||
uint8_t key_id_mode : 2; /**< Key identifier mode */
|
||||
uint8_t reserved : 3; /**< Reserved bits */
|
||||
} scf_t;
|
||||
|
||||
/** \brief 802.15.4 Aux security header */
|
||||
typedef struct{
|
||||
scf_t security_control; /**< Security control bitfield */
|
||||
uint32_t frame_counter; /**< Frame counter, used for security */
|
||||
uint8_t key[9]; /**< The key itself, or an index to the key */
|
||||
} aux_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Some constants for frame length calculations.
|
||||
* The IEEE 802.15.4 frame has a number of constant/fixed fields that
|
||||
* can be counted to make frame construction and max payload
|
||||
* calculations easier.
|
||||
*
|
||||
* These include:
|
||||
* 1. FCF - 2 bytes - Fixed
|
||||
* 2. Sequence number - 1 byte - Fixed
|
||||
* 3. Addressing fields - 4 - 20 bytes - Variable
|
||||
* 4. Aux security header - 0 - 14 bytes - Variable
|
||||
* 5. CRC - 2 bytes - Fixed
|
||||
*/
|
||||
#define FIXEDFRAMEOVERHEAD (5)
|
||||
|
||||
/** \brief A union of short and long address types. Although a node can have
|
||||
* both long and short addresses a frame will contain
|
||||
* only one of these. Therefore, a union is appropriate here. */
|
||||
typedef union{
|
||||
uint16_t shortAddr; /**< Short address, two bytes */
|
||||
uint64_t longAddr; /**< Long address, eight bytes */
|
||||
}ADDR_SIZE_SPEC_t;
|
||||
|
||||
/** \brief Structure containing a PAN ID and an address */
|
||||
typedef struct{
|
||||
uint16_t panId; /**< PAN ID */
|
||||
ADDR_SIZE_SPEC_t addrSpec; /**< A short or long address */
|
||||
}PAN_ID_ADDR_SPEC_t;
|
||||
|
||||
/** \brief Structure containing both source and destination addresses */
|
||||
typedef struct{
|
||||
PAN_ID_ADDR_SPEC_t destAddrFields; /**< Destination address */
|
||||
PAN_ID_ADDR_SPEC_t srcAddrFields; /**< Source address */
|
||||
}ADDR_FIELD_SPEC_t;
|
||||
|
||||
/** \brief Union of both short and long addresses */
|
||||
typedef union{
|
||||
uint16_t addr16; /**< Short address */
|
||||
uint64_t addr64; /**< Long address */
|
||||
} addr_t;
|
||||
|
||||
/** \brief Strucure used to return that status of the frame create process.
|
||||
* See frame_tx_create() function.*/
|
||||
typedef struct{
|
||||
uint8_t *frame; /**< Pointer to created frame */
|
||||
uint8_t length; /**< Length (in bytes) of created frame */
|
||||
} frame_result_t;
|
||||
|
||||
/** \brief Parameters used by the frame_tx_create() function. These
|
||||
* parameters are used in the 802.15.4 frame header. See the 802.15.4
|
||||
* specification for details.
|
||||
*/
|
||||
typedef struct{
|
||||
fcf_t fcf; /**< Frame control field */
|
||||
uint8_t seq; /**< Sequence number */
|
||||
uint16_t dest_pid; /**< Destination PAN ID */
|
||||
addr_t dest_addr; /**< Destination address */
|
||||
uint16_t src_pid; /**< Source PAN ID */
|
||||
addr_t src_addr; /**< Source address */
|
||||
aux_hdr_t aux_hdr; /**< Aux security header */
|
||||
uint8_t *payload; /**< Pointer to 802.15.4 frame payload */
|
||||
uint8_t payload_len; /**< Length of payload field */
|
||||
} frame_create_params_t;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief 802.15.4 frame structure, including the LQI, RSSI, and frame time
|
||||
* fields.
|
||||
*/
|
||||
/* typedef struct{ */
|
||||
/* fcf_t fcf; /\**< The FCF of the frame. *\/ */
|
||||
/* uint8_t seqNum; /\**< The sequence number of the frame. *\/ */
|
||||
/* uint16_t dest_pid; /\**< Destination PAN ID. *\/ */
|
||||
/* addr_t dest_addr; /\**< Destination address. *\/ */
|
||||
/* uint16_t src_pid; /\**< PAN ID *\/ */
|
||||
/* addr_t src_addr; /\**< Source address *\/ */
|
||||
/* uint8_t aux_sec_hdr[14]; /\**< 802.15.4 Aux security header *\/ */
|
||||
/* uint8_t payload_length; /\**< Length of payload section of frame *\/ */
|
||||
/* uint8_t payload[118]; /\**< Frame payload *\/ */
|
||||
/* uint8_t lqi; /\**< Link quality indication value *\/ */
|
||||
/* uint8_t rssi; /\**< Received signal strength indication value *\/ */
|
||||
/* uint32_t time; /\**< Time stamp of received frame *\/ */
|
||||
/* bool fcs:1; /\**< True if checksum has passed *\/ */
|
||||
/* bool in_use:1; /\**< Is this frame struct being used? *\/ */
|
||||
/* }FRAME_t; */
|
||||
|
||||
typedef struct{
|
||||
fcf_t * fcf; /**< The FCF of the frame. */
|
||||
uint8_t * seqNum; /**< The sequence number of the frame. */
|
||||
uint16_t * dest_pid; /**< Destination PAN ID. */
|
||||
addr_t * dest_addr; /**< Destination address. */
|
||||
uint16_t * src_pid; /**< PAN ID */
|
||||
addr_t * src_addr; /**< Source address */
|
||||
uint8_t * aux_sec_hdr; /**< 802.15.4 Aux security header */
|
||||
uint8_t * payload; /**< Frame payload */
|
||||
uint8_t payload_length; /**< Length of payload section of frame */
|
||||
uint8_t lqi; /**< Link quality indication value */
|
||||
uint8_t rssi; /**< Received signal strength indication value */
|
||||
uint32_t time; /**< Time stamp of received frame */
|
||||
bool fcs:1; /**< True if checksum has passed */
|
||||
bool in_use:1; /**< Is this frame struct being used? */
|
||||
} parsed_frame_t;
|
||||
|
||||
/* Globals */
|
||||
|
||||
//extern FRAME_t rx_frame;
|
||||
|
||||
/* Protoypes */
|
||||
|
||||
void frame_tx_create(frame_create_params_t *p,frame_result_t *frame_result);
|
||||
void frame_rx_callback(uint16_t data);
|
||||
void rx_frame_parse(hal_rx_frame_t *rx_frame, parsed_frame_t *pf);
|
||||
|
||||
/** @} */
|
||||
#endif /* FRAME_UTILS_H */
|
729
cpu/avr/radio/rf230/hal.c
Normal file
729
cpu/avr/radio/rf230/hal.c
Normal file
@ -0,0 +1,729 @@
|
||||
/* 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.
|
||||
*
|
||||
* $Id: hal.c,v 1.1 2008/10/14 09:43:40 adamdunkels Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup wireless
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup hal RF230 hardware level drivers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* This file contains low-level radio driver code.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*============================ 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.
|
||||
*
|
||||
* \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; /* Store 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 */
|
||||
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;
|
||||
|
||||
/*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)){
|
||||
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){
|
||||
if(trx_end_callback != NULL){
|
||||
trx_end_callback(isr_timestamp);
|
||||
}
|
||||
} else if (interrupt_source & HAL_TRX_UR_MASK){
|
||||
;
|
||||
} else if (interrupt_source & HAL_PLL_UNLOCK_MASK){
|
||||
;
|
||||
} else if (interrupt_source & HAL_PLL_LOCK_MASK){
|
||||
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. */
|
||||
} else {
|
||||
;
|
||||
}
|
||||
}
|
||||
# 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*/
|
321
cpu/avr/radio/rf230/hal.h
Normal file
321
cpu/avr/radio/rf230/hal.h
Normal file
@ -0,0 +1,321 @@
|
||||
/* 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 2008/10/14 09:43:40 adamdunkels 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 */
|
||||
#define RAVEN_D 0
|
||||
#define RAVENUSB_C 1
|
||||
|
||||
|
||||
#if 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 "RAVEN 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
|
||||
|
||||
|
||||
#define RADIO_VECT TIMER1_CAPT_vect
|
||||
#define HAL_ENABLE_RADIO_INTERRUPT( ) ( TIMSK1 |= ( 1 << ICIE1 ) )
|
||||
#define HAL_DISABLE_RADIO_INTERRUPT( ) ( TIMSK1 &= ~( 1 << ICIE1 ) )
|
||||
|
||||
#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*/
|
1373
cpu/avr/radio/rf230/radio.c
Normal file
1373
cpu/avr/radio/rf230/radio.c
Normal file
File diff suppressed because it is too large
Load Diff
219
cpu/avr/radio/rf230/radio.h
Normal file
219
cpu/avr/radio/rf230/radio.h
Normal file
@ -0,0 +1,219 @@
|
||||
/* 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: radio.h,v 1.1 2008/10/14 09:43:40 adamdunkels 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)
|
||||
/*============================ 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 ====================================*/
|
||||
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);
|
||||
#define delay_us( us ) ( _delay_loop_2( ( F_CPU / 4000000UL ) * ( us ) ) )
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
/*EOF*/
|
Loading…
Reference in New Issue
Block a user