Merged in merlin17/nuttx/xbee (pull request #484)

drivers/wireless:  Adds XBee S2C (802.15.4 firmware) support. XBee driver emulates mac802154 interface

* drivers/wireless/xbee: Adds xbee_netdev. Very similar to mac802154_netdev

* configs/same70-xplained: Starts adding support for XBee radio

* drivers/wireless/ieee802154/xbee: More structuring of XBee driver

* drivers/wireless/ieee802154/xbee: More Xbee work. Starts adding support on Clicker2

* drivers/wireless/ieee802154/xbee: More XBee MAC code

* configs/clicker2-stm32: More work to add XBee radio support

* drivers/wireless/ieee802154/xbee: Most of driver is now structured. No build errors

* configs/clicker2-stm32: Adjustments to XBee click module support

* drivers/xbee: Changes md_ prefix to xd_ prefix for xbeenet_driver_s fields

* drivers/xbee: XBee network device now passes MAC events via IOCTL

* drivers/xbee: Support querying device for parameters, setting parameters, and structures association/startpan logic

* configs/clicker2-stm32: Fixes Xbee lower half ATTN poll logic

* drivers/xbee: Removes dependce on CONFIG_IEEE802154_NETDEV

* drivers/xbee: Supports MAC RESET.request primitive

* drivers/xbee: Exposes generic AT query to the rest of driver

* drivers/xbee: Sets local values when writing setting change to Xbee device

* drivers/xbee: Finish association logic

* drivers/xbee: Adds xbee_get_mhrlen( ) allocating enough space for API frame header to frame

* drivers/xbee: Finishes transmit/receive logic

* drivers/xbee: Fixes xbee_netdev to match logic in mac802154_netdev.c

* drivers/xbee: Rearranges logic to prevent a loop condition where recursion could potentially occur to the point of deadlocking the system

Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
Anthony Merlino 2017-09-15 14:37:55 +00:00 committed by Gregory Nutt
parent 9af6b7cdae
commit 22754053e8
25 changed files with 6416 additions and 0 deletions

View File

@ -42,4 +42,27 @@ config CLICKER2_STM32_MRF24J40LH_VERBOSE
---help---
Enable verbose syslog for MRF24J40 lowerhalf
config CLICKER2_STM32_MB1_XBEE
bool "mikroBUS1 XBee radio"
default n
depends on IEEE802154_XBEE
select CLICKER2_STM32_MB1_SPI
---help---
Enable support for XBee radio on mikroBUS1
config CLICKER2_STM32_MB2_XBEE
bool "mikroBUS2 XBee radio"
default n
depends on IEEE802154_XBEE
select CLICKER2_STM32_MB2_SPI
---help---
Enable support for XBee on mikroBUS2
config CLICKER2_STM32_XBEELH_VERBOSE
bool "Verbose XBee lowerhalf"
default n
depends on IEEE802154_XBEE && DEBUG_WIRELESS_INFO
---help---
Enable verbose syslog for XBee lowerhalf
endif # ARCH_BOARD_CLICKER2_STM32

View File

@ -60,6 +60,10 @@ ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
CSRCS += stm32_mrf24j40.c
endif
ifeq ($(CONFIG_IEEE802154_XBEE),y)
CSRCS += stm32_xbee.c
endif
ifeq ($(CONFIG_ADC),y)
CSRCS += stm32_adc.c
endif

View File

@ -215,6 +215,12 @@
#define GPIO_MB2_RST (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN13)
#define GPIO_MB1_XBEE_RST (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN7)
#define GPIO_MB2_XBEE_RST (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN13)
/* Interrupts
*
* mikroBUS1 Interrupt: PE10-MB1_INT
@ -227,6 +233,9 @@
#define GPIO_MB1_INT (GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI|GPIO_PORTE|GPIO_PIN10)
#define GPIO_MB2_INT (GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI|GPIO_PORTE|GPIO_PIN14)
#define GPIO_MB1_XBEE_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN10)
#define GPIO_MB2_XBEE_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN14)
#ifndef __ASSEMBLY__
/************************************************************************************
@ -313,5 +322,21 @@ int stm32_can_setup(void);
int stm32_mrf24j40_initialize(void);
#endif
/****************************************************************************
* Name: stm32_xbee_initialize
*
* Description:
* Initialize the XBee device.
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
#if defined(CONFIG_CLICKER2_STM32_MB1_XBEE) || defined(CONFIG_CLICKER2_STM32_MB2_XBEE)
int stm32_xbee_initialize(void);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __CONFIGS_CLICKER2_STM32_SRC_CLICKER2_H */

View File

@ -163,6 +163,16 @@ int stm32_bringup(void)
}
#endif
#if defined(CONFIG_CLICKER2_STM32_MB1_XBEE) || defined(CONFIG_CLICKER2_STM32_MB2_XBEE)
/* Configure XBee wireless */
ret = stm32_xbee_initialize();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: stm32_xbee_initialize() failed: %d\n", ret);
}
#endif
#ifdef CONFIG_BUTTONS
/* Register the BUTTON driver */

View File

@ -144,6 +144,13 @@ void stm32_spi3select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
stm32_gpiowrite(GPIO_MB1_CS, !selected);
break;
#endif
#ifdef CONFIG_IEEE802154_XBEE
case SPIDEV_IEEE802154(0):
/* Set the GPIO low to select and high to de-select */
stm32_gpiowrite(GPIO_MB1_CS, !selected);
break;
#endif
default:
break;

View File

@ -0,0 +1,347 @@
/****************************************************************************
* configs/clicker2-stm32/src/stm32_xbee.c
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/fs/fs.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/xbee.h>
#include "stm32_gpio.h"
#include "stm32_exti.h"
#include "stm32_spi.h"
#include "clicker2-stm32.h"
#ifdef CONFIG_IEEE802154_XBEE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_DRIVERS_WIRELESS
# error Wireless support requires CONFIG_DRIVERS_WIRELESS
#endif
#if !defined(CONFIG_CLICKER2_STM32_MB1_XBEE) && \
!defined(CONFIG_CLICKER2_STM32_MB2_XBEE)
# error Only the Mikroe XBee board is supported
#endif
#ifdef CONFIG_CLICKER2_STM32_MB1_XBEE
# ifndef CONFIG_STM32_SPI3
# error Mikroe XBee on mikroBUS1 requires CONFIG_STM32_SPI3
# endif
#endif
#ifdef CONFIG_CLICKER2_STM32_MB2_XBEE
# ifndef CONFIG_STM32_SPI2
# error Mikroe XBee on mikroBUS1 requires CONFIG_STM32_SPI2
# endif
#endif
/****************************************************************************
* Private Types
****************************************************************************/
struct stm32_priv_s
{
struct xbee_lower_s dev;
xcpt_t handler;
FAR void *arg;
uint32_t rstcfg;
uint32_t attncfg;
uint8_t spidev;
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the XBee driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
* reset - Reset the XBee using the reset pin
* attn_attach - Attach the XBee interrupt handler to the GPIO
* interrupt (ATTN)
* attn_enable - Enable or disable the GPIO interrupt
* attn_poll - Poll the current state of the GPIO interrupt (ATTN)
*/
static void stm32_reset(FAR const struct xbee_lower_s *lower);
static int stm32_attach_attn(FAR const struct xbee_lower_s *lower,
xcpt_t handler, FAR void *arg);
static void stm32_enable_attn(FAR const struct xbee_lower_s *lower, bool state);
static bool stm32_poll_attn(FAR const struct xbee_lower_s *lower);
static int stm32_xbee_devsetup(FAR struct stm32_priv_s *priv);
/****************************************************************************
* Private Data
****************************************************************************/
/* A reference to a structure of this type must be passed to the XBee
* driver. This structure provides information about the configuration
* of the XBee and provides some board-specific hooks.
*
* Memory for this structure is provided by the caller. It is not copied
* by the driver and is presumed to persist while the driver is active. The
* memory must be writable because, under certain circumstances, the driver
* may modify frequency or X plate resistance values.
*/
#ifdef CONFIG_CLICKER2_STM32_MB1_XBEE
static struct stm32_priv_s g_xbee_mb1_priv =
{
.dev.reset = stm32_reset,
.dev.attach = stm32_attach_attn,
.dev.enable = stm32_enable_attn,
.dev.poll = stm32_poll_attn,
.handler = NULL,
.arg = NULL,
.rstcfg = GPIO_MB1_XBEE_RST,
.attncfg = GPIO_MB1_XBEE_INT,
.spidev = 3,
};
#endif
#ifdef CONFIG_CLICKER2_STM32_MB2_XBEE
static struct stm32_priv_s g_xbee_mb2_priv =
{
.dev.reset = stm32_reset,
.dev.attach = stm32_attach_attn,
.dev.enable = stm32_enable_attn,
.dev.poll = stm32_poll_attn,
.handler = NULL,
.arg = NULL,
.rstcfg = GPIO_MB2_XBEE_RST,
.attncfg = GPIO_MB2_XBEE_INT,
.spidev = 2,
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the XBee driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
* reset - Reset the XBee using the reset pin
* attn_attach - Attach the XBee interrupt handler to the GPIO
* interrupt (ATTN)
* attn_enable - Enable or disable the GPIO interrupt
* attn_poll - Poll the current state of the GPIO interrupt (ATTN)
*/
static void stm32_reset(FAR const struct xbee_lower_s *lower)
{
FAR struct stm32_priv_s *priv = (FAR struct stm32_priv_s *)lower;
DEBUGASSERT(priv != NULL);
/* Hold reset line low for min. 200ns */
stm32_gpiowrite(priv->rstcfg, false);
up_udelay(1);
stm32_gpiowrite(priv->rstcfg, true);
up_mdelay(100);
}
static int stm32_attach_attn(FAR const struct xbee_lower_s *lower,
xcpt_t handler, FAR void *arg)
{
FAR struct stm32_priv_s *priv = (FAR struct stm32_priv_s *)lower;
DEBUGASSERT(priv != NULL);
/* Just save the handler for use when the interrupt is enabled */
priv->handler = handler;
priv->arg = arg;
return OK;
}
static void stm32_enable_attn(FAR const struct xbee_lower_s *lower,
bool state)
{
FAR struct stm32_priv_s *priv = (FAR struct stm32_priv_s *)lower;
/* The caller should not attempt to enable interrupts if the handler
* has not yet been 'attached'
*/
DEBUGASSERT(priv != NULL && (priv->handler != NULL || !state));
#ifdef CONFIG_CLICKER2_STM32_XBEELH_VERBOSE
wlinfo("state:%d\n", (int)state);
#endif
/* Attach and enable, or detach and disable */
if (state)
{
(void)stm32_gpiosetevent(priv->attncfg, false, true, true,
priv->handler, priv->arg);
}
else
{
(void)stm32_gpiosetevent(priv->attncfg, false, false, false,
NULL, NULL);
}
}
static bool stm32_poll_attn(FAR const struct xbee_lower_s *lower)
{
FAR struct stm32_priv_s *priv = (FAR struct stm32_priv_s *)lower;
return !stm32_gpioread(priv->attncfg);
}
/****************************************************************************
* Name: stm32_xbee_devsetup
*
* Description:
* Initialize one the XBee device in one mikroBUS slot
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
static int stm32_xbee_devsetup(FAR struct stm32_priv_s *priv)
{
FAR struct spi_dev_s *spi;
XBEEHANDLE xbee;
int ret;
/* Configure the Reset and Attention pins */
stm32_configgpio(priv->rstcfg);
stm32_configgpio(priv->attncfg);
/* Initialize the SPI bus and get an instance of the SPI interface */
spi = stm32_spibus_initialize(priv->spidev);
if (spi == NULL)
{
wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev);
return -ENODEV;
}
/* Initialize and register the SPI XBee device */
xbee = xbee_init(spi, &priv->dev);
if (xbee == NULL)
{
wlerr("ERROR: Failed to initialize XBee driver%d\n", priv->dev);
return -ENODEV;
}
/* Register the XBee netdev providing it the XBee MAC layer to interface with */
ret = xbee_netdev_register(xbee);
if (ret < 0)
{
wlerr("ERROR: Failed to register the XBee MAC network driver wpan%d: %d\n",
0, ret);
return ret;
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_xbee_initialize
*
* Description:
* Initialize the XBee device.
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
int stm32_xbee_initialize(void)
{
int ret;
#ifdef CONFIG_CLICKER2_STM32_MB1_XBEE
wlinfo("Configuring XBee in mikroBUS1\n");
ret = stm32_xbee_devsetup(&g_xbee_mb1_priv);
if (ret < 0)
{
wlerr("ERROR: Failed to initialize XBee on mikroBUS1: %d\n", ret);
}
#endif
#ifdef CONFIG_CLICKER2_STM32_MB2_XBEE
wlinfo("Configuring XBee in mikroBUS2\n");
ret = stm32_xbee_devsetup(&g_xbee_mb2_priv);
if (ret < 0)
{
wlerr("ERROR: Failed to initialize XBee on mikroBUS2: %d\n", ret);
}
#endif
UNUSED(ret);
return OK;
}
#endif /* CONFIG_IEEE802154_XBEE */

View File

@ -0,0 +1,120 @@
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="clicker2-stm32"
CONFIG_ARCH_BOARD_CLICKER2_STM32=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP_STM32F407VG=y
CONFIG_ARCH_CHIP_STM32=y
CONFIG_ARCH_IRQBUTTONS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_USBDEVCTRL=y
CONFIG_BOARD_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_CDCACM_CONSOLE=y
CONFIG_CDCACM_RXBUFSIZE=256
CONFIG_CDCACM_TXBUFSIZE=256
CONFIG_CDCACM=y
CONFIG_CLICKER2_STM32_MB1_XBEE=y
# CONFIG_DEV_CONSOLE is not set
CONFIG_DRIVERS_IEEE802154=y
CONFIG_DRIVERS_WIRELESS=y
CONFIG_EXAMPLES_NETTEST_DEVNAME="wpan0"
CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_1=0xfe80
CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_6=0x00ff
CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_7=0xfe00
CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_8=0x0800
CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=61616
CONFIG_EXAMPLES_NETTEST_TARGET2=y
CONFIG_EXAMPLES_NETTEST=y
CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
CONFIG_EXAMPLES_NSH=y
CONFIG_EXAMPLES_UDP_CLIENT_PORTNO=61617
CONFIG_EXAMPLES_UDP_DEVNAME="wpan0"
CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_1=0xfe80
CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_6=0x00ff
CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_7=0xfe00
CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_8=0x0d00
CONFIG_EXAMPLES_UDP_SERVER_PORTNO=61616
CONFIG_EXAMPLES_UDP_TARGET2=y
CONFIG_EXAMPLES_UDP=y
CONFIG_FAT_LCNAMES=y
CONFIG_FAT_LFN=y
CONFIG_FS_FAT=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_HAVE_CXX=y
CONFIG_IEEE802154_I8SAK=y
CONFIG_IEEE802154_IND_PREALLOC=32
CONFIG_IEEE802154_MACDEV=y
CONFIG_IEEE802154_NETDEV=y
CONFIG_IEEE802154_XBEE=y
CONFIG_INTELHEX_BINARY=y
CONFIG_IOB_BUFSIZE=128
CONFIG_IOB_NBUFFERS=32
CONFIG_IOB_NCHAINS=16
CONFIG_MAC802154_NNOTIF=48
CONFIG_MAC802154_NTXDESC=32
CONFIG_MAX_TASKS=16
CONFIG_MAX_WDOGPARMS=2
CONFIG_NET_6LOWPAN=y
CONFIG_NET_BROADCAST=y
CONFIG_NETDEVICES=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_STATISTICS=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
# CONFIG_NET_ETHERNET is not set
CONFIG_NET_HOSTNAME="XBee"
# CONFIG_NET_IPv4 is not set
CONFIG_NET_IPv6=y
CONFIG_NET_SOCKOPTS=y
CONFIG_NET_STATISTICS=y
CONFIG_NET_TCPBACKLOG=y
CONFIG_NET_TCP_WRITE_BUFFERS=y
CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
CONFIG_NETUTILS_TELNETD=y
CONFIG_NET=y
CONFIG_NFILE_DESCRIPTORS=8
CONFIG_NFILE_STREAMS=8
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
# CONFIG_NSH_CMDOPT_DF_H is not set
CONFIG_NSH_DISABLE_GET=y
CONFIG_NSH_DISABLE_PUT=y
# CONFIG_NSH_DISABLE_TELNETD is not set
CONFIG_NSH_DISABLE_WGET=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_NETLOCAL=y
CONFIG_NSH_NOMAC=y
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_MQ_MSGS=4
CONFIG_PREALLOC_TIMERS=4
CONFIG_PREALLOC_WDOGS=16
CONFIG_RAMLOG_BUFSIZE=8192
CONFIG_RAMLOG_SYSLOG=y
CONFIG_RAMLOG=y
CONFIG_RAM_SIZE=131072
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORKPERIOD=50000
CONFIG_SCHED_HPWORKPRIORITY=192
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_LPWORKPRIORITY=160
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_SDCLONE_DISABLE=y
CONFIG_STANDARD_SERIAL=y
CONFIG_START_YEAR=2013
CONFIG_STM32_CCMEXCLUDE=y
CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_OTGFS=y
CONFIG_STM32_PWR=y
CONFIG_SYSTEM_TELNET_CLIENT=y
CONFIG_TASK_NAME_SIZE=32
CONFIG_USBDEV=y
CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_WIRELESS_IEEE802154=y
CONFIG_WIRELESS=y

View File

@ -339,6 +339,16 @@ int sam_bringup(void)
}
#endif
#ifdef HAVE_XBEE
/* Configure XBee */
ret = sam_xbee_initialize();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: sam_xbee_initialize() failed: %d\n", ret);
}
#endif
#ifdef HAVE_ELF
/* Initialize the ELF binary loader */

View File

@ -0,0 +1,310 @@
/****************************************************************************
* configs/same70-xplained/src/sam_xbee.c
*
* Copyright (C) 2017 Verge Inc, All rights reserver
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/fs/fs.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/xbee.h>
#include "sam_gpio.h"
#include "sam_spi.h"
#include "same70-xplained.h"
#ifdef HAVE_XBEE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_DRIVERS_WIRELESS
# error Wireless support requires CONFIG_DRIVERS_WIRELESS
#endif
/****************************************************************************
* Private Types
****************************************************************************/
struct sam_priv_s
{
struct xbee_lower_s dev;
uint32_t attncfg;
uint32_t rstcfg;
uint8_t irq;
uint8_t spidev;
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind callbacks
* to isolate the XBee driver from differences in GPIO interrupt handling
* varying boards and MCUs.
*
* sam_reset - Reset the XBee
* irq_attach - Attach the XBee ATTN handler to the GPIO interrupt
* irq_enable - Enable or disable the GPIO interrupt
*/
static int sam_reset(FAR const struct xbee_lower_s *lower);
static int sam_attach_irq(FAR const struct xbee_lower_s *lower,
xcpt_t handler, FAR void *arg);
static void sam_enable_irq(FAR const struct xbee_lower_s *lower,
bool state);
static int sam_xbee_devsetup(FAR struct sam_priv_s *priv);
/****************************************************************************
* Private Data
****************************************************************************/
/* A reference to a structure of this type must be passed to the XBee
* driver. This structure provides information about the configuration
* of the XBee and provides some board-specific hooks.
*
* Memory for this structure is provided by the caller. It is not copied
* by the driver and is presumed to persist while the driver is active. The
* memory must be writable because, under certain circumstances, the driver
* may modify frequency or X plate resistance values.
*/
#ifdef CONFIG_SAME70XPLAINED_MB1_XBEE
static struct sam_priv_s g_xbee_mb1_priv =
{
.dev.attach = sam_attach_irq,
.dev.enable = sam_enable_irq,
.intcfg = CLICK_MB1_INTR,
.rstcfg = CLICK_MB1_RESET,
.irq = IRQ_MB1,
.csno = MB1_CSNO,
};
#endif
#ifdef CONFIG_SAME70XPLAINED_MB2_XBEE
static struct sam_priv_s g_xbee_mb2_priv =
{
.dev.attach = sam_attach_irq,
.dev.enable = sam_enable_irq,
.intcfg = CLICK_MB2_INTR,
.rstcfg = CLICK_MB2_RESET,
.irq = IRQ_MB2,
.spidev = MB2_CSNO,
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
static int sam_reset(FAR const struct xbee_lower_s *lower)
{
FAR struct sam_priv_s *priv = (FAR struct sam_priv_s *)lower;
DEBUGASSERT(priv != NULL);
/* Reset pulse */
sam_gpiowrite(priv->rstcfg, true);
sam_gpiowrite(priv->rstcfg, false);
/* Wait minimum 1.5 ms to allow Xbee a proper boot-up sequence */
/* TODO: Update time according to datasheet */
usleep(1500);
return OK;
}
static int sam_attach_irq(FAR const struct xbee_lower_s *lower,
xcpt_t handler, FAR void *arg)
{
FAR struct sam_priv_s *priv = (FAR struct sam_priv_s *)lower;
int ret;
DEBUGASSERT(priv != NULL);
ret = irq_attach(priv->irq, handler, arg);
if (ret < 0)
{
wlerr("ERROR: Failed to attach XBee interrupt: %d\n", ret);
}
return ret;
}
static void sam_enable_irq(FAR const struct xbee_lower_s *lower,
bool state)
{
FAR struct sam_priv_s *priv = (FAR struct sam_priv_s *)lower;
static bool enabled;
irqstate_t flags;
/* The caller should not attempt to enable interrupts if the handler
* has not yet been 'attached'
*/
DEBUGASSERT(priv != NULL);
wlinfo("state: %d irq: %u\n", (int)state, priv->irq);
/* Has the interrupt state changed */
flags = enter_critical_section();
if (state != enabled)
{
/* Enable or disable interrupts */
if (state)
{
wlinfo("Enabling\n");
sam_gpioirqenable(priv->irq);
enabled = true;
}
else
{
wlinfo("Disabling\n");
sam_gpioirqdisable(priv->irq);
enabled = false;
}
}
leave_critical_section(flags);
}
/****************************************************************************
* Name: sam_xbee_devsetup
*
* Description:
* Initialize one the XBee device in one mikroBUS slot
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
static int sam_xbee_devsetup(FAR struct sam_priv_s *priv)
{
FAR struct xbee_mac_s *xbee;
FAR struct spi_dev_s *spi;
int ret;
sam_configgpio(priv->rstcfg);
sam_configgpio(priv->attncfg);
sam_gpioirq(priv->attncfg);
/* Initialize the SPI bus and get an instance of the SPI interface */
spi = sam_spibus_initialize(priv->csno);
if (spi == NULL)
{
wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->csno);
return -ENODEV;
}
/* Initialize and register the SPI XBee device */
xbee = xbee_init(spi, &priv->dev);
if (xbee == NULL)
{
wlerr("ERROR: Failed to initialize XBee radio\n");
return -ENODEV;
}
ret = xbee_netdev_register(xbee);
if (ret < 0)
{
wlerr("ERROR: Failed to register the XBee MAC network driver wpan%d: %d\n",
0, ret);
return ret;
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_xbee_initialize
*
* Description:
* Initialize the XBee device.
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
int sam_xbee_initialize(void)
{
int ret;
#ifdef CONFIG_SAME70XPLAINED_MB1_XBEE
wlinfo("Configuring BEE in mikroBUS1\n");
ret = sam_xbee_devsetup(&g_xbee_mb1_priv);
if (ret < 0)
{
wlerr("ERROR: Failed to initialize XBee on mikroBUS1: %d\n", ret);
}
#endif
#ifdef CONFIG_SAME70XPLAINED_MB2_XBEE
wlinfo("Configuring XBee in mikroBUS2\n");
ret = sam_xbee_devsetup(&g_xbee_mb2_priv);
if (ret < 0)
{
wlerr("ERROR: Failed to initialize XBee on mikroBUS2: %d\n", ret);
}
#endif
UNUSED(ret);
return OK;
}
#endif /* HAVE_XBEE */

View File

@ -64,6 +64,7 @@
#define HAVE_PROGMEM_CHARDEV 1
#define HAVE_I2CTOOL 1
#define HAVE_MRF24J40 1
#define HAVE_XBEE 1
/* HSMCI */
/* Can't support MMC/SD if the card interface is not enabled */
@ -230,6 +231,29 @@
# undef HAVE_MRF24J40
#endif
/* Check if the XBee is supported in this configuration */
#ifndef CONFIG_IEEE802154_XBEE
# undef HAVE_XBEE
#endif
#ifndef CONFIG_SAME70XPLAINED_CLICKSHIELD
# undef HAVE_XBEE
#endif
#if !defined(CONFIG_SAME70XPLAINED_MB1_XBEE) && !defined(CONFIG_SAME70XPLAINED_MB2_XBEE) && \
!defined(CONFIG_SAME70XPLAINED_MB3_XBEE)
# undef HAVE_XBEE
#endif
#ifndef CONFIG_SAMV7_SPI0_MASTER
# undef HAVE_XBEE
#endif
#ifndef CONFIG_SAMV7_GPIOA_IRQ
# undef HAVE_XBEE
#endif
/* SAME70-XPLD GPIO Pin Definitions *************************************************/
/* Ethernet MAC.

View File

@ -22,4 +22,12 @@ config IEEE802154_AT86RF233
source drivers/wireless/ieee802154/at86rf23x/Kconfig
config IEEE802154_XBEE
bool "XBee IEEE 802.15.4 Radio (w/ MAC)"
default n
---help---
This selection enables support for the XBee Radio device.
source drivers/wireless/ieee802154/xbee/Kconfig
endif # DRIVERS_IEEE802154

View File

@ -43,6 +43,7 @@ ifeq ($(CONFIG_DRIVERS_IEEE802154),y)
include wireless$(DELIM)ieee802154$(DELIM)mrf24j40$(DELIM)Make.defs
include wireless$(DELIM)ieee802154$(DELIM)at86rf23x$(DELIM)Make.defs
include wireless$(DELIM)ieee802154$(DELIM)xbee$(DELIM)Make.defs
# Include common IEEE 802.15.4 build support

View File

@ -0,0 +1,77 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
if IEEE802154_XBEE
config IEEE802154_XBEE_FREQUENCY
int "SPI Frequency for XBee Radio"
default 2000000
---help---
SPI SLCK frequency in Hz
config XBEE_NETDEV_RECVRPRIO
int "Priority of frame receiver registerd with the MAC layer"
default 1
---help---
When the MAC layer receives an incoming data frame, it passes the frame
to registered receivers, in order of receiver priority, until one of the
receivers claim the frame.
An example case would be when 6LoWPAN and the MAC character driver are
enabled. Both have receivers registered with the MAC. The 6LoWPAN layer
should get assigned a higher priority than the character driver. In this
case, the 6LoWPAN receiver will receive the frame first. If the frame is
a 6LoWPAN frame, it will claim the frame and the MAC will not pass the
frame to any additional receivers. If it does not claim the frame, the
MAC layer will call the next highest priority receiver, in this case,
the MAC character driver (which should always be lowest priority since
it is a "catch-all" type receiver).
choice
prompt "Work queue"
default XBEE_NETDEV_LPWORK if SCHED_LPWORK
default XBEE_NETDEV_HPWORK if !SCHED_LPWORK && SCHED_HPWORK
depends on SCHED_WORKQUEUE
---help---
Work queue support is required to use the XBee MAC network
driver.
WARNING!! The IEEE802.15.4 network device must never run on the same
work queue as does the IEEE 802.15.4 MAC. That configuration will
cause deadlocks: The network logic may be blocked on the work queue
waiting on resources that can only be freed by the MAC logic but the
MAC is unable to run because the work queue is blocked. The
recommended configuration is: Network on the LP work queue; MAC on HP
work queue. Blocking on the HP work queue is a very bad thing in
any case.
config XBEE_NETDEV_HPWORK
bool "High priority"
depends on SCHED_HPWORK
config XBEE_NETDEV_LPWORK
bool "Low priority"
depends on SCHED_LPWORK
endchoice # Work queue
config XBEE_NNOTIF
int "Number or notification structures"
default 3
---help---
Configured number of notification strucures Default: 3
When various MAC management events occur, the MAC notifies the registered
receiver with an allocated notification structure indicating the event. The
events are primitives such as Association Indication etc.
config XBEE_LOCK_VERBOSE
bool "Verbose logging related to XBee driver lock management"
default n
depends on DEBUG_WIRELESS_INFO
---help---
Enable verbose logging of XBee lock management. Default: false
endif # IEEE802154_XBEE

View File

@ -0,0 +1,48 @@
############################################################################
# drivers/ieee802154/xbee/Make.defs
#
# Copyright (C) 2017 Verge Inc. All rights reserved.
# Author: Anthony Merlino <anthony@vergeaero.com>
#
# 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 NuttX 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 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.
#
############################################################################
ifeq ($(CONFIG_IEEE802154_XBEE),y)
# Include XBee files into the build
CSRCS += xbee_dataind.c xbee_ioctl.c xbee_mac.c xbee_netdev.c xbee_notif.c xbee.c
# Include XBee build support
DEPPATH += --dep-path wireless$(DELIM)ieee802154$(DELIM)xbee
VPATH += :wireless$(DELIM)ieee802154$(DELIM)xbee
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)ieee802154$(DELIM)xbee}
endif # CONFIG_IEEE802154_XBEE

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,581 @@
/****************************************************************************
* drivers/wireless/ieee802154/xbee/xbee.h
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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 __DRIVERS_WIRELESS_IEEE802154_XBEE_H
#define __DRIVERS_WIRELESS_IEEE802154_XBEE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <semaphore.h>
#include <nuttx/wqueue.h>
#include <nuttx/spi/spi.h>
#include <nuttx/wireless/ieee802154/xbee.h>
#include "xbee_notif.h"
#include "xbee_dataind.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration *************************************************************/
#ifndef CONFIG_SCHED_HPWORK
# error High priority work queue required in this driver
#endif
#ifndef CONFIG_IEEE802154_XBEE_FREQUENCY
# define CONFIG_IEEE802154_XBEE_FREQUENCY 2000000
#endif
#ifndef CONFIG_SPI_EXCHANGE
# error CONFIG_SPI_EXCHANGE required for this driver
#endif
#if !defined(CONFIG_XBEE_NNOTIF) || CONFIG_XBEE_NNOTIF <= 0
# undef CONFIG_XBEE_NNOTIF
# define CONFIG_XBEE_NNOTIF 6
#endif
#if !defined(CONFIG_XBEE_NDATAIND) || CONFIG_XBEE_NDATAIND <= 0
# undef CONFIG_XBEE_NDATAIND
# define CONFIG_XBEE_NDATAIND 8
#endif
#define XBEE_APIFRAME_MODEMSTATUS 0x8A
#define XBEE_APIFRAME_ATCOMMMAND 0x08
#define XBEE_APIFRAME_ATCOMMMANDQUEUED 0x09
#define XBEE_APIFRAME_ATRESPONSE 0x88
#define XBEE_APIFRAME_REMOTEREQUEST 0x17
#define XBEE_APIFRAME_REMOTERESPONSE 0x97
#define XBEE_APIFRAME_TXREQ_EADDR 0x00
#define XBEE_APIFRAME_TXREQ_SADDR 0x01
#define XBEE_APIFRAME_TXSTATUS 0x89
#define XBEE_APIFRAME_RX_EADDR 0x80
#define XBEE_APIFRAME_RX_SADDR 0x81
#define XBEE_APIFRAME_RXIO_EADDR 0x82
#define XBEE_APIFRAME_RXIO_SADDR 0x83
#define XBEE_EPASSOCFLAGS_PANID_REASSIGN 1
#define XBEE_EPASSOCFLAGS_CHAN_REASSIGN 2
#define XBEE_EPASSOCFLAGS_AUTOASSOC 4
#define XBEE_EPASSOCFLAGS_POLLONWAKE 8
#define XBEE_COORDASSOCFLAGS_PANID_REASSIGN 1
#define XBEE_COORDASSOCFLAGS_CHAN_REASSIGN 2
#define XBEE_COORDASSOCFLAGS_ALLOWASSOC 4
/* Size of read buffer active for all of the transaction. i.e. must be big enough
* to handle full transmit and receive.
*/
#define XBEE_RXBUF_SIZE 256
#define XBEE_STARTBYTE 0x7E
#define XBEE_APIFRAME_OVERHEAD 4
#define XBEE_APIFRAMEINDEX_STARTBYTE 0
#define XBEE_APIFRAMEINDEX_LENGTHMSB 1
#define XBEE_APIFRAMEINDEX_LENGTHLSB 2
#define XBEE_APIFRAMEINDEX_TYPE 3
/****************************************************************************
* Public Types
****************************************************************************/
/* Enumeration of Modem Status values */
enum xbee_modemstatus_e
{
XBEE_MODEMSTATUS_HARDRESET = 0,
XBEE_MODEMSTATUS_WATCHDOGRESET,
XBEE_MODEMSTATUS_ASSOCIATED,
XBEE_MODEMSTATUS_NONETWORK,
XBEE_MODEMSTATUS_COORD,
XBEE_MODEMSTATUS_VOLTAGETOOHIGH,
};
enum xbee_response_e
{
XBEE_RESP_MODEMSTATUS,
XBEE_RESP_AT_FIRMWAREVERSION,
XBEE_RESP_AT_HARDWAREVERSION,
XBEE_RESP_AT_NETWORKID,
XBEE_RESP_AT_SERIALHIGH,
XBEE_RESP_AT_SERIALLOW,
XBEE_RESP_AT_SOURCEADDR,
XBEE_RESP_AT_CHAN,
/* Skip some allow for new AT commands */
};
struct xbee_respwaiter_s
{
FAR struct xbee_respwaiter_s *flink;
sem_t sem;
enum xbee_response_e resp_id;
};
/* An XBee device instance */
struct xbee_priv_s
{
/* Low-level MCU-specific support */
FAR const struct xbee_lower_s *lower;
FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
FAR struct xbee_maccb_s *cb; /* Head of a list of XBee MAC callbacks */
FAR struct iob_s *rx_apiframes; /* List of incoming API frames to process */
struct work_s attnwork; /* For deferring interrupt work to work queue */
sem_t exclsem; /* Exclusive access to this struct */
WDOG_ID assocwd; /* Association watchdog */
struct work_s assocwork; /* For polling for association status */
volatile bool attn_latched; /* Latched state of ATTN */
sq_queue_t waiter_queue; /* List of response waiters */
sq_queue_t tx_queue; /* List of pending TX requests */
uint8_t frameid; /* For differentiating AT request/response */
uint16_t firmwareversion;
/************* Fields related to addressing and coordinator *****************/
/* Holds all address information (Extended, Short, and PAN ID) for the MAC. */
struct ieee802154_addr_s addr;
struct ieee802154_pandesc_s pandesc;
/******************* Fields related to notifications ************************/
/* Pre-allocated notifications to be passed to the registered callback. These
* need to be freed by the application using xbee_xxxxnotif_free when
* the callee layer is finished with it's use.
*/
FAR struct xbee_notif_s *notif_free;
struct xbee_notif_s notif_pool[CONFIG_XBEE_NNOTIF];
sem_t notif_sem;
uint8_t nclients;
/******************* Fields related to data indications *********************/
/* Pre-allocated notifications to be passed to the registered callback. These
* need to be freed by the application using xbee_dataind_free when
* the callee layer is finished with it's use.
*/
FAR struct xbee_dataind_s *dataind_free;
struct xbee_dataind_s dataind_pool[CONFIG_XBEE_NDATAIND];
sem_t dataind_sem;
/****************** Uncategorized MAC PIB attributes ***********************/
/* What type of device is this node acting as */
enum ieee802154_devmode_e devmode : 2;
/****************** PHY attributes ***********************/
uint8_t chan;
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Inline Functions
****************************************************************************/
#define xbee_givesem(s) sem_post(s)
static inline int xbee_takesem(sem_t *sem, bool allowinterrupt)
{
int ret;
do
{
/* Take a count from the semaphore, possibly waiting */
ret = sem_wait(sem);
if (ret < 0)
{
/* EINTR is the only error that we expect */
DEBUGASSERT(get_errno() == EINTR);
if (allowinterrupt)
{
return -EINTR;
}
}
}
while (ret != OK);
return OK;
}
#ifdef CONFIG_XBEE_LOCK_VERBOSE
#define xbee_unlock(dev) \
xbee_givesem(&dev->exclsem); \
wlinfo("MAC unlocked\n");
#else
#define xbee_unlock(dev) \
xbee_givesem(&dev->exclsem);
#endif
#define xbee_lock(dev, allowinterrupt) \
xbee_lockpriv(dev, allowinterrupt, __FUNCTION__)
static inline int xbee_lockpriv(FAR struct xbee_priv_s *dev,
bool allowinterrupt, FAR const char *funcname)
{
int ret;
#ifdef CONFIG_XBEE_LOCK_VERBOSE
wlinfo("Locking MAC: %s\n", funcname);
#endif
ret = xbee_takesem(&dev->exclsem, allowinterrupt);
if (ret < 0)
{
wlwarn("Failed to lock MAC\n");
}
else
{
#ifdef CONFIG_XBEE_LOCK_VERBOSE
wlinfo("MAC locked\n");
#endif
}
return ret;
}
/****************************************************************************
* Name: xbee_register_respwaiter
*
* Description:
* Register a respone waiter
*
****************************************************************************/
static inline void xbee_register_respwaiter(FAR struct xbee_priv_s *priv,
FAR struct xbee_respwaiter_s *waiter)
{
sq_addlast((sq_entry_t *)waiter, &priv->waiter_queue);
}
/****************************************************************************
* Name: xbee_unregister_respwaiter
*
* Description:
* Unregister a respone waiter
*
****************************************************************************/
static inline void xbee_unregister_respwaiter(FAR struct xbee_priv_s *priv,
FAR struct xbee_respwaiter_s *waiter)
{
sq_rem((sq_entry_t *)waiter, &priv->waiter_queue);
}
/****************************************************************************
* Name: xbee_notify_respwaiter
*
* Description:
* Check to see if there are any respwaiters waiting for this response type.
* If so, signal them.
*
****************************************************************************/
static inline void xbee_notify_respwaiter(FAR struct xbee_priv_s *priv,
enum xbee_response_e resp_id)
{
FAR struct xbee_respwaiter_s *waiter;
waiter = (FAR struct xbee_respwaiter_s *)sq_peek(&priv->waiter_queue);
while (waiter != NULL)
{
if (waiter->resp_id == resp_id)
{
sem_post(&waiter->sem);
}
waiter = (FAR struct xbee_respwaiter_s *)sq_next((FAR sq_entry_t *)waiter);
}
}
/****************************************************************************
* Name: xbee_next_frameid
*
* Description:
* Increment the frame id. This is used to coordinate TX requests with subsequent
* TX status frames received by the XBee device. We must skip value 0 since
* that value is to tell the XBee not to provide a status response.
*
****************************************************************************/
static inline uint8_t xbee_next_frameid(FAR struct xbee_priv_s *priv)
{
priv->frameid++;
if (priv->frameid == 0)
{
priv->frameid = 1;
}
return priv->frameid;
}
/****************************************************************************
* Name: xbee_insert_checksum
*
* Description:
* Insert checksum into outbound API frame.
*
* Parameters:
* frame - pointer to the frame data
* framelen - size of the overall frame. NOT the data length field
*
****************************************************************************/
static inline void xbee_insert_checksum(FAR uint8_t *frame, uint16_t framelen)
{
int i;
uint8_t checksum = 0;
DEBUGASSERT(framelen > XBEE_APIFRAME_OVERHEAD);
/* Skip the start byte and frame length */
for (i = 3; i < framelen - 1; i++)
{
checksum += frame[i];
}
frame[framelen - 1] = 0xFF - checksum;
}
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: xbee_send_apiframe
*
* Description:
* Write an api frame over SPI
*
****************************************************************************/
void xbee_send_apiframe(FAR struct xbee_priv_s *priv,
FAR const uint8_t *frame, uint16_t framelen);
/****************************************************************************
* Name: xbee_at_query
*
* Description:
* Helper function to query a AT Command value.
*
****************************************************************************/
void xbee_at_query(FAR struct xbee_priv_s *priv, FAR const char *atcommand);
/****************************************************************************
* Name: xbee_query_firmwareversion
*
* Description:
* Sends API frame with AT command request in order to get the firmware version
* from the device.
*
****************************************************************************/
void xbee_query_firmwareversion(FAR struct xbee_priv_s *priv);
/****************************************************************************
* Name: xbee_query_panid
*
* Description:
* Sends API frame with AT command request in order to get the PAN ID
* (Network ID) from the device.
*
****************************************************************************/
void xbee_query_panid(FAR struct xbee_priv_s *priv);
/****************************************************************************
* Name: xbee_query_eaddr
*
* Description:
* Sends API frame with AT command request in order to get the IEEE 802.15.4
* Extended Address. (Serial Number) from the device.
*
****************************************************************************/
void xbee_query_eaddr(FAR struct xbee_priv_s *priv);
/****************************************************************************
* Name: xbee_query_saddr
*
* Description:
* Sends API frame with AT command request in order to get the
* Short Address. (Source Address (MY)) from the device.
*
****************************************************************************/
void xbee_query_saddr(FAR struct xbee_priv_s *priv);
/****************************************************************************
* Name: xbee_query_chan
*
* Description:
* Sends API frame with AT command request in order to get the RF Channel
* (Operating Channel) from the device.
*
****************************************************************************/
void xbee_query_chan(FAR struct xbee_priv_s *priv);
/****************************************************************************
* Name: xbee_query_assoc
*
* Description:
* Sends API frame with AT command request in order to get the association
* status (Association Indication) of the device
*
****************************************************************************/
void xbee_query_assoc(FAR struct xbee_priv_s *priv);
/****************************************************************************
* Name: xbee_set_panid
*
* Description:
* Sends API frame with AT command request in order to set the PAN ID
* (Network ID) of the device.
*
****************************************************************************/
void xbee_set_panid(FAR struct xbee_priv_s *priv, FAR const uint8_t *panid);
/****************************************************************************
* Name: xbee_set_saddr
*
* Description:
* Sends API frame with AT command request in order to set the Short Address
* (Source Address (MY)) of the device
*
****************************************************************************/
void xbee_set_saddr(FAR struct xbee_priv_s *priv, FAR const uint8_t *saddr);
/****************************************************************************
* Name: xbee_set_chan
*
* Description:
* Sends API frame with AT command request in order to set the RF channel
* (Operatin Channel) of the device.
*
****************************************************************************/
void xbee_set_chan(FAR struct xbee_priv_s *priv, uint8_t chan);
/****************************************************************************
* Name: xbee_set_epassocflags
*
* Description:
* Set flags in 'A1' command register to determine how endpoint behaves
* with regards to association.
*
****************************************************************************/
void xbee_set_epassocflags(FAR struct xbee_priv_s *priv, uint8_t flags);
/****************************************************************************
* Name: xbee_set_coordassocflags
*
* Description:
* Set flags in 'AT' command register to determine how coordinator behaves
* with regards to association.
*
****************************************************************************/
void xbee_set_coordassocflags(FAR struct xbee_priv_s *priv, uint8_t flags);
/****************************************************************************
* Name: xbee_set_sleepperiod
*
* Description:
* Set Cyclic Sleep Period using 'SP' AT command.
*
****************************************************************************/
void xbee_set_sleepperiod(FAR struct xbee_priv_s *priv, uint16_t period);
/****************************************************************************
* Name: xbee_enable_coord
*
* Description:
* Enables/Disables coordinator mode using 'CE' command
*
****************************************************************************/
void xbee_enable_coord(FAR struct xbee_priv_s *priv, bool enable);
/****************************************************************************
* Name: xbee_regdump
*
* Description:
* Perform a series of queries updating struct and printing settings to SYSLOG.
*
****************************************************************************/
void xbee_regdump(FAR struct xbee_priv_s *priv);
#endif /* __DRIVERS_WIRELESS_IEEE802154_XBEE_H */

View File

@ -0,0 +1,202 @@
/****************************************************************************
* drivers/wireless/ieee802154/xbee/xbee_dataind.c
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <string.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/xbee.h>
#include "xbee.h"
#include "xbee_mac.h"
#include "xbee_notif.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: xbee_dataind_free
*
* Description:
* When the XBee driver calls the registered rxframe function, it passes a
* reference to a ieee802154_data_ind_s structure. This structure needs to be
* freed after the handler is done using it.
*
****************************************************************************/
void xbee_dataind_free(XBEEHANDLE xbee, FAR struct ieee802154_data_ind_s *dataind)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
FAR struct xbee_dataind_s *privind = (FAR struct xbee_dataind_s *)dataind;
xbee_lock(priv, false);
privind->flink = priv->dataind_free;
priv->dataind_free = privind;
xbee_givesem(&priv->dataind_sem);
xbee_unlock(priv);
}
/****************************************************************************
* Name: xbee_datatindpool_init
*
* Description:
* This function initializes the data indication structure pool. It allows the
* XBee driver to pass received frames with meta data to the callee, where they
* can free them when the calle is done using them, saving copying the data
* when passing.
*
****************************************************************************/
void xbee_dataindpool_init(FAR struct xbee_priv_s *priv)
{
FAR struct xbee_dataind_s *pool = priv->dataind_pool;
int remaining = CONFIG_XBEE_NDATAIND;
priv->dataind_free = NULL;
while (remaining > 0)
{
FAR struct xbee_dataind_s *dataind = pool;
/* Add the next meta data structure from the pool to the list of
* general structures.
*/
dataind->flink = priv->dataind_free;
priv->dataind_free = dataind;
/* Set up for the next structure from the pool */
pool++;
remaining--;
}
sem_init(&priv->dataind_sem, 0, CONFIG_XBEE_NDATAIND);
}
/****************************************************************************
* Name: xbee_dataind_alloc
*
* Description:
* This function allocates a free data indication structure from the free list
* to be used for passing to the registered rxframe callback. The callee software
* is responsible for freeing the data indication structure after it is done using
* it via xbee_data_ind_sfree.
*
* Assumptions:
* priv XBee struct is locked when calling.
*
* Notes:
* If any of the semaphore waits inside this function get interrupted, the
* function will release the MAC layer. If this function returns -EINTR, the
* calling code should NOT release the MAC semaphore.
*
****************************************************************************/
int xbee_dataind_alloc(FAR struct xbee_priv_s *priv,
FAR struct ieee802154_data_ind_s **dataind,
bool allow_interrupt)
{
int ret;
FAR struct xbee_dataind_s *privind;
/* Try and take a count from the semaphore. If this succeeds, we have
* "reserved" the structure, but still need to unlink it from the free list.
* The MAC is already locked, so there shouldn't be any other conflicting calls
*/
ret = sem_trywait(&priv->dataind_sem);
if (ret == OK)
{
privind = priv->dataind_free;
priv->dataind_free = privind->flink;
}
else
{
wlinfo("waiting for dataind to be free\n");
/* Unlock XBee driver so that other work can be done to free a data indication */
xbee_unlock(priv);
/* Take a count from the indication semaphore, waiting if necessary. We
* only return from here with an error if we are allowing interruptions
* and we received a signal */
ret = xbee_takesem(&priv->dataind_sem, allow_interrupt);
if (ret < 0)
{
/* MAC sem is already released */
return -EINTR;
}
/* If we've taken a count from the semaphore, we have "reserved" the struct
* but now we need to pop it off of the free list. We need to re-lock the
* MAC in order to ensure this happens correctly.
*/
ret = xbee_lock(priv, allow_interrupt);
if (ret < 0)
{
xbee_givesem(&priv->dataind_sem);
return -EINTR;
}
/* We can now safely unlink the next free structure from the free list */
privind = priv->dataind_free;
priv->dataind_free = privind->flink;
wlinfo("dataind allocated\n");
}
*dataind = (FAR struct ieee802154_data_ind_s *)privind;
return OK;
}

View File

@ -0,0 +1,77 @@
/****************************************************************************
* drivers/wireless/ieee802154/xbee/xbee_dataind.h
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
*
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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 __DRIVERS_WIRELESS_IEEE802154_XBEE_DATAIND_H
#define __DRIVERS_WIRELESS_IEEE802154_XBEE_DATAIND_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
/****************************************************************************
* Private Types
****************************************************************************/
/* Extend the public ieee802154_data_ind_s to include a private forward link to
* support a list to handle allocation
*/
struct xbee_dataind_s
{
struct ieee802154_data_ind_s pub; /* Publically visible structure */
FAR struct xbee_dataind_s *flink; /* Supports a singly linked list */
};
/****************************************************************************
* Function Prototypes
****************************************************************************/
struct xbee_priv_s; /* Forward Reference */
void xbee_dataindpool_init(FAR struct xbee_priv_s *priv);
int xbee_dataind_alloc(FAR struct xbee_priv_s *priv,
FAR struct ieee802154_data_ind_s **dataind,
bool allow_interrupt);
#endif /* __DRIVERS_WIRELESS_IEEE802154_XBEE_DATAIND_H */

View File

@ -0,0 +1,179 @@
/****************************************************************************
* drivers/wireless/xbee/drivers/xbee_ioctl.c
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
*
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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <string.h>
#include <nuttx/fs/ioctl.h>
#include <xbee.h>
#include <xbee_mac.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: xbee_ioctl
*
* Description:
* Handle MAC and radio IOCTL commands directed to the MAC.
*
* Parameters:
* mac - Reference to the XBee driver state structure
* cmd - The IOCTL command
* arg - The argument for the IOCTL command
*
* Returned Value:
* OK on success; Negated errno on failure.
*
****************************************************************************/
int xbee_ioctl(XBEEHANDLE xbee, int cmd, unsigned long arg)
{
int ret = -EINVAL;
FAR union ieee802154_macarg_u *macarg =
(FAR union ieee802154_macarg_u *)((uintptr_t)arg);
DEBUGASSERT(xbee != NULL);
/* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */
if (_MAC802154IOCVALID(cmd))
{
/* Handle the MAC IOCTL command */
switch (cmd)
{
case MAC802154IOC_MLME_GET_REQUEST:
{
ret = xbee_req_get(xbee, macarg->getreq.attr,
&macarg->getreq.attrval);
}
break;
case MAC802154IOC_MLME_SET_REQUEST:
{
ret = xbee_req_set(xbee, macarg->setreq.attr,
&macarg->setreq.attrval);
}
break;
case MAC802154IOC_MLME_START_REQUEST:
{
ret = xbee_req_start(xbee, &macarg->startreq);
}
break;
case MAC802154IOC_MLME_ASSOC_REQUEST:
{
ret = xbee_req_associate(xbee, &macarg->assocreq);
}
break;
case MAC802154IOC_MLME_RESET_REQUEST:
{
ret = xbee_req_reset(xbee, macarg->resetreq.resetattr);
}
break;
#if 0
case MAC802154IOC_MLME_ASSOC_RESPONSE:
{
ret = xbee_resp_associate(xbee, &macarg->assocresp);
}
break;
case MAC802154IOC_MLME_DISASSOC_REQUEST:
{
ret = xbee_req_disassociate(xbee, &macarg->disassocreq);
}
break;
case MAC802154IOC_MLME_RXENABLE_REQUEST:
{
ret = xbee_req_rxenable(xbee, &macarg->rxenabreq);
}
break;
case MAC802154IOC_MLME_SCAN_REQUEST:
{
ret = xbee_req_scan(xbee, &macarg->scanreq);
}
break;
case MAC802154IOC_MLME_POLL_REQUEST:
{
ret = xbee_req_poll(xbee, &macarg->pollreq);
}
break;
#endif
default:
wlerr("ERROR: Unrecognized cmd: %d\n", cmd);
ret = -ENOTTY;
break;
}
}
return ret;
}

View File

@ -0,0 +1,601 @@
/****************************************************************************
* drivers/wireless/xbee/drivers/xbee_mac.c
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <errno.h>
#include <nuttx/mm/iob.h>
#include "xbee.h"
#include "xbee_mac.h"
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/xbee.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define XBEE_ASSOC_POLLDELAY 100
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static void xbee_assoctimer(int argc, uint32_t arg, ...);
static void xbee_assocworker(FAR void *arg);
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: xbee_assoctimer
*
* Description:
* This function is used to schedule * an associatioin indication poll. When
* association first gets triggered, a watchdog timer is started. This function
* is called when it expires. The watchdog timer is scheduled again until
* the association is either successful or fails.
*
* Parameters:
* argc - The number of available arguments
* arg - The first argument
*
* Returned Value:
* None
*
* Assumptions:
*
****************************************************************************/
static void xbee_assoctimer(int argc, uint32_t arg, ...)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)arg;
int ret;
/* In complex environments, we cannot do SPI transfers from the timout
* handler because semaphores are probably used to lock the SPI bus. In
* this case, we will defer processing to the worker thread. This is also
* much kinder in the use of system resources and is, therefore, probably
* a good thing to do in any event.
*/
DEBUGASSERT(priv && work_available(&priv->assocwork));
/* Notice that poll watchdog is not active so further poll timeouts can
* occur until we restart the poll timeout watchdog.
*/
ret = work_queue(HPWORK, &priv->assocwork, xbee_assocworker, (FAR void *)priv, 0);
(void)ret;
DEBUGASSERT(ret == OK);
}
/****************************************************************************
* Name: xbee_assocworker
*
* Description:
* Poll the device for the assosciation status. This function is indirectly
* scheduled rom xbee_req_associate in order to poll the device for association
* progress.
*
* Parameters:
* arg - The reference to the driver structure (cast to void*)
*
* Returned Value:
* None
*
* Assumptions:
*
****************************************************************************/
static void xbee_assocworker(FAR void *arg)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)arg;
xbee_at_query(priv, "AI");
(void)wd_start(priv->assocwd, XBEE_ASSOC_POLLDELAY, xbee_assoctimer, 1, (wdparm_t)arg);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: xbee_bind
*
* Description:
* Bind the MAC callback table to the XBee driver.
*
* Parameters:
* xbee - Reference to the XBee driver structure
* cb - MAC callback operations
*
* Returned Value:
* OK on success; Negated errno on failure.
*
****************************************************************************/
int xbee_bind(XBEEHANDLE xbee, FAR struct xbee_maccb_s *cb)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
FAR struct xbee_maccb_s *next;
FAR struct xbee_maccb_s *prev;
/* Add the MAC client callback structure to the list of MAC callbacks in
* priority order.
*
* Search the list to find the location to insert the new instance.
* The list is maintained in descending priority order.
*/
for (prev = NULL, next = priv->cb;
(next != NULL && cb->prio <= next->prio);
prev = next, next = next->flink);
/* Add the instance to the spot found in the list. Check if the instance
* goes at the head of the list.
*/
if (prev == NULL)
{
cb->flink = priv->cb; /* May be NULL */
priv->cb = cb;
}
/* No.. the instance goes between prev and next */
else
{
cb->flink = next; /* May be NULL */
prev->flink = cb;
}
/* Keep track of the number of clients requesting notification */
if (cb->notify != NULL)
{
priv->nclients++;
}
return OK;
}
/****************************************************************************
* Name: xbee_get_mhrlen
*
* Description:
* Calculate the MAC header length given the frame meta-data. For the XBee,
* we use the header to store the entire API frame for the TX request. The
* size we need is fixed based on the address mode we are using as it changes
* which API frame we need to issue.
*
****************************************************************************/
int xbee_get_mhrlen(XBEEHANDLE xbee, FAR const struct ieee802154_frame_meta_s *meta)
{
int ret = 9; /* Smallest possible header size */
/* We assume that the XBee is configured with application header on but
* encryption not on.
*/
ret += 2;
if (meta->srcmode == IEEE802154_ADDRMODE_EXTENDED)
{
ret += 6;
}
if (meta->destaddr.mode == IEEE802154_ADDRMODE_EXTENDED)
{
ret += 6;
}
return ret;
}
/****************************************************************************
* Name: xbee_req_data
*
* Description:
* The MCPS-DATA.request primitive requests the transfer of a data SPDU
* (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
*
****************************************************************************/
int xbee_req_data(XBEEHANDLE xbee,
FAR const struct ieee802154_frame_meta_s *meta,
FAR struct iob_s *frame)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
int index;
uint16_t apiframelen;
uint8_t frametype;
int prevoffs = frame->io_offset;
/* Figure out how much room we need to place the API frame header */
if (meta->destaddr.mode == IEEE802154_ADDRMODE_EXTENDED)
{
DEBUGASSERT(frame->io_offset >= 14);
frame->io_offset -= 14;
frametype = XBEE_APIFRAME_TXREQ_EADDR;
}
else if (meta->destaddr.mode == IEEE802154_ADDRMODE_SHORT)
{
DEBUGASSERT(frame->io_offset >= 8);
frame->io_offset -= 8;
frametype = XBEE_APIFRAME_TXREQ_SADDR;
}
else
{
return -EINVAL;
}
index = frame->io_offset;
apiframelen = (frame->io_len - frame->io_offset - 3);
frame->io_data[index++] = XBEE_STARTBYTE;
frame->io_data[index++] = ((apiframelen >> 8) & 0xFF);
frame->io_data[index++] = (apiframelen & 0xFF);
frame->io_data[index++] = frametype;
frame->io_data[index++] = xbee_next_frameid(priv);
if (meta->destaddr.mode == IEEE802154_ADDRMODE_EXTENDED)
{
frame->io_data[index++] = meta->destaddr.eaddr[7];
frame->io_data[index++] = meta->destaddr.eaddr[6];
frame->io_data[index++] = meta->destaddr.eaddr[5];
frame->io_data[index++] = meta->destaddr.eaddr[4];
frame->io_data[index++] = meta->destaddr.eaddr[3];
frame->io_data[index++] = meta->destaddr.eaddr[2];
frame->io_data[index++] = meta->destaddr.eaddr[1];
frame->io_data[index++] = meta->destaddr.eaddr[0];
}
else
{
frame->io_data[index++] = meta->destaddr.saddr[1];
frame->io_data[index++] = meta->destaddr.saddr[0];
}
frame->io_data[index++] = 0; /* Options byte. Currently we do not support anything here */
DEBUGASSERT(index == prevoffs);
/* Increment io_len by 1 to account for checksum */
frame->io_len++;
xbee_insert_checksum(&frame->io_data[frame->io_offset],
(frame->io_len - frame->io_offset));
xbee_send_apiframe(priv, &frame->io_data[frame->io_offset],
(frame->io_len - frame->io_offset));
iob_free(frame);
return OK;
}
/****************************************************************************
* Name: xbee_req_get
*
* Description:
* The MLME-GET.request primitive requests information about a given PIB
* attribute.
*
* NOTE: The standard specifies that the attribute value should be returned
* via the asynchronous MLME-GET.confirm primitve. However, in our
* implementation, we synchronously return the value immediately.Therefore, we
* merge the functionality of the MLME-GET.request and MLME-GET.confirm
* primitives together.
*
****************************************************************************/
int xbee_req_get(XBEEHANDLE xbee, enum ieee802154_attr_e attr,
FAR union ieee802154_attr_u *attrval)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
int ret = IEEE802154_STATUS_SUCCESS;
switch (attr)
{
case IEEE802154_ATTR_MAC_PANID:
{
xbee_query_panid(priv);
IEEE802154_PANIDCOPY(attrval->mac.panid, priv->addr.panid);
}
break;
case IEEE802154_ATTR_MAC_SADDR:
{
xbee_query_saddr(priv);
IEEE802154_SADDRCOPY(attrval->mac.saddr, priv->addr.saddr);
}
break;
case IEEE802154_ATTR_MAC_EADDR:
{
xbee_query_eaddr(priv);
IEEE802154_EADDRCOPY(attrval->mac.eaddr, priv->addr.eaddr);
}
break;
case IEEE802154_ATTR_MAC_COORD_SADDR:
{
IEEE802154_SADDRCOPY(attrval->mac.coordsaddr, priv->pandesc.coordaddr.saddr);
}
break;
case IEEE802154_ATTR_MAC_COORD_EADDR:
{
IEEE802154_EADDRCOPY(attrval->mac.coordeaddr, priv->pandesc.coordaddr.eaddr);
}
break;
case IEEE802154_ATTR_MAC_DEVMODE:
{
attrval->mac.devmode = priv->devmode;
}
break;
case IEEE802154_ATTR_PHY_CHAN:
{
xbee_query_chan(priv);
attrval->phy.chan = priv->chan;
}
break;
case IEEE802154_ATTR_RADIO_REGDUMP:
{
xbee_regdump(priv);
}
break;
default:
{
wlwarn("Unsupported attribute\n");
ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE;
}
break;
}
return ret;
}
/****************************************************************************
* Name: xbee_req_set
*
* Description:
* The MLME-SET.request primitive attempts to write the given value to the
* indicated MAC PIB attribute.
*
* NOTE: The standard specifies that confirmation should be indicated via
* the asynchronous MLME-SET.confirm primitve. However, in our implementation
* we synchronously return the status from the request. Therefore, we do merge
* the functionality of the MLME-SET.request and MLME-SET.confirm primitives
* together.
*
****************************************************************************/
int xbee_req_set(XBEEHANDLE xbee, enum ieee802154_attr_e attr,
FAR const union ieee802154_attr_u *attrval)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
int ret = IEEE802154_STATUS_SUCCESS;
switch (attr)
{
case IEEE802154_ATTR_MAC_PANID:
{
xbee_set_panid(priv, attrval->mac.panid);
}
break;
case IEEE802154_ATTR_MAC_EADDR:
{
ret = IEEE802154_STATUS_DENIED;
}
break;
case IEEE802154_ATTR_MAC_SADDR:
{
xbee_set_saddr(priv, attrval->mac.saddr);
}
break;
case IEEE802154_ATTR_PHY_CHAN:
{
xbee_set_chan(priv, attrval->phy.chan);
}
break;
case IEEE802154_ATTR_MAC_ASSOCIATION_PERMIT:
{
if (attrval->mac.assocpermit)
{
xbee_set_coordassocflags(priv, XBEE_COORDASSOCFLAGS_ALLOWASSOC);
}
else
{
xbee_set_coordassocflags(priv, 0);
}
}
break;
#if 0
case IEEE802154_ATTR_MAC_COORD_SADDR:
{
xbee_set_coordsaddr(priv, attrval->mac.coordsaddr);
}
break;
case IEEE802154_ATTR_MAC_COORD_EADDR:
{
xbee_set_coordeaddr(priv, attrval->mac.coordeaddr);
}
break;
case IEEE802154_ATTR_MAC_RESPONSE_WAIT_TIME:
{
priv->resp_waittime = attrval->mac.resp_waittime;
}
case IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE:
{
xbee_setrxonidle(priv, attrval->mac.rxonidle);
}
#endif
default:
{
wlwarn("Unsupported attribute\n");
ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE;
}
break;
}
return ret;
}
/****************************************************************************
* Name: xbee_req_start
*
* Description:
* The MLME-START.request primitive makes a request for the device to start
* acting as a coordinator. The XBee modules do not support beacon-enabled
* networking!
*
****************************************************************************/
int xbee_req_start(XBEEHANDLE xbee, FAR struct ieee802154_start_req_s *req)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
if (req->beaconorder != 15)
{
wlwarn("xbee: beacon-enabled networks not supported\n");
return -EINVAL;
}
xbee_set_panid(priv, req->panid);
xbee_set_chan(priv, req->chan);
xbee_enable_coord(priv, true);
xbee_set_sleepperiod(priv, 0);
return OK;
}
/****************************************************************************
* Name: xbee_req_associate
*
* Description:
* The MLME-ASSOCIATE.request primitive allows a device to request an
* association with a coordinator.
*
* On receipt of the MLME-ASSOCIATE.request primitive, the MLME of an
* unassociated device first updates the appropriate PHY and MAC PIB
* attributes, as described in 5.1.3.1, and then generates an association
* request command, as defined in 5.3.1 [1] pg.80
*
****************************************************************************/
int xbee_req_associate(XBEEHANDLE xbee, FAR struct ieee802154_assoc_req_s *req)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
if (req->coordaddr.mode == IEEE802154_ADDRMODE_NONE)
{
return -EINVAL;
}
xbee_enable_coord(priv, false);
xbee_set_panid(priv, req->coordaddr.panid);
xbee_set_chan(priv, req->chan);
xbee_set_epassocflags(priv, XBEE_EPASSOCFLAGS_AUTOASSOC);
/* In order to track the association status, we must poll the device for
* an update.
*/
return wd_start(priv->assocwd, XBEE_ASSOC_POLLDELAY, xbee_assoctimer, 1, (wdparm_t)priv);
}
/****************************************************************************
* Name: xbee_req_reset
*
* Description:
* The MLME-RESET.request primitive allows the next higher layer to request
* that the MLME performs a reset operation.
*
* Input Parameters:
* xbee - Handle to the XBee instance
* resetattr - Whether or not to reset the MAC PIB attributes to defaults
*
****************************************************************************/
int xbee_req_reset(XBEEHANDLE xbee, bool resetattr)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
/* Reset the XBee radio */
priv->lower->reset(priv->lower);
if (resetattr)
{
xbee_set_panid(priv, IEEE802154_PANID_UNSPEC);
xbee_set_saddr(priv, IEEE802154_SADDR_UNSPEC);
xbee_enable_coord(priv, false);
xbee_set_epassocflags(priv, 0);
xbee_set_coordassocflags(priv, 0);
}
return OK;
}

View File

@ -0,0 +1,262 @@
/****************************************************************************
* drivers/wireless/ieee802154/xbee/xbee_mac.h
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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 __DRIVERS_WIRELESS_IEEE802154_XBEE_MAC_H
#define __DRIVERS_WIRELESS_IEEE802154_XBEE_MAC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <semaphore.h>
#include <nuttx/wqueue.h>
#include <nuttx/spi/spi.h>
#include <nuttx/wireless/ieee802154/xbee.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
/* Callback operations to notify the next highest layer of various
* asynchronous events, usually triggered by some previous request or
* response invoked by the upper layer.
*/
struct xbee_maccb_s
{
FAR struct xbee_maccb_s *flink; /* Implements a singly linked list */
uint8_t prio; /* RX frame callback priority */
/* Callback methods */
CODE void (*notify)(FAR struct xbee_maccb_s *maccb,
FAR struct ieee802154_notif_s *notif);
CODE int (*rxframe)(FAR struct xbee_maccb_s *maccb,
FAR struct ieee802154_data_ind_s *ind);
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: xbee_bind
*
* Description:
* Bind the XBee callback table to the MAC state.
*
* Parameters:
* xbee - Reference to the XBee driver state structure
* cb - XBee callback operations
*
* Returned Value:
* OK on success; Negated errno on failure.
*
****************************************************************************/
int xbee_bind(XBEEHANDLE xbee, FAR struct xbee_maccb_s *cb);
/****************************************************************************
* Name: xbee_ioctl
*
* Description:
* Handle MAC and radio IOCTL commands directed to the XBee device.
*
* Parameters:
* mac - Reference to the Xbee driver state structure
* cmd - The IOCTL command
* arg - The argument for the IOCTL command
*
* Returned Value:
* OK on success; Negated errno on failure.
*
****************************************************************************/
int xbee_ioctl(XBEEHANDLE xbee, int cmd, unsigned long arg);
/****************************************************************************
* MAC Interface Operations
****************************************************************************/
/****************************************************************************
* Name: xbee_get_mhrlen
*
* Description:
* Calculate the MAC header length given the frame meta-data. For the XBee,
* we use the header to store the entire API frame for the TX request. The
* size we need is fixed based on the address mode we are using as it changes
* which API frame we need to issue.
*
****************************************************************************/
int xbee_get_mhrlen(XBEEHANDLE xbee, FAR const struct ieee802154_frame_meta_s *meta);
/****************************************************************************
* Name: xbee_req_data
*
* Description:
* The MCPS-DATA.request primitive requests the transfer of a data SPDU
* (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
* Confirmation is returned via the
* struct xbee_maccb_s->conf_data callback.
*
****************************************************************************/
int xbee_req_data(XBEEHANDLE xbee, FAR const struct ieee802154_frame_meta_s *meta,
FAR struct iob_s *frame);
/****************************************************************************
* Name: xbee_req_get
*
* Description:
* The MLME-GET.request primitive requests information about a given PIB
* attribute.
*
* NOTE: The standard specifies that the attribute value should be returned
* via the asynchronous MLME-GET.confirm primitve. However, in our
* implementation, we synchronously return the value immediately.Therefore, we
* merge the functionality of the MLME-GET.request and MLME-GET.confirm
* primitives together.
*
****************************************************************************/
int xbee_req_get(XBEEHANDLE xbee, enum ieee802154_attr_e attr,
FAR union ieee802154_attr_u *attrval);
/****************************************************************************
* Name: xbee_req_set
*
* Description:
* The MLME-SET.request primitive attempts to write the given value to the
* indicated MAC PIB attribute.
*
* NOTE: The standard specifies that confirmation should be indicated via
* the asynchronous MLME-SET.confirm primitve. However, in our implementation
* we synchronously return the status from the request. Therefore, we do merge
* the functionality of the MLME-SET.request and MLME-SET.confirm primitives
* together.
*
****************************************************************************/
int xbee_req_set(XBEEHANDLE xbee, enum ieee802154_attr_e attr,
FAR const union ieee802154_attr_u *attrval);
/****************************************************************************
* Name: xbee_req_start
*
* Description:
* The MLME-START.request primitive makes a request for the device to start
* acting as a coordinator. The XBee modules do not support beacon-enabled
* networking!
*
****************************************************************************/
int xbee_req_start(XBEEHANDLE xbee, FAR struct ieee802154_start_req_s *req);
/****************************************************************************
* Name: xbee_req_associate
*
* Description:
* The MLME-ASSOCIATE.request primitive allows a device to request an
* association with a coordinator.
*
* On receipt of the MLME-ASSOCIATE.request primitive, the MLME of an
* unassociated device first updates the appropriate PHY and MAC PIB
* attributes, as described in 5.1.3.1, and then generates an association
* request command, as defined in 5.3.1 [1] pg.80
*
****************************************************************************/
int xbee_req_associate(XBEEHANDLE xbee, FAR struct ieee802154_assoc_req_s *req);
/****************************************************************************
* Name: xbee_req_reset
*
* Description:
* The MLME-RESET.request primitive allows the next higher layer to request
* that the MLME performs a reset operation.
*
* Input Parameters:
* xbee - Handle to the XBee instance
* resetattr - Whether or not to reset the MAC PIB attributes to defaults
*
****************************************************************************/
int xbee_req_reset(XBEEHANDLE xbee, bool resetattr);
/****************************************************************************
* Name: xbee_notif_free
*
* Description:
* When the XBee driver calls the registered callback, it passes a reference
* to a ieee802154_notif_s structure. This structure needs to be freed
* after the callback handler is done using it.
*
****************************************************************************/
void xbee_notif_free(XBEEHANDLE mac, FAR struct ieee802154_notif_s *notif);
/****************************************************************************
* Name: xbee_dataind_free
*
* Description:
* When the XBee driver calls the registered callback, it passes a reference
* to a ieee802154_data_ind_s structure. This structure needs to be freed
* after the callback handler is done using it.
*
****************************************************************************/
void xbee_dataind_free(XBEEHANDLE mac, FAR struct ieee802154_data_ind_s *dataind);
#endif /* __DRIVERS_WIRELESS_IEEE802154_XBEE_MAC_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,283 @@
/****************************************************************************
* drivers/wireless/ieee802154/xbee/xbee_notif.c
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <string.h>
#include "xbee.h"
#include "xbee_mac.h"
#include "xbee_notif.h"
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/xbee.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: xbee_notif_free
*
* Description:
* When the XBee driver calls the registered callback, it passes a reference
* to a ieee802154_notif_s structure. This structure needs to be freed
* after the callback handler is done using it.
*
****************************************************************************/
void xbee_notif_free(XBEEHANDLE xbee, FAR struct ieee802154_notif_s *notif)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)xbee;
/* Lock the MAC */
xbee_lock(priv, false);
/* Call the internal helper function to free the notification */
xbee_notif_free_locked(priv, notif);
/* Unlock the MAC */
xbee_unlock(priv)
}
/****************************************************************************
* Internal MAC Functions
****************************************************************************/
/****************************************************************************
* Name: xbee_notifpool_init
*
* Description:
* This function initializes the notification structure pool. It allows the
* XBee driver to pass notifications and for the callee to free them when they
* are done using them, saving copying the data when passing.
*
****************************************************************************/
void xbee_notifpool_init(FAR struct xbee_priv_s *priv)
{
FAR struct xbee_notif_s *pool = priv->notif_pool;
int remaining = CONFIG_XBEE_NNOTIF;
priv->notif_free = NULL;
while (remaining > 0)
{
FAR struct xbee_notif_s *notif = pool;
/* Add the next meta data structure from the pool to the list of
* general structures.
*/
notif->flink = priv->notif_free;
priv->notif_free = notif;
/* Set up for the next structure from the pool */
pool++;
remaining--;
}
sem_init(&priv->notif_sem, 0, CONFIG_XBEE_NNOTIF);
}
/****************************************************************************
* Name: xbee_notif_alloc
*
* Description:
* This function allocates a free notification structure from the free list
* to be used for passing to the registered notify callback. The callee software
* is responsible for freeing the notification structure after it is done using
* it via xbee_notif_free.
*
* Assumptions:
* priv XBee struct is locked when calling.
*
* Notes:
* If any of the semaphore waits inside this function get interrupted, the
* function will release the MAC layer. If this function returns -EINTR, the
* calling code should NOT release the MAC semaphore.
*
****************************************************************************/
int xbee_notif_alloc(FAR struct xbee_priv_s *priv,
FAR struct ieee802154_notif_s **notif,
bool allow_interrupt)
{
int ret;
FAR struct xbee_notif_s *privnotif;
/* Try and take a count from the semaphore. If this succeeds, we have
* "reserved" the structure, but still need to unlink it from the free list.
* The MAC is already locked, so there shouldn't be any other conflicting calls
*/
ret = sem_trywait(&priv->notif_sem);
if (ret == OK)
{
privnotif = priv->notif_free;
priv->notif_free = privnotif->flink;
privnotif->nclients = 0;
}
else
{
/* Unlock XBee driver so that other work can be done to free a notification */
xbee_unlock(priv)
/* Take a count from the notification semaphore, waiting if necessary. We
* only return from here with an error if we are allowing interruptions
* and we received a signal */
ret = xbee_takesem(&priv->notif_sem, allow_interrupt);
if (ret < 0)
{
/* MAC sem is already released */
return -EINTR;
}
/* If we've taken a count from the semaphore, we have "reserved" the struct
* but now we need to pop it off of the free list. We need to re-lock the
* MAC in order to ensure this happens correctly.
*/
ret = xbee_lock(priv, allow_interrupt);
if (ret < 0)
{
xbee_givesem(&priv->notif_sem);
return -EINTR;
}
/* We can now safely unlink the next free structure from the free list */
privnotif = priv->notif_free;
priv->notif_free = privnotif->flink;
privnotif->nclients = 0;
}
*notif = (FAR struct ieee802154_notif_s *)privnotif;
return OK;
}
/****************************************************************************
* Name: xbee_notif_free_locked
*
* Description:
* When the XBee driver calls the registered callback, it passes a reference
* to a ieee802154_notif_s structure. This structure needs to be freed
* after the callback handler is done using it.
*
* Internal version that already has XBee driver locked
*
****************************************************************************/
void xbee_notif_free_locked(FAR struct xbee_priv_s * priv,
FAR struct ieee802154_notif_s *notif)
{
FAR struct xbee_notif_s *privnotif =
(FAR struct xbee_notif_s *)notif;
/* We know how many clients have registered for notifications. Each must
* call xbee_notif_free() before we can release the notification
* resource.
*/
if (privnotif->nclients < 2)
{
/* This is the free from the last notification */
privnotif->flink = priv->notif_free;
priv->notif_free = privnotif;
privnotif->nclients = 0;
xbee_givesem(&priv->notif_sem);
}
else
{
/* More calls are expected. Decrement the count of expected calls
* and preserve the notification resources.
*/
privnotif->nclients--;
}
}
/****************************************************************************
* Name: xbee_notify
*
* Description:
* Notify every register XBee MAC client.
*
****************************************************************************/
void xbee_notify(FAR struct xbee_priv_s *priv,
FAR struct ieee802154_notif_s *notif)
{
FAR struct xbee_maccb_s *cb;
FAR struct xbee_notif_s *privnotif = (FAR struct xbee_notif_s *)notif;
/* Set the notification count so that the notification resources will be
* preserved until the final notification.
*/
privnotif->nclients = priv->nclients;
/* Try to notify every registered XBee MAC client */
for (cb = priv->cb; cb != NULL; cb = cb->flink)
{
/* Does this client want notifications? */
if (cb->notify != NULL)
{
/* Yes.. Notify */
cb->notify(cb, notif);
}
}
}

View File

@ -0,0 +1,84 @@
/****************************************************************************
* drivers/wireless/ieee802154/xbee/xbee_notif.h
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
*
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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 __DRIVERS_WIRELESS_IEEE802154_XBEE_NOTIF_H
#define __DRIVERS_WIRELESS_IEEE802154_XBEE_NOTIF_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
/****************************************************************************
* Private Types
****************************************************************************/
/* Extend the public ieee802154_notif_s to include a private forward link to
* support a list to handle allocation
*/
struct xbee_notif_s
{
struct ieee802154_notif_s pub; /* Publically visible structure */
FAR struct xbee_notif_s *flink; /* Supports a singly linked list */
uint8_t nclients;
};
/****************************************************************************
* Function Prototypes
****************************************************************************/
struct xbee_priv_s; /* Forward Reference */
void xbee_notifpool_init(FAR struct xbee_priv_s *priv);
int xbee_notif_alloc(FAR struct xbee_priv_s *priv,
FAR struct ieee802154_notif_s **notif,
bool allow_interrupt);
void xbee_notify(FAR struct xbee_priv_s *priv,
FAR struct ieee802154_notif_s *notif);
void xbee_notif_free_locked(FAR struct xbee_priv_s * priv,
FAR struct ieee802154_notif_s *notif);
#endif /* __DRIVERS_WIRELESS_IEEE802154_XBEE_NOTIF_H */

View File

@ -0,0 +1,135 @@
/****************************************************************************
* include/nuttx/wireless/ieee802154/xbee.h
*
* Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Anthony Merlino <anthony@vergeaero.com>
*
* 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 NuttX 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 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 __INCLUDE_NUTTX_WIRELESS_IEEE802154_XBEE_H
#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_XBEE_H
/****************************************************************************
* Included files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <nuttx/arch.h>
/****************************************************************************
* Public Types
****************************************************************************/
/* The XBee provides interrupts (ATTN) to the MCU via a GPIO pin. The
* following structure provides an MCU-independent mechanism for controlling
* the XBee GPIO interrupt.
*
* The XBee interrupt is active low.
*/
struct xbee_lower_s
{
void (*reset)(FAR const struct xbee_lower_s *lower);
int (*attach)(FAR const struct xbee_lower_s *lower, xcpt_t handler,
FAR void *arg);
void (*enable)(FAR const struct xbee_lower_s *lower, bool state);
bool (*poll)(FAR const struct xbee_lower_s *lower);
};
/* This is an opaque reference to the XBee's internal private state. It is
* returned by xbee_init() when it is created. It may then be used
* at other interfaces in order to interact with the XBee MAC.
*/
typedef FAR void *XBEEHANDLE;
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: xbee_init
*
* Description:
* Initialize an XBee driver. The XBee device is assumed to be
* in the post-reset state upon entry to this function.
*
* Parameters:
* spi - A reference to the platform's SPI driver for the XBee
* lower - The MCU-specific interrupt used to control low-level MCU
* functions (i.e., XBee GPIO interrupts).
* devno - If more than one XBee is supported, then this is the
* zero based number that identifies the XBee;
*
* Returned Value:
* OK on success; Negated errno on failure.
*
* Assumptions:
*
****************************************************************************/
struct spi_dev_s; /* Forward reference */
XBEEHANDLE xbee_init(FAR struct spi_dev_s *spi,
FAR const struct xbee_lower_s *lower);
/****************************************************************************
* Name: xbee_netdev_register
*
* Description:
* Register XBee network device. The network device is what binds the XBee MAC
* to the network layer (6LoWPAN, PF_IEEE802154).
*
* Parameters:
* xbee - A reference to the XBee Mac driver
*
* Returned Value:
* OK on success; Negated errno on failure.
*
* Assumptions:
*
****************************************************************************/
int xbee_netdev_register(XBEEHANDLE xbee);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_XBEE_H */