Merge branch 'beacon802154'
This commit is contained in:
commit
4fde6fc654
@ -35,4 +35,11 @@ config CLICKER2_STM32_MB2_BEE
|
|||||||
---help---
|
---help---
|
||||||
Enable support for MRF24J40 BEE on mikroBUS2
|
Enable support for MRF24J40 BEE on mikroBUS2
|
||||||
|
|
||||||
|
config CLICKER2_STM32_MRF24J40LH_VERBOSE
|
||||||
|
bool "Verbose MRF24J40 lowerhalf"
|
||||||
|
default n
|
||||||
|
depends on IEEE802154_MRF24J40 && DEBUG_WIRELESS_INFO
|
||||||
|
---help---
|
||||||
|
Enable verbose syslog for MRF24J40 lowerhalf
|
||||||
|
|
||||||
endif # ARCH_BOARD_CLICKER2_STM32
|
endif # ARCH_BOARD_CLICKER2_STM32
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# CONFIG_NSH_CMDOPT_DF_H is not set
|
CONFIG_ARCH="arm"
|
||||||
CONFIG_ARCH_BOARD_CLICKER2_STM32=y
|
|
||||||
CONFIG_ARCH_BOARD="clicker2-stm32"
|
CONFIG_ARCH_BOARD="clicker2-stm32"
|
||||||
|
CONFIG_ARCH_BOARD_CLICKER2_STM32=y
|
||||||
CONFIG_ARCH_BUTTONS=y
|
CONFIG_ARCH_BUTTONS=y
|
||||||
CONFIG_ARCH_CHIP_STM32=y
|
|
||||||
CONFIG_ARCH_CHIP_STM32F407VG=y
|
CONFIG_ARCH_CHIP_STM32F407VG=y
|
||||||
|
CONFIG_ARCH_CHIP_STM32=y
|
||||||
CONFIG_ARCH_IRQBUTTONS=y
|
CONFIG_ARCH_IRQBUTTONS=y
|
||||||
CONFIG_ARCH_STACKDUMP=y
|
CONFIG_ARCH_STACKDUMP=y
|
||||||
CONFIG_ARCH="arm"
|
|
||||||
CONFIG_BOARD_INITIALIZE=y
|
CONFIG_BOARD_INITIALIZE=y
|
||||||
CONFIG_BOARD_LOOPSPERMSEC=16717
|
CONFIG_BOARD_LOOPSPERMSEC=16717
|
||||||
CONFIG_BUILTIN=y
|
CONFIG_BUILTIN=y
|
||||||
@ -17,8 +16,9 @@ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
|
|||||||
CONFIG_EXAMPLES_NSH=y
|
CONFIG_EXAMPLES_NSH=y
|
||||||
CONFIG_FS_PROCFS=y
|
CONFIG_FS_PROCFS=y
|
||||||
CONFIG_FS_WRITABLE=y
|
CONFIG_FS_WRITABLE=y
|
||||||
CONFIG_HAVE_CXX=y
|
|
||||||
CONFIG_HAVE_CXXINITIALIZE=y
|
CONFIG_HAVE_CXXINITIALIZE=y
|
||||||
|
CONFIG_HAVE_CXX=y
|
||||||
|
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||||
CONFIG_IEEE802154_I8SAK=y
|
CONFIG_IEEE802154_I8SAK=y
|
||||||
CONFIG_IEEE802154_MACDEV=y
|
CONFIG_IEEE802154_MACDEV=y
|
||||||
CONFIG_IEEE802154_MRF24J40=y
|
CONFIG_IEEE802154_MRF24J40=y
|
||||||
@ -30,6 +30,7 @@ CONFIG_NFILE_DESCRIPTORS=8
|
|||||||
CONFIG_NFILE_STREAMS=8
|
CONFIG_NFILE_STREAMS=8
|
||||||
CONFIG_NSH_ARCHINIT=y
|
CONFIG_NSH_ARCHINIT=y
|
||||||
CONFIG_NSH_BUILTIN_APPS=y
|
CONFIG_NSH_BUILTIN_APPS=y
|
||||||
|
# CONFIG_NSH_CMDOPT_DF_H is not set
|
||||||
CONFIG_NSH_DISABLE_GET=y
|
CONFIG_NSH_DISABLE_GET=y
|
||||||
CONFIG_NSH_DISABLE_IFUPDOWN=y
|
CONFIG_NSH_DISABLE_IFUPDOWN=y
|
||||||
CONFIG_NSH_DISABLE_PUT=y
|
CONFIG_NSH_DISABLE_PUT=y
|
||||||
@ -44,8 +45,8 @@ CONFIG_RAM_SIZE=131072
|
|||||||
CONFIG_RAM_START=0x20000000
|
CONFIG_RAM_START=0x20000000
|
||||||
CONFIG_RAW_BINARY=y
|
CONFIG_RAW_BINARY=y
|
||||||
CONFIG_RR_INTERVAL=200
|
CONFIG_RR_INTERVAL=200
|
||||||
CONFIG_SCHED_HPWORK=y
|
|
||||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||||
|
CONFIG_SCHED_HPWORK=y
|
||||||
CONFIG_SCHED_WAITPID=y
|
CONFIG_SCHED_WAITPID=y
|
||||||
CONFIG_SDCLONE_DISABLE=y
|
CONFIG_SDCLONE_DISABLE=y
|
||||||
CONFIG_START_YEAR=2013
|
CONFIG_START_YEAR=2013
|
||||||
|
@ -75,6 +75,11 @@ ifneq ($(CONFIG_DEBUG_NOOPT),y)
|
|||||||
ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
|
ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# enable precise stack overflow tracking
|
||||||
|
ifeq ($(CONFIG_ARMV7M_STACKCHECK),y)
|
||||||
|
INSTRUMENTATIONDEFINES = -finstrument-functions -ffixed-r10
|
||||||
|
endif
|
||||||
|
|
||||||
ARCHCFLAGS = -fno-builtin
|
ARCHCFLAGS = -fno-builtin
|
||||||
ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
|
ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
|
||||||
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
|
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
|
||||||
@ -82,9 +87,9 @@ ARCHWARNINGSXX = -Wall -Wshadow -Wundef
|
|||||||
ARCHDEFINES =
|
ARCHDEFINES =
|
||||||
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
|
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
|
||||||
|
|
||||||
CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
|
CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) $(INSTRUMENTATIONDEFINES) -pipe
|
||||||
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
|
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
|
||||||
CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
|
CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) $(INSTRUMENTATIONDEFINES) -pipe
|
||||||
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
|
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
|
||||||
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
|
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
|
||||||
AFLAGS = $(CFLAGS) -D__ASSEMBLY__
|
AFLAGS = $(CFLAGS) -D__ASSEMBLY__
|
||||||
|
@ -193,9 +193,12 @@ static void stm32_enable_irq(FAR const struct mrf24j40_lower_s *lower,
|
|||||||
|
|
||||||
DEBUGASSERT(priv != NULL && (priv->handler != NULL || !state));
|
DEBUGASSERT(priv != NULL && (priv->handler != NULL || !state));
|
||||||
|
|
||||||
|
#ifdef CONFIG_CLICKER2_STM32_MRF24J40LH_VERBOSE
|
||||||
|
wlinfo("state:%d\n", (int)state);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Attach and enable, or detach and disable */
|
/* Attach and enable, or detach and disable */
|
||||||
|
|
||||||
wlinfo("state:%d\n", (int)state);
|
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
(void)stm32_gpiosetevent(priv->intcfg, true, true, true,
|
(void)stm32_gpiosetevent(priv->intcfg, true, true, true,
|
||||||
|
@ -11,10 +11,14 @@ config IEEE802154_MRF24J40
|
|||||||
---help---
|
---help---
|
||||||
This selection enables support for the Microchip MRF24J40 device.
|
This selection enables support for the Microchip MRF24J40 device.
|
||||||
|
|
||||||
|
source drivers/wireless/ieee802154/mrf24j40/Kconfig
|
||||||
|
|
||||||
config IEEE802154_AT86RF233
|
config IEEE802154_AT86RF233
|
||||||
bool "ATMEL RF233 IEEE 802.15.4 transceiver"
|
bool "ATMEL RF233 IEEE 802.15.4 transceiver"
|
||||||
default n
|
default n
|
||||||
---help---
|
---help---
|
||||||
This selection enables support for the Atmel RF233 device.
|
This selection enables support for the Atmel RF233 device.
|
||||||
|
|
||||||
|
source drivers/wireless/ieee802154/at86rf23x/Kconfig
|
||||||
|
|
||||||
endif # DRIVERS_IEEE802154
|
endif # DRIVERS_IEEE802154
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
# drivers/ieee802154/Make.defs
|
# drivers/ieee802154/Make.defs
|
||||||
#
|
#
|
||||||
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
# Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -41,15 +41,10 @@ ifeq ($(CONFIG_DRIVERS_IEEE802154),y)
|
|||||||
|
|
||||||
# Include IEEE 802.15.4 drivers into the build
|
# Include IEEE 802.15.4 drivers into the build
|
||||||
|
|
||||||
ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
|
include wireless$(DELIM)ieee802154$(DELIM)mrf24j40$(DELIM)Make.defs
|
||||||
CSRCS += mrf24j40.c
|
include wireless$(DELIM)ieee802154$(DELIM)at86rf23x$(DELIM)Make.defs
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_IEEE802154_AT86RF233),y)
|
# Include common IEEE 802.15.4 build support
|
||||||
CSRCS += at86rf23x.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Include IEEE 802.15.4 build support
|
|
||||||
|
|
||||||
DEPPATH += --dep-path wireless$(DELIM)ieee802154
|
DEPPATH += --dep-path wireless$(DELIM)ieee802154
|
||||||
VPATH += :wireless$(DELIM)ieee802154
|
VPATH += :wireless$(DELIM)ieee802154
|
||||||
|
8
drivers/wireless/ieee802154/at86rf23x/Kconfig
Normal file
8
drivers/wireless/ieee802154/at86rf23x/Kconfig
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
# For a description of the syntax of this configuration file,
|
||||||
|
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||||
|
#
|
||||||
|
|
||||||
|
if IEEE802154_AT86RF233
|
||||||
|
|
||||||
|
endif # IEEE802154_AT86RF233
|
48
drivers/wireless/ieee802154/at86rf23x/Make.defs
Normal file
48
drivers/wireless/ieee802154/at86rf23x/Make.defs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
############################################################################
|
||||||
|
# drivers/ieee802154/at86rf23x/Make.defs
|
||||||
|
#
|
||||||
|
# Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
|
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# Include AT86RF23x drivers into the build
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_IEEE802154_AT86RF233),y)
|
||||||
|
|
||||||
|
CSRCS += at86rf23x.c
|
||||||
|
|
||||||
|
# Include AT86RF23x build support
|
||||||
|
|
||||||
|
DEPPATH += --dep-path wireless$(DELIM)ieee802154$(DELIM)at86rf23x
|
||||||
|
VPATH += :wireless$(DELIM)ieee802154$(DELIM)at86rf23x
|
||||||
|
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)ieee802154$(DELIM)at86rf23x}
|
||||||
|
|
||||||
|
endif # CONFIG_IEEE802154_AT86RF233
|
@ -1,5 +1,5 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/wireless/ieee802154/at86rf23x.c
|
* drivers/wireless/ieee802154/at86rf23x/at86rf23x.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Matt Poppe. All rights reserved.
|
* Copyright (C) 2016 Matt Poppe. All rights reserved.
|
||||||
* Author: Matt Poppe <matt@poppe.me>
|
* Author: Matt Poppe <matt@poppe.me>
|
||||||
@ -996,19 +996,20 @@ static int at86rf23x_gettxpower(FAR struct ieee802154_radio_s *ieee,
|
|||||||
reg = at86rf23x_getreg(dev->spi, RF23X_REG_TXPWR);
|
reg = at86rf23x_getreg(dev->spi, RF23X_REG_TXPWR);
|
||||||
switch (reg)
|
switch (reg)
|
||||||
{
|
{
|
||||||
case RF23X_TXPWR_POS_4:
|
case RF23X_TXPWR_POS_4:
|
||||||
|
|
||||||
*txpwr = 0;
|
*txpwr = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF23X_TXPWR_POS_3_7:
|
case RF23X_TXPWR_POS_3_7:
|
||||||
|
*txpwr =0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RF23X_TXPWR_POS_3_4:
|
||||||
*txpwr = 0;
|
*txpwr = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF23X_TXPWR_POS_3_4:
|
case RF23X_TXPWR_POS_3:
|
||||||
*txpwr = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RF23X_TXPWR_POS_3:
|
|
||||||
*txpwr = 0;
|
*txpwr = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1016,23 +1017,23 @@ static int at86rf23x_gettxpower(FAR struct ieee802154_radio_s *ieee,
|
|||||||
*txpwr = 0;
|
*txpwr = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF23X_TXPWR_POS_2:
|
case RF23X_TXPWR_POS_2:
|
||||||
*txpwr = 0;
|
*txpwr = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF23X_TXPWR_POS_1:
|
case RF23X_TXPWR_POS_1:
|
||||||
*txpwr = 0;
|
*txpwr = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF23X_TXPWR_0:
|
case RF23X_TXPWR_0:
|
||||||
*txpwr = 0;
|
*txpwr =0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF23X_TXPWR_NEG_1:
|
case RF23X_TXPWR_NEG_1:
|
||||||
*txpwr = 1000;
|
*txpwr = 1000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF23X_TXPWR_NEG_2:
|
case RF23X_TXPWR_NEG_2:
|
||||||
*txpwr = 2000;
|
*txpwr = 2000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1071,11 +1072,11 @@ static int at86rf23x_gettxpower(FAR struct ieee802154_radio_s *ieee,
|
|||||||
* Configures if energy detection is used or carrier sense. The base
|
* Configures if energy detection is used or carrier sense. The base
|
||||||
* measurement is configured here as well
|
* measurement is configured here as well
|
||||||
*
|
*
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int at86rf23x_setcca(FAR struct ieee802154_radio_s *ieee,
|
static
|
||||||
FAR struct ieee802154_cca_s *cca)
|
int at86rf23x_setcca(FAR struct ieee802154_radio_s *ieee,
|
||||||
|
FAR struct ieee802154_cca_s *cca)
|
||||||
{
|
{
|
||||||
FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
|
FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/wireless/ieee802154/at86rf23x.c
|
* drivers/wireless/ieee802154/at86rf23x/at86rf23x.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Matt Poppe. All rights reserved.
|
* Copyright (C) 2016 Matt Poppe. All rights reserved.
|
||||||
* Author: Matt Poppe <matt@poppe.me>
|
* Author: Matt Poppe <matt@poppe.me>
|
||||||
@ -33,8 +33,8 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H
|
#ifndef __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_AT86RF23X_H
|
||||||
#define __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H
|
#define __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_AT86RF23X_H
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@ -218,4 +218,4 @@
|
|||||||
|
|
||||||
#define RF23X_IRQ_MASK_DEFAULT (RF23X_IRQ_MASK_TRX_END)
|
#define RF23X_IRQ_MASK_DEFAULT (RF23X_IRQ_MASK_TRX_END)
|
||||||
|
|
||||||
#endif /* __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H */
|
#endif /* __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_AT86RF23X_H */
|
File diff suppressed because it is too large
Load Diff
8
drivers/wireless/ieee802154/mrf24j40/Kconfig
Normal file
8
drivers/wireless/ieee802154/mrf24j40/Kconfig
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
# For a description of the syntax of this configuration file,
|
||||||
|
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||||
|
#
|
||||||
|
|
||||||
|
if IEEE802154_MRF24J40
|
||||||
|
|
||||||
|
endif # IEEE802154_MRF24J40
|
49
drivers/wireless/ieee802154/mrf24j40/Make.defs
Normal file
49
drivers/wireless/ieee802154/mrf24j40/Make.defs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
############################################################################
|
||||||
|
# drivers/ieee802154/mrf24j40/Make.defs
|
||||||
|
#
|
||||||
|
# Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
|
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
#
|
||||||
|
# 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_MRF24J40),y)
|
||||||
|
|
||||||
|
# Include MRF24J40 files into the build
|
||||||
|
|
||||||
|
CSRCS += mrf24j40_getset.c mrf24j40_interrupt.c mrf24j40_radif.c
|
||||||
|
CSRCS += mrf24j40_regops.c mrf24j40.c
|
||||||
|
|
||||||
|
# Include MRF24J40 build support
|
||||||
|
|
||||||
|
DEPPATH += --dep-path wireless$(DELIM)ieee802154$(DELIM)mrf24j40
|
||||||
|
VPATH += :wireless$(DELIM)ieee802154$(DELIM)mrf24j40
|
||||||
|
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)ieee802154$(DELIM)mrf24j40}
|
||||||
|
|
||||||
|
endif # CONFIG_IEEE802154_MRF24J40
|
473
drivers/wireless/ieee802154/mrf24j40/mrf24j40.c
Normal file
473
drivers/wireless/ieee802154/mrf24j40/mrf24j40.c
Normal file
@ -0,0 +1,473 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||||
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/wqueue.h>
|
||||||
|
#include <nuttx/semaphore.h>
|
||||||
|
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
|
|
||||||
|
#include <nuttx/wireless/ieee802154/mrf24j40.h>
|
||||||
|
#include <nuttx/wireless/ieee802154/ieee802154_radio.h>
|
||||||
|
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||||
|
|
||||||
|
#include "mrf24j40.h"
|
||||||
|
#include "mrf24j40_reg.h"
|
||||||
|
#include "mrf24j40_radif.h"
|
||||||
|
#include "mrf24j40_getset.h"
|
||||||
|
#include "mrf24j40_regops.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR uint8_t *energy);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_energydetect
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Measure the RSSI level for the current channel.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR uint8_t *energy)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
/* Manually enable the LNA*/
|
||||||
|
|
||||||
|
mrf24j40_setpamode(dev, MRF24J40_PA_ED);
|
||||||
|
|
||||||
|
/* Set RSSI average duration to 8 symbols */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXBCON1);
|
||||||
|
reg |= 0x30;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXBCON1, reg);
|
||||||
|
|
||||||
|
/* 1. Set RSSIMODE1 0x3E<7> – Initiate RSSI calculation. */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BBREG6, 0x80);
|
||||||
|
|
||||||
|
/* 2. Wait until RSSIRDY 0x3E<0> is set to ‘1’ – RSSI calculation is
|
||||||
|
* complete.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while(!(mrf24j40_getreg(dev->spi, MRF24J40_BBREG6) & 0x01));
|
||||||
|
|
||||||
|
/* 3. Read RSSI 0x210<7:0> – The RSSI register contains the averaged RSSI
|
||||||
|
* received power level for 8 symbol periods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
*energy = mrf24j40_getreg(dev->spi, MRF24J40_RSSI);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BBREG6, 0x40);
|
||||||
|
|
||||||
|
/* Back to automatic control */
|
||||||
|
|
||||||
|
mrf24j40_setpamode(dev, MRF24J40_PA_AUTO);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: mrf24j40_dopoll_csma
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function is called in order to preform an out-of-sequence TX poll.
|
||||||
|
* This is done:
|
||||||
|
*
|
||||||
|
* 1. After completion of a transmission (mrf24j40_txdone_csma),
|
||||||
|
* 2. When new TX data is available (mrf24j40_txnotify), and
|
||||||
|
* 3. After a TX timeout to restart the sending process
|
||||||
|
* (mrf24j40_txtimeout_csma).
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* radio - Reference to the radio driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_dopoll_csma(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
/* Get exclusive access to the driver */
|
||||||
|
|
||||||
|
while (sem_wait(&dev->exclsem) != 0) { }
|
||||||
|
|
||||||
|
/* If this a CSMA transaction and we have room in the CSMA fifo */
|
||||||
|
|
||||||
|
if (!dev->csma_busy)
|
||||||
|
{
|
||||||
|
wlinfo("Polling for frame\n");
|
||||||
|
len = dev->radiocb->poll(dev->radiocb, false, &dev->csma_desc);
|
||||||
|
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
wlinfo("Frame received. Frame length: %d\n", len);
|
||||||
|
|
||||||
|
/* Now the txdesc is in use */
|
||||||
|
|
||||||
|
dev->csma_busy = 1;
|
||||||
|
|
||||||
|
/* Setup the transaction on the device in the CSMA FIFO */
|
||||||
|
|
||||||
|
mrf24j40_norm_setup(dev, dev->csma_desc->frame, true);
|
||||||
|
mrf24j40_norm_trigger(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sem_post(&dev->exclsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: mrf24j40_dopoll_gts
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function is called in order to preform an out-of-sequence TX poll.
|
||||||
|
* This is done:
|
||||||
|
*
|
||||||
|
* 1. After completion of a transmission (mrf24j40_txdone_gts),
|
||||||
|
* 2. When new TX data is available (mrf24j40_txnotify), and
|
||||||
|
* 3. After a TX timeout to restart the sending process
|
||||||
|
* (mrf24j40_txtimeout_gts).
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* arg - Reference to the radio driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_dopoll_gts(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg;
|
||||||
|
int gts = 0;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
/* Get exclusive access to the driver */
|
||||||
|
|
||||||
|
while (sem_wait(&dev->exclsem) != 0) { }
|
||||||
|
|
||||||
|
for (gts = 0; gts < MRF24J40_GTS_SLOTS; gts++)
|
||||||
|
{
|
||||||
|
if (!dev->gts_busy[gts])
|
||||||
|
{
|
||||||
|
len = dev->radiocb->poll(dev->radiocb, true, &dev->gts_desc[gts]);
|
||||||
|
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
/* Now the txdesc is in use */
|
||||||
|
|
||||||
|
dev->gts_busy[gts]= 1;
|
||||||
|
|
||||||
|
/* Setup the transaction on the device in the open GTS FIFO */
|
||||||
|
|
||||||
|
mrf24j40_gts_setup(dev, gts, dev->gts_desc[gts]->frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sem_post(&dev->exclsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_norm_setup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Setup a transaction in the normal TX FIFO
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR struct iob_s *frame, bool csma)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
/* Enable tx int */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg &= ~MRF24J40_INTCON_TXNIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
|
||||||
|
/* Enable/Disable CSMA mode */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXMCR);
|
||||||
|
|
||||||
|
if (csma)
|
||||||
|
{
|
||||||
|
reg &= ~MRF24J40_TXMCR_NOCSMA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reg |= MRF24J40_TXMCR_NOCSMA;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXMCR, reg);
|
||||||
|
|
||||||
|
/* Setup the FIFO */
|
||||||
|
|
||||||
|
mrf24j40_setup_fifo(dev, frame->io_data, frame->io_len, MRF24J40_TXNORM_FIFO);
|
||||||
|
|
||||||
|
/* If the frame control field contains an acknowledgment request, set the
|
||||||
|
* TXNACKREQ bit. See IEEE 802.15.4/2003 7.2.1.1 page 112 for info.
|
||||||
|
*/
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXNCON);
|
||||||
|
|
||||||
|
if (frame->io_data[0] & IEEE802154_FRAMECTRL_ACKREQ)
|
||||||
|
{
|
||||||
|
reg |= MRF24J40_TXNCON_TXNACKREQ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reg &= ~MRF24J40_TXNCON_TXNACKREQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXNCON, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_norm_trigger
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Trigger the normal TX FIFO
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_norm_trigger(FAR struct mrf24j40_radio_s *dev)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXNCON);
|
||||||
|
reg |= MRF24J40_TXNCON_TXNTRIG;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXNCON, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_beacon_trigger
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Trigger the beacon TX FIFO
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_beacon_trigger(FAR struct mrf24j40_radio_s *dev)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXBCON0);
|
||||||
|
|
||||||
|
reg |= MRF24J40_TXBCON0_TXBTRIG;
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXBCON0, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_gts_setup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Setup a GTS transaction in one of the GTS FIFOs
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t fifo,
|
||||||
|
FAR struct iob_s *frame)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setup_fifo
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, FAR const uint8_t *buf,
|
||||||
|
uint8_t length, uint32_t fifo_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
int hlen = 3; /* Include frame control and seq number */
|
||||||
|
int i;
|
||||||
|
uint16_t frame_ctrl;
|
||||||
|
|
||||||
|
/* Analyze frame control to compute header length */
|
||||||
|
|
||||||
|
frame_ctrl = buf[0];
|
||||||
|
frame_ctrl |= (buf[1] << 8);
|
||||||
|
|
||||||
|
if ((frame_ctrl & IEEE802154_FRAMECTRL_DADDR)== IEEE802154_ADDRMODE_SHORT)
|
||||||
|
{
|
||||||
|
hlen += 2 + 2; /* Destination PAN + shortaddr */
|
||||||
|
}
|
||||||
|
else if ((frame_ctrl & IEEE802154_FRAMECTRL_DADDR) == IEEE802154_ADDRMODE_EXTENDED)
|
||||||
|
{
|
||||||
|
hlen += 2 + 8; /* Destination PAN + extaddr */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(frame_ctrl & IEEE802154_FRAMECTRL_PANIDCOMP))
|
||||||
|
{
|
||||||
|
hlen += 2; /* No PAN compression, source PAN is different from dest PAN */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((frame_ctrl & IEEE802154_FRAMECTRL_SADDR)== IEEE802154_ADDRMODE_SHORT)
|
||||||
|
{
|
||||||
|
hlen += 2; /* Source saddr */
|
||||||
|
}
|
||||||
|
else if ((frame_ctrl & IEEE802154_FRAMECTRL_SADDR) == IEEE802154_ADDRMODE_EXTENDED)
|
||||||
|
{
|
||||||
|
hlen += 8; /* Ext saddr */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header len, 0, TODO for security modes */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, fifo_addr++, hlen);
|
||||||
|
|
||||||
|
|
||||||
|
/* Frame length */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, fifo_addr++, length);
|
||||||
|
|
||||||
|
/* Frame data */
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, fifo_addr++, buf[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return an mrf24j40 device for use by other drivers.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi,
|
||||||
|
FAR const struct mrf24j40_lower_s *lower)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev;
|
||||||
|
|
||||||
|
dev = kmm_zalloc(sizeof(struct mrf24j40_radio_s));
|
||||||
|
if (dev == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach irq */
|
||||||
|
|
||||||
|
if (lower->attach(lower, mrf24j40_interrupt, dev) != OK)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
free(dev);
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow exclusive access to the privmac struct */
|
||||||
|
|
||||||
|
sem_init(&dev->exclsem, 0, 1);
|
||||||
|
|
||||||
|
dev->radio.bind = mrf24j40_bind;
|
||||||
|
dev->radio.reset = mrf24j40_reset;
|
||||||
|
dev->radio.getattr = mrf24j40_getattr;
|
||||||
|
dev->radio.setattr = mrf24j40_setattr;
|
||||||
|
dev->radio.txnotify = mrf24j40_txnotify;
|
||||||
|
dev->radio.txdelayed = mrf24j40_txdelayed;
|
||||||
|
dev->radio.rxenable = mrf24j40_rxenable;
|
||||||
|
dev->radio.beaconstart = mrf24j40_beaconstart;
|
||||||
|
dev->radio.beaconupdate = mrf24j40_beaconupdate;
|
||||||
|
dev->radio.beaconstop = mrf24j40_beaconstop;
|
||||||
|
dev->radio.sfupdate = mrf24j40_sfupdate;
|
||||||
|
|
||||||
|
dev->lower = lower;
|
||||||
|
dev->spi = spi;
|
||||||
|
|
||||||
|
mrf24j40_reset(&dev->radio);
|
||||||
|
|
||||||
|
dev->lower->enable(dev->lower, true);
|
||||||
|
return &dev->radio;
|
||||||
|
}
|
||||||
|
|
227
drivers/wireless/ieee802154/mrf24j40/mrf24j40.h
Normal file
227
drivers/wireless/ieee802154/mrf24j40/mrf24j40.h
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
*
|
||||||
|
* 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_MRF24J40_H
|
||||||
|
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_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/ieee802154_mac.h>
|
||||||
|
#include <nuttx/wireless/ieee802154/ieee802154_radio.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define MRF24J40_GTS_SLOTS 2
|
||||||
|
|
||||||
|
/* Definitions for the device structure */
|
||||||
|
|
||||||
|
#define MRF24J40_RXMODE_NORMAL 0
|
||||||
|
#define MRF24J40_RXMODE_PROMISC 1
|
||||||
|
#define MRF24J40_RXMODE_NOCRC 2
|
||||||
|
|
||||||
|
#define MRF24J40_MODE_DEVICE 0
|
||||||
|
#define MRF24J40_MODE_COORD 1
|
||||||
|
#define MRF24J40_MODE_PANCOORD 2
|
||||||
|
|
||||||
|
/* Definitions for PA control on high power modules */
|
||||||
|
|
||||||
|
#define MRF24J40_PA_AUTO 1
|
||||||
|
#define MRF24J40_PA_ED 2
|
||||||
|
#define MRF24J40_PA_SLEEP 3
|
||||||
|
|
||||||
|
/* Formula for calculating default macMaxFrameWaitTime is on pg. 130
|
||||||
|
*
|
||||||
|
* For PHYs other than CSS and UWB, the attribute phyMaxFrameDuration is given by:
|
||||||
|
*
|
||||||
|
* phyMaxFrameDuration = phySHRDuration +
|
||||||
|
* ceiling([aMaxPHYPacketSize + 1] x phySymbolsPerOctet)
|
||||||
|
*
|
||||||
|
* where ceiling() is a function that returns the smallest integer value greater
|
||||||
|
* than or equal to its argument value. [1] pg. 158
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MRF24J40_DEFAULT_MAX_FRAME_WAITTIME 1824
|
||||||
|
|
||||||
|
#define MRF24J40_SYMBOL_DURATION_PS 16000000
|
||||||
|
|
||||||
|
/* Clock configuration macros */
|
||||||
|
|
||||||
|
#define MRF24J40_BEACONINTERVAL_NSEC(beaconorder) \
|
||||||
|
(IEEE802154_BASE_SUPERFRAME_DURATION * (1 << beaconorder) * (16 * 1000))
|
||||||
|
|
||||||
|
#define MRF24J40_SUPERFRAMEDURATION_NSEC(sforder) \
|
||||||
|
(IEEE802154_BASE_SUPERFRAME_DURATION * (1 << sforder) * (16 * 1000))
|
||||||
|
|
||||||
|
/* Configuration *************************************************************/
|
||||||
|
|
||||||
|
#ifndef CONFIG_SCHED_HPWORK
|
||||||
|
# error High priority work queue required in this driver
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_IEEE802154_MRF24J40_SPIMODE
|
||||||
|
# define CONFIG_IEEE802154_MRF24J40_SPIMODE SPIDEV_MODE0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_IEEE802154_MRF24J40_FREQUENCY
|
||||||
|
# define CONFIG_IEEE802154_MRF24J40_FREQUENCY 8000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_SPI_EXCHANGE
|
||||||
|
# error CONFIG_SPI_EXCHANGE required for this driver
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* A MRF24J40 device instance */
|
||||||
|
|
||||||
|
struct mrf24j40_radio_s
|
||||||
|
{
|
||||||
|
struct ieee802154_radio_s radio; /* The public device instance */
|
||||||
|
FAR struct ieee802154_radiocb_s *radiocb; /* Registered callbacks */
|
||||||
|
|
||||||
|
/* Low-level MCU-specific support */
|
||||||
|
|
||||||
|
FAR const struct mrf24j40_lower_s *lower;
|
||||||
|
FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
|
||||||
|
|
||||||
|
struct work_s irqwork; /* For deferring interrupt work to work queue */
|
||||||
|
struct work_s csma_pollwork; /* For deferring poll work to the work queue */
|
||||||
|
struct work_s gts_pollwork; /* For deferring poll work to the work queue */
|
||||||
|
|
||||||
|
sem_t exclsem; /* Exclusive access to this struct */
|
||||||
|
|
||||||
|
/* MAC Attributes */
|
||||||
|
|
||||||
|
struct ieee802154_addr_s addr;
|
||||||
|
|
||||||
|
uint8_t chan; /* 11 to 26 for the 2.4 GHz band */
|
||||||
|
uint8_t devmode; /* device mode: device, coord, pancoord */
|
||||||
|
uint8_t paenabled; /* enable usage of PA */
|
||||||
|
uint8_t rxmode; /* Reception mode: Main, no CRC, promiscuous */
|
||||||
|
int32_t txpower; /* TX power in mBm = dBm/100 */
|
||||||
|
struct ieee802154_cca_s cca; /* Clear channel assessement method */
|
||||||
|
uint32_t slpclkper; /* Sleep clock period (nanoseconds) */
|
||||||
|
|
||||||
|
/* MAC PIB attributes */
|
||||||
|
|
||||||
|
uint32_t max_frame_waittime;
|
||||||
|
|
||||||
|
struct ieee802154_txdesc_s *txdelayed_desc;
|
||||||
|
struct ieee802154_txdesc_s *csma_desc;
|
||||||
|
bool txdelayed_busy : 1;
|
||||||
|
bool csma_busy : 1;
|
||||||
|
bool reschedule_csma : 1;
|
||||||
|
|
||||||
|
bool rxenabled : 1;
|
||||||
|
|
||||||
|
uint8_t bsn;
|
||||||
|
|
||||||
|
struct ieee802154_txdesc_s *gts_desc[MRF24J40_GTS_SLOTS];
|
||||||
|
bool gts_busy[MRF24J40_GTS_SLOTS];
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Inline Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_spi_lock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Acquire exclusive access to the shared SPI bus.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void mrf24j40_spi_lock(FAR struct spi_dev_s *spi)
|
||||||
|
{
|
||||||
|
SPI_LOCK(spi, 1);
|
||||||
|
SPI_SETBITS(spi, 8);
|
||||||
|
SPI_SETMODE(spi, CONFIG_IEEE802154_MRF24J40_SPIMODE);
|
||||||
|
SPI_SETFREQUENCY(spi, CONFIG_IEEE802154_MRF24J40_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_spi_unlock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Release exclusive access to the shared SPI bus.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void mrf24j40_spi_unlock(FAR struct spi_dev_s *spi)
|
||||||
|
{
|
||||||
|
SPI_LOCK(spi,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_interrupt(int irq, FAR void *context, FAR void *arg);
|
||||||
|
void mrf24j40_irqworker(FAR void *arg);
|
||||||
|
|
||||||
|
void mrf24j40_dopoll_csma(FAR void *arg);
|
||||||
|
void mrf24j40_dopoll_gts(FAR void *arg);
|
||||||
|
|
||||||
|
void mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR struct iob_s *frame, bool csma);
|
||||||
|
void mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t gts,
|
||||||
|
FAR struct iob_s *frame);
|
||||||
|
void mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR const uint8_t *buf, uint8_t length, uint32_t fifo_addr);
|
||||||
|
|
||||||
|
void mrf24j40_norm_trigger(FAR struct mrf24j40_radio_s *dev);
|
||||||
|
void mrf24j40_beacon_trigger(FAR struct mrf24j40_radio_s *dev);
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H */
|
499
drivers/wireless/ieee802154/mrf24j40/mrf24j40_getset.c
Normal file
499
drivers/wireless/ieee802154/mrf24j40/mrf24j40_getset.c
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_getset.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||||
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
|
#include "mrf24j40.h"
|
||||||
|
#include "mrf24j40_reg.h"
|
||||||
|
#include "mrf24j40_regops.h"
|
||||||
|
#include "mrf24j40_getset.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_resetrfsm(FAR struct mrf24j40_radio_s *dev);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_resetrfsm
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Reset the RF state machine. Required at boot, after channel change,
|
||||||
|
* and probably after PA settings.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_resetrfsm(FAR struct mrf24j40_radio_s *dev)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_RFCTL);
|
||||||
|
reg |= 0x04;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCTL, reg);
|
||||||
|
|
||||||
|
reg &= ~0x04;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCTL, reg);
|
||||||
|
up_udelay(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setrxmode
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set the RX mode (normal, promiscuous, no CRC)
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setrxmode(FAR struct mrf24j40_radio_s *dev, int mode)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
if (mode < MRF24J40_RXMODE_NORMAL || mode > MRF24J40_RXMODE_NOCRC)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR);
|
||||||
|
reg &= ~0x03;
|
||||||
|
reg |= mode;
|
||||||
|
|
||||||
|
/* Set mode options */
|
||||||
|
|
||||||
|
if (mode != MRF24J40_RXMODE_NORMAL)
|
||||||
|
{
|
||||||
|
/* Promisc and error modes: Disable auto ACK */
|
||||||
|
|
||||||
|
reg |= MRF24J40_RXMCR_NOACKRSP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Normal mode : enable auto-ACK */
|
||||||
|
|
||||||
|
reg &= ~MRF24J40_RXMCR_NOACKRSP;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg);
|
||||||
|
|
||||||
|
dev->rxmode = mode;
|
||||||
|
wlinfo("%u\n", (unsigned)mode);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setchannel
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the current radio channel the device is operating on.
|
||||||
|
* In the 2.4 GHz, there are 16 channels, each 2 MHz wide, 5 MHz spacing:
|
||||||
|
* Chan MHz Chan MHz Chan MHz Chan MHz
|
||||||
|
* 11 2405 15 2425 19 2445 23 2465
|
||||||
|
* 12 2410 16 2430 20 2450 24 2470
|
||||||
|
* 13 2415 17 2435 21 2455 25 2475
|
||||||
|
* 14 2420 18 2440 22 2460 26 2480
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setchannel(FAR struct mrf24j40_radio_s *dev, uint8_t chan)
|
||||||
|
{
|
||||||
|
if (chan < 11 || chan > 26)
|
||||||
|
{
|
||||||
|
wlerr("ERROR: Invalid chan: %d\n",chan);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 15. Set channel – See Section 3.4 “Channel Selection”. */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCON0, (chan - 11) << 4 | 0x03);
|
||||||
|
|
||||||
|
/* 17. RFCTL (0x36) = 0x04 – Reset RF state machine.
|
||||||
|
* 18. RFCTL (0x36) = 0x00.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_resetrfsm(dev);
|
||||||
|
|
||||||
|
dev->chan = chan;
|
||||||
|
wlinfo("%u\n", (unsigned)chan);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setpanid
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the PAN ID the device is operating on.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setpanid(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR const uint8_t *panid)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_PANIDL, panid[0]);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_PANIDH, panid[1]);
|
||||||
|
|
||||||
|
IEEE802154_PANIDCOPY(dev->addr.panid, panid);
|
||||||
|
wlinfo("%02X:%02X\n", panid[0], panid[1]);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setsaddr
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the device short address. The following addresses are special:
|
||||||
|
* FFFEh : Broadcast
|
||||||
|
* FFFFh : Unspecified
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setsaddr(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR const uint8_t *saddr)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_SADRL, saddr[0]);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_SADRH, saddr[1]);
|
||||||
|
|
||||||
|
IEEE802154_SADDRCOPY(dev->addr.saddr, saddr);
|
||||||
|
|
||||||
|
wlinfo("%02X:%02X\n", saddr[0], saddr[1]);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_seteaddr
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the device extended address. The following addresses are special:
|
||||||
|
* FFFFFFFFFFFFFFFFh : Unspecified
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_seteaddr(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR const uint8_t *eaddr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_EADR0 + i, eaddr[i]);
|
||||||
|
dev->addr.eaddr[i] = eaddr[i];
|
||||||
|
}
|
||||||
|
wlinfo("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", eaddr[0], eaddr[1],
|
||||||
|
eaddr[2], eaddr[3], eaddr[4], eaddr[5], eaddr[6], eaddr[7]);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setcoordsaddr
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the coordinator short address. The following addresses are special:
|
||||||
|
* FFFEh : Broadcast
|
||||||
|
* FFFFh : Unspecified
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setcoordsaddr(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR const uint8_t *saddr)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_ASSOSADR0, saddr[0]);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_ASSOSADR1, saddr[1]);
|
||||||
|
|
||||||
|
IEEE802154_SADDRCOPY(dev->addr.saddr, saddr);
|
||||||
|
|
||||||
|
wlinfo("%02X:%02X\n", saddr[0], saddr[1]);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setcoordeaddr
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the coordinator extended address. The following addresses are special:
|
||||||
|
* FFFFFFFFFFFFFFFFh : Unspecified
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setcoordeaddr(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR const uint8_t *eaddr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_ASSOEADR0 + i, eaddr[i]);
|
||||||
|
dev->addr.eaddr[i] = eaddr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
wlinfo("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", eaddr[0], eaddr[1],
|
||||||
|
eaddr[2], eaddr[3], eaddr[4], eaddr[5], eaddr[6], eaddr[7]);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setdevmode
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the device behaviour: normal end device or coordinator
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setdevmode(FAR struct mrf24j40_radio_s *dev, uint8_t mode)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
/* Define dev mode */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR);
|
||||||
|
|
||||||
|
if (mode == MRF24J40_MODE_PANCOORD)
|
||||||
|
{
|
||||||
|
reg |= MRF24J40_RXMCR_PANCOORD;
|
||||||
|
reg &= ~MRF24J40_RXMCR_COORD;
|
||||||
|
}
|
||||||
|
else if (mode == MRF24J40_MODE_COORD)
|
||||||
|
{
|
||||||
|
reg |= MRF24J40_RXMCR_COORD;
|
||||||
|
reg &= ~MRF24J40_RXMCR_PANCOORD;
|
||||||
|
}
|
||||||
|
else if (mode == MRF24J40_MODE_DEVICE)
|
||||||
|
{
|
||||||
|
reg &= ~MRF24J40_RXMCR_PANCOORD;
|
||||||
|
reg &= ~MRF24J40_RXMCR_COORD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg);
|
||||||
|
dev->devmode = mode;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_settxpower
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the transmit power. Value is passed in mBm, it is rounded to
|
||||||
|
* the nearest value. Some MRF modules have a power amplifier, this routine
|
||||||
|
* does not care about this. We only change the CHIP output power.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_settxpower(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
int32_t txpwr)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
int save_txpwr = txpwr;
|
||||||
|
|
||||||
|
if (txpwr <= -3000 && txpwr > -3630)
|
||||||
|
{
|
||||||
|
reg = 0xC0;
|
||||||
|
txpwr += 3000;
|
||||||
|
}
|
||||||
|
else if (txpwr <= -2000)
|
||||||
|
{
|
||||||
|
reg = 0x80;
|
||||||
|
txpwr += 2000;
|
||||||
|
}
|
||||||
|
else if (txpwr <= -1000)
|
||||||
|
{
|
||||||
|
reg = 0x40;
|
||||||
|
txpwr += 1000;
|
||||||
|
}
|
||||||
|
else if (txpwr <= 0)
|
||||||
|
{
|
||||||
|
reg = 0x00;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlinfo("Remaining attenuation: %d mBm\n",txpwr);
|
||||||
|
|
||||||
|
switch(txpwr/100)
|
||||||
|
{
|
||||||
|
case -9:
|
||||||
|
case -8:
|
||||||
|
case -7:
|
||||||
|
case -6:
|
||||||
|
reg |= 0x07;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -5:
|
||||||
|
reg |= 0x06;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -4:
|
||||||
|
reg |= 0x05;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -3:
|
||||||
|
reg |= 0x04;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -2:
|
||||||
|
reg |= 0x03;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
reg |= 0x02;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
reg |= 0x00; /* value 0x01 is 0.5 db, not used */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCON3, reg);
|
||||||
|
|
||||||
|
dev->txpower = save_txpwr;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setcca
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the Clear Channel Assessement method.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setcca(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR struct ieee802154_cca_s *cca)
|
||||||
|
{
|
||||||
|
uint8_t mode;
|
||||||
|
|
||||||
|
if (!cca->use_ed && !cca->use_cs)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cca->use_cs && cca->csth > 0x0f)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = mrf24j40_getreg(dev->spi, MRF24J40_BBREG2);
|
||||||
|
mode &= 0x03;
|
||||||
|
|
||||||
|
if (cca->use_ed)
|
||||||
|
{
|
||||||
|
mode |= MRF24J40_BBREG2_CCAMODE_ED;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_CCAEDTH, cca->edth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cca->use_cs)
|
||||||
|
{
|
||||||
|
mode |= MRF24J40_BBREG2_CCAMODE_CS;
|
||||||
|
mode |= cca->csth << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BBREG2, mode);
|
||||||
|
|
||||||
|
memcpy(&dev->cca, cca, sizeof(struct ieee802154_cca_s));
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setpamode
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Control the external LNA/PA on the MRF24J40MB/MC/MD/ME modules
|
||||||
|
* GPIO 1: PA enable
|
||||||
|
* GPIO 2: LNA enable
|
||||||
|
* GPIO 3: PA power enable (not required on MB)
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_setpamode(FAR struct mrf24j40_radio_s *dev, int mode)
|
||||||
|
{
|
||||||
|
if (!dev->paenabled)
|
||||||
|
{
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == MRF24J40_PA_AUTO)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TRISGPIO, 0x08);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_GPIO , 0x08);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TESTMODE, 0x0F);
|
||||||
|
}
|
||||||
|
else if (mode == MRF24J40_PA_ED)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TESTMODE, 0x08);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TRISGPIO, 0x0F);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_GPIO , 0x0C);
|
||||||
|
}
|
||||||
|
else if (mode == MRF24J40_PA_SLEEP)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TESTMODE, 0x08);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TRISGPIO, 0x0F);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_GPIO , 0x00);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrf24j40_resetrfsm(dev);
|
||||||
|
return OK;
|
||||||
|
}
|
66
drivers/wireless/ieee802154/mrf24j40/mrf24j40_getset.h
Normal file
66
drivers/wireless/ieee802154/mrf24j40/mrf24j40_getset.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_getset.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||||
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
* 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_MRF24J40_GETSET_H
|
||||||
|
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_GETSET_H
|
||||||
|
|
||||||
|
int mrf24j40_setrxmode(FAR struct mrf24j40_radio_s *dev, int mode);
|
||||||
|
|
||||||
|
int mrf24j40_setchannel(FAR struct mrf24j40_radio_s *dev, uint8_t chan);
|
||||||
|
|
||||||
|
int mrf24j40_setpanid(FAR struct mrf24j40_radio_s *dev, FAR const uint8_t *panid);
|
||||||
|
|
||||||
|
int mrf24j40_setsaddr(FAR struct mrf24j40_radio_s *dev, FAR const uint8_t *saddr);
|
||||||
|
|
||||||
|
int mrf24j40_seteaddr(FAR struct mrf24j40_radio_s *dev, FAR const uint8_t *eaddr);
|
||||||
|
|
||||||
|
int mrf24j40_setcoordsaddr(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR const uint8_t *saddr);
|
||||||
|
|
||||||
|
int mrf24j40_setcoordeaddr(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR const uint8_t *eaddr);
|
||||||
|
|
||||||
|
int mrf24j40_setdevmode(FAR struct mrf24j40_radio_s *dev, uint8_t mode);
|
||||||
|
|
||||||
|
int mrf24j40_settxpower(FAR struct mrf24j40_radio_s *dev, int32_t txpwr);
|
||||||
|
|
||||||
|
int mrf24j40_setcca(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
FAR struct ieee802154_cca_s *cca);
|
||||||
|
|
||||||
|
int mrf24j40_setpamode(FAR struct mrf24j40_radio_s *dev, int mode);
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_GETSET_H */
|
443
drivers/wireless/ieee802154/mrf24j40/mrf24j40_interrupt.c
Normal file
443
drivers/wireless/ieee802154/mrf24j40/mrf24j40_interrupt.c
Normal file
@ -0,0 +1,443 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_interrupt.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||||
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
|
|
||||||
|
#include <nuttx/wireless/ieee802154/mrf24j40.h>
|
||||||
|
|
||||||
|
#include "mrf24j40.h"
|
||||||
|
#include "mrf24j40_reg.h"
|
||||||
|
#include "mrf24j40_regops.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev);
|
||||||
|
static void mrf24j40_irqwork_txnorm(FAR struct mrf24j40_radio_s *dev);
|
||||||
|
static void mrf24j40_irqwork_txgts(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
uint8_t gts_num);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_irqwork_txnorm
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Manage completion of packet transmission.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_irqwork_txnorm(FAR struct mrf24j40_radio_s *dev)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
enum ieee802154_status_e status;
|
||||||
|
bool framepending;
|
||||||
|
|
||||||
|
/* Disable tx int */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg |= MRF24J40_INTCON_TXNIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
|
||||||
|
/* Get the status from the device and copy the status into the tx desc.
|
||||||
|
* The status for the normal FIFO is represented with bit TXNSTAT where
|
||||||
|
* 0=success, 1= failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXSTAT);
|
||||||
|
|
||||||
|
/* TXNSTAT = 0: Transmission was successful
|
||||||
|
* TXNSTAT = 1: Transmission failed, retry count exceeded
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (reg & MRF24J40_TXSTAT_TXNSTAT)
|
||||||
|
{
|
||||||
|
/* The number of retries of the most recent transmission is contained in the
|
||||||
|
* TXNRETRY (TXSTAT 0x24<7:6>) bits. The CCAFAIL (TXSTAT 0x24<5>) bit = 1
|
||||||
|
* indicates if the failed transmission was due to the channel busy
|
||||||
|
* (CSMA-CA timed out).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (reg & MRF24J40_TXSTAT_CCAFAIL)
|
||||||
|
{
|
||||||
|
status = IEEE802154_STATUS_CHANNEL_ACCESS_FAILURE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = IEEE802154_STATUS_NO_ACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = IEEE802154_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
framepending = (mrf24j40_getreg(dev->spi, MRF24J40_TXNCON) &
|
||||||
|
MRF24J40_TXNCON_FPSTAT);
|
||||||
|
|
||||||
|
if (dev->txdelayed_busy)
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Inform the next layer of the transmission success/failure */
|
||||||
|
|
||||||
|
dev->txdelayed_desc->conf->status = status;
|
||||||
|
dev->txdelayed_desc->framepending = framepending;
|
||||||
|
dev->radiocb->txdone(dev->radiocb, dev->txdelayed_desc);
|
||||||
|
|
||||||
|
dev->txdelayed_busy = false;
|
||||||
|
|
||||||
|
if (dev->reschedule_csma)
|
||||||
|
{
|
||||||
|
mrf24j40_norm_setup(dev, dev->csma_desc->frame, true);
|
||||||
|
mrf24j40_norm_trigger(dev);
|
||||||
|
dev->reschedule_csma = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Inform the next layer of the transmission success/failure */
|
||||||
|
|
||||||
|
dev->csma_desc->conf->status = status;
|
||||||
|
dev->csma_desc->framepending = framepending;
|
||||||
|
dev->radiocb->txdone(dev->radiocb, dev->csma_desc);
|
||||||
|
|
||||||
|
/* We are now done with the transaction */
|
||||||
|
|
||||||
|
dev->csma_busy = 0;
|
||||||
|
|
||||||
|
/* Must unlock the radio before calling poll */
|
||||||
|
|
||||||
|
sem_post(&dev->exclsem);
|
||||||
|
mrf24j40_dopoll_csma(dev);
|
||||||
|
while (sem_wait(&dev->exclsem) != 0) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_irqwork_gts
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Manage completion of packet transmission.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_irqwork_txgts(FAR struct mrf24j40_radio_s *dev,
|
||||||
|
uint8_t gts)
|
||||||
|
{
|
||||||
|
uint8_t txstat;
|
||||||
|
|
||||||
|
/* Disable tx int */
|
||||||
|
|
||||||
|
txstat = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
txstat |= MRF24J40_INTCON_TXNIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, txstat);
|
||||||
|
|
||||||
|
/* Get the status from the device and copy the status into the tx desc.
|
||||||
|
* The status for the normal FIFO is represented with bit TXNSTAT where
|
||||||
|
* 0=success, 1= failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
txstat = mrf24j40_getreg(dev->spi, MRF24J40_TXSTAT);
|
||||||
|
|
||||||
|
if (gts == 0)
|
||||||
|
{
|
||||||
|
dev->csma_desc->conf->status = txstat & MRF24J40_TXSTAT_TXG1STAT;
|
||||||
|
}
|
||||||
|
else if (gts == 1)
|
||||||
|
{
|
||||||
|
dev->csma_desc->conf->status = txstat & MRF24J40_TXSTAT_TXG2STAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inform the next layer of the transmission success/failure */
|
||||||
|
|
||||||
|
dev->radiocb->txdone(dev->radiocb, dev->gts_desc[gts]);
|
||||||
|
|
||||||
|
/* We are now done with the transaction */
|
||||||
|
|
||||||
|
dev->gts_busy[gts]= 0;
|
||||||
|
|
||||||
|
mrf24j40_dopoll_gts(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_irqwork_rx
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Manage packet reception.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev)
|
||||||
|
|
||||||
|
{
|
||||||
|
FAR struct ieee802154_data_ind_s *ind;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t index;
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
wlinfo("RX interrupt\n");
|
||||||
|
|
||||||
|
/* Disable rx int */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg |= MRF24J40_INTCON_RXIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
|
||||||
|
/* Disable packet reception. See pg. 109 of datasheet */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, MRF24J40_BBREG1_RXDECINV);
|
||||||
|
|
||||||
|
/* Allocate a data_ind to put the frame in */
|
||||||
|
|
||||||
|
ind = ieee802154_ind_allocate();
|
||||||
|
if (ind == NULL)
|
||||||
|
{
|
||||||
|
wlerr("ERROR: Unable to allocate data_ind. Discarding frame\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read packet */
|
||||||
|
|
||||||
|
addr = MRF24J40_RXBUF_BASE;
|
||||||
|
|
||||||
|
ind->frame->io_len = mrf24j40_getreg(dev->spi, addr++);
|
||||||
|
|
||||||
|
for (index = 0; index < ind->frame->io_len; index++)
|
||||||
|
{
|
||||||
|
ind->frame->io_data[index] = mrf24j40_getreg(dev->spi, addr++);
|
||||||
|
}
|
||||||
|
|
||||||
|
ind->lqi = mrf24j40_getreg(dev->spi, addr++);
|
||||||
|
ind->rssi = mrf24j40_getreg(dev->spi, addr++);
|
||||||
|
|
||||||
|
/* Reduce len by 2, we only receive frames with correct crc, no check
|
||||||
|
* required.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ind->frame->io_len -= 2;
|
||||||
|
|
||||||
|
/* Callback the receiver in the next highest layer */
|
||||||
|
|
||||||
|
dev->radiocb->rxframe(dev->radiocb, ind);
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* Enable reception of next packet by flushing the fifo.
|
||||||
|
* This is an MRF24J40 errata (no. 1).
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RXFLUSH, 1);
|
||||||
|
|
||||||
|
/* Only enable RX interrupt if we are to be listening when IDLE */
|
||||||
|
|
||||||
|
if (dev->rxenabled)
|
||||||
|
{
|
||||||
|
/* Enable packet reception */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, 0);
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg &= ~MRF24J40_INTCON_RXIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_irqworker
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform interrupt handling logic outside of the interrupt handler (on
|
||||||
|
* the work queue thread).
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* arg - The reference to the driver structure (cast to void*)
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_irqworker(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg;
|
||||||
|
uint8_t intstat;
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
DEBUGASSERT(dev->spi);
|
||||||
|
|
||||||
|
/* Get exclusive access to the driver */
|
||||||
|
|
||||||
|
while (sem_wait(&dev->exclsem) != 0) { }
|
||||||
|
|
||||||
|
/* Read and store INTSTAT - this clears the register. */
|
||||||
|
|
||||||
|
intstat = mrf24j40_getreg(dev->spi, MRF24J40_INTSTAT);
|
||||||
|
|
||||||
|
/* Do work according to the pending interrupts */
|
||||||
|
|
||||||
|
if ((intstat & MRF24J40_INTSTAT_HSYMTMRIF))
|
||||||
|
{
|
||||||
|
/* As of now the only use for the MAC timer is for delayed transactions.
|
||||||
|
* Therefore, all we do here is trigger the TX norm FIFO
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_norm_trigger(dev);
|
||||||
|
|
||||||
|
/* Timers are one-shot, so disable the interrupt */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg |= MRF24J40_INTCON_HSYMTMRIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((intstat & MRF24J40_INTSTAT_RXIF) && dev->rxenabled)
|
||||||
|
{
|
||||||
|
/* A packet was received, retrieve it */
|
||||||
|
|
||||||
|
mrf24j40_irqwork_rx(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((intstat & MRF24J40_INTSTAT_TXNIF))
|
||||||
|
{
|
||||||
|
/* A packet was transmitted or failed*/
|
||||||
|
|
||||||
|
mrf24j40_irqwork_txnorm(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((intstat & MRF24J40_INTSTAT_TXG1IF))
|
||||||
|
{
|
||||||
|
/* A packet was transmitted or failed*/
|
||||||
|
|
||||||
|
mrf24j40_irqwork_txgts(dev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((intstat & MRF24J40_INTSTAT_TXG1IF))
|
||||||
|
{
|
||||||
|
/* A packet was transmitted or failed*/
|
||||||
|
|
||||||
|
mrf24j40_irqwork_txgts(dev, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((intstat & MRF24J40_INTSTAT_SLPIF))
|
||||||
|
{
|
||||||
|
dev->radiocb->sfevent(dev->radiocb, IEEE802154_SFEVENT_ENDOFACTIVE);
|
||||||
|
|
||||||
|
/* Acknowledge the alert and put the device to sleep */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_SLPACK);
|
||||||
|
reg |= MRF24J40_SLPACK_SLPACK;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_SLPACK, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((intstat & MRF24J40_INTSTAT_WAKEIF))
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MAC802154_SFEVENT_VERBOSE
|
||||||
|
wlinfo("Wake Interrupt\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dev->devmode != IEEE802154_DEVMODE_ENDPOINT)
|
||||||
|
{
|
||||||
|
/* This is right before the beacon, we set the bsn here, since the MAC
|
||||||
|
* uses the SLPIF (end of active portion of superframe). to make any
|
||||||
|
* changes to the beacon. This assumes that any changes to the beacon
|
||||||
|
* be in by the time that this interrupt fires.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BEACON_FIFO + 4, dev->bsn++);
|
||||||
|
mrf24j40_beacon_trigger(dev);
|
||||||
|
wlinfo("Beacon triggered. BSN: 0x%02X\n", dev->bsn-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the radio device */
|
||||||
|
|
||||||
|
sem_post(&dev->exclsem);
|
||||||
|
|
||||||
|
/* Re-enable GPIO interrupts */
|
||||||
|
|
||||||
|
dev->lower->enable(dev->lower, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_interrupt
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Hardware interrupt handler
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* irq - Number of the IRQ that generated the interrupt
|
||||||
|
* context - Interrupt register state save info (architecture-specific)
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev != NULL);
|
||||||
|
|
||||||
|
/* In complex environments, we cannot do SPI transfers from the interrupt
|
||||||
|
* 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(work_available(&dev->irqwork));
|
||||||
|
|
||||||
|
/* Notice that further GPIO interrupts are disabled until the work is
|
||||||
|
* actually performed. This is to prevent overrun of the worker thread.
|
||||||
|
* Interrupts are re-enabled in enc_irqworker() when the work is completed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dev->lower->enable(dev->lower, false);
|
||||||
|
return work_queue(HPWORK, &dev->irqwork, mrf24j40_irqworker, (FAR void *)dev, 0);
|
||||||
|
}
|
749
drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.c
Normal file
749
drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.c
Normal file
@ -0,0 +1,749 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||||
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
|
#include <nuttx/wireless/ieee802154/ieee802154_radio.h>
|
||||||
|
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||||
|
|
||||||
|
#include "mrf24j40.h"
|
||||||
|
#include "mrf24j40_reg.h"
|
||||||
|
#include "mrf24j40_getset.h"
|
||||||
|
#include "mrf24j40_regops.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_mactimer(FAR struct mrf24j40_radio_s *dev, int numsymbols);
|
||||||
|
static void mrf24j40_setorder(FAR struct mrf24j40_radio_s *dev, uint8_t bo,
|
||||||
|
uint8_t so);
|
||||||
|
static void mrf24j40_slpclkcal(FAR struct mrf24j40_radio_s *dev);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static const uint8_t g_allones[8] =
|
||||||
|
{
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_mactimer(FAR struct mrf24j40_radio_s *dev, int numsymbols)
|
||||||
|
{
|
||||||
|
uint16_t nhalfsym;
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
nhalfsym = (numsymbols << 1);
|
||||||
|
|
||||||
|
/* Disable the interrupt, clear the timer count */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg |= MRF24J40_INTCON_HSYMTMRIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_HSYMTMRL, 0x00);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_HSYMTMRH, 0x00);
|
||||||
|
|
||||||
|
reg &= ~MRF24J40_INTCON_HSYMTMRIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
|
||||||
|
/* Set the timer count and enable interrupts */
|
||||||
|
|
||||||
|
reg = (nhalfsym & 0xFF);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_HSYMTMRL, reg);
|
||||||
|
|
||||||
|
reg = (nhalfsym >> 8) & 0xFF;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_HSYMTMRH, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setorder
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Configures the timers and sets the ORDER register
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mrf24j40_setorder(FAR struct mrf24j40_radio_s *dev, uint8_t bo,
|
||||||
|
uint8_t so)
|
||||||
|
{
|
||||||
|
uint32_t bi = MRF24J40_BEACONINTERVAL_NSEC(bo);
|
||||||
|
uint32_t sfduration = MRF24J40_SUPERFRAMEDURATION_NSEC(so);
|
||||||
|
uint32_t maincnt;
|
||||||
|
uint32_t remcnt;
|
||||||
|
|
||||||
|
wlinfo("bo: %d, so: %d\n", bo, so);
|
||||||
|
|
||||||
|
if (bo < 15)
|
||||||
|
{
|
||||||
|
if (dev->devmode == IEEE802154_DEVMODE_ENDPOINT)
|
||||||
|
{
|
||||||
|
wlinfo("Configuring sleep for inactive period\n");
|
||||||
|
maincnt = (bi - sfduration) / dev->slpclkper;
|
||||||
|
remcnt = ((bi - sfduration) - (maincnt * dev->slpclkper)) / 50;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wlinfo("Configuring sleep for beacon interval\n");
|
||||||
|
maincnt = bi / dev->slpclkper;
|
||||||
|
remcnt = (bi - (maincnt * dev->slpclkper)) / 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlinfo("MAINCNT: %lu, REMCNT: %lu\n", maincnt, remcnt);
|
||||||
|
|
||||||
|
/* Program the Main Counter, MAINCNT (0x229<1:0>, 0x228, 0x227, 0x226), and
|
||||||
|
* Remain Counter, REMCNT (0x225, 0x224), according to BO and SO values. Refer
|
||||||
|
* to Section 3.15.1.3 “Sleep Mode * Counters”
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_REMCNTL, (remcnt & 0xFF));
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_REMCNTH, ((remcnt >> 8) & 0xFF));
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT0, (maincnt & 0xFF));
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT1, ((maincnt >> 8) & 0xFF));
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT2, ((maincnt >> 16) & 0xFF));
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT3, ((maincnt >> 24) & 0x03));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure the BO (ORDER 0x10<7:4>) and SO (ORDER 0x10<3:0>) values.
|
||||||
|
* After configuring BO and SO, the beacon frame will be sent immediately.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_ORDER, ((bo << 4) & 0xF0) | (so & 0x0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mrf24j40_slpclkcal(FAR struct mrf24j40_radio_s *dev)
|
||||||
|
{
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
/* Select the source of SLPCLK (internal 100kHz) */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCON7, MRF24J40_RFCON7_SEL_100KHZ);
|
||||||
|
|
||||||
|
/* If the Sleep Clock Selection, SLPCLKSEL (0x207<7:6), is the internal
|
||||||
|
* oscillator (100 kHz), set SLPCLKDIV to a minimum value of 0x01.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_SLPCON1,
|
||||||
|
0x01 | MRF24J40_SLPCON1_CLKOUT_DISABLED);
|
||||||
|
|
||||||
|
/* Begin calibration by setting the SLPCALEN bit (SLPCAL2 0x20B<4>) to
|
||||||
|
* ‘1’. Sixteen samples of the SLPCLK are counted and stored in the
|
||||||
|
* SLPCAL register. No need to mask, this is the only writable bit
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_SLPCAL2, MRF24J40_SLPCAL2_SLPCALEN);
|
||||||
|
|
||||||
|
/* Calibration is complete when the SLPCALRDY bit (SLPCAL2 0x20B<7>) is
|
||||||
|
* set to ‘1’.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (!(mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL2) &
|
||||||
|
MRF24J40_SLPCAL2_SLPCALRDY))
|
||||||
|
{
|
||||||
|
up_udelay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL0);
|
||||||
|
dev->slpclkper = reg;
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL1);
|
||||||
|
dev->slpclkper |= (reg << 8);
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL2) & 0x0F;
|
||||||
|
dev->slpclkper |= (reg << 16);
|
||||||
|
|
||||||
|
dev->slpclkper = (dev->slpclkper * 50 / 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
/* Radio Interface Functions ***********************************************/
|
||||||
|
|
||||||
|
int mrf24j40_bind(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR struct ieee802154_radiocb_s *radiocb)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev != NULL);
|
||||||
|
dev->radiocb = radiocb;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: mrf24j40_txnotify
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Driver callback invoked when new TX data is available. This is a
|
||||||
|
* stimulus perform an out-of-cycle poll and, thereby, reduce the TX
|
||||||
|
* latency.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* radio - Reference to the radio driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_txnotify(FAR struct ieee802154_radio_s *radio, bool gts)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
|
||||||
|
if (gts)
|
||||||
|
{
|
||||||
|
/* Is our single work structure available? It may not be if there are
|
||||||
|
* pending interrupt actions and we will have to ignore the Tx
|
||||||
|
* availability action.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (work_available(&dev->gts_pollwork))
|
||||||
|
{
|
||||||
|
/* Schedule to serialize the poll on the worker thread. */
|
||||||
|
|
||||||
|
work_queue(HPWORK, &dev->gts_pollwork, mrf24j40_dopoll_gts, dev, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Is our single work structure available? It may not be if there are
|
||||||
|
* pending interrupt actions and we will have to ignore the Tx
|
||||||
|
* availability action.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (work_available(&dev->csma_pollwork))
|
||||||
|
{
|
||||||
|
/* Schedule to serialize the poll on the worker thread. */
|
||||||
|
|
||||||
|
work_queue(HPWORK, &dev->csma_pollwork, mrf24j40_dopoll_csma, dev, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: mrf24j40_txdelayed
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Transmit a packet without regard to supeframe structure after a certain
|
||||||
|
* number of symbols. This function is used to send Data Request responses.
|
||||||
|
* It can also be used to send data immediately if the delay is set to 0.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* radio - Reference to the radio driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_txdelayed(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR struct ieee802154_txdesc_s *txdesc,
|
||||||
|
uint32_t symboldelay)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
/* Get exclusive access to the radio device */
|
||||||
|
|
||||||
|
if (sem_wait(&dev->exclsem) != 0)
|
||||||
|
{
|
||||||
|
return -EINTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There should never be more than one of these transactions at once. */
|
||||||
|
|
||||||
|
DEBUGASSERT(!dev->txdelayed_busy);
|
||||||
|
|
||||||
|
dev->txdelayed_desc = txdesc;
|
||||||
|
dev->txdelayed_busy = true;
|
||||||
|
|
||||||
|
/* Disable the TX norm interrupt and clear it */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg |= MRF24J40_INTCON_TXNIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
|
||||||
|
/* If after disabling the interrupt, the irqworker is not scheduled, there
|
||||||
|
* are no interrupts to worry about. However, if there is work scheduled,
|
||||||
|
* we need to process it before going any further.
|
||||||
|
* FIXME: I think this could be done cleaner.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!work_available(&dev->irqwork))
|
||||||
|
{
|
||||||
|
sem_post(&dev->exclsem);
|
||||||
|
mrf24j40_irqworker((FAR void *)dev);
|
||||||
|
|
||||||
|
/* Get exclusive access to the radio device */
|
||||||
|
|
||||||
|
if (sem_wait(&dev->exclsem) != 0)
|
||||||
|
{
|
||||||
|
return -EINTR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->csma_busy)
|
||||||
|
{
|
||||||
|
dev->reschedule_csma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrf24j40_norm_setup(dev, txdesc->frame, false);
|
||||||
|
|
||||||
|
if (symboldelay == 0)
|
||||||
|
{
|
||||||
|
mrf24j40_norm_trigger(dev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mrf24j40_mactimer(dev, symboldelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
sem_post(&dev->exclsem);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_rxenable
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Enable/Disable receiver.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_rxenable(FAR struct ieee802154_radio_s *radio, bool enable)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
dev->rxenabled = enable;
|
||||||
|
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
/* Disable packet reception. See pg. 109 of datasheet */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, MRF24J40_BBREG1_RXDECINV);
|
||||||
|
|
||||||
|
/* Enable rx int */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg &= ~MRF24J40_INTCON_RXIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
|
||||||
|
/* Purge the RX buffer */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_RXFLUSH);
|
||||||
|
reg |= MRF24J40_RXFLUSH_RXFLUSH;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RXFLUSH, reg);
|
||||||
|
|
||||||
|
/* Re-enable packet reception. See pg. 109 of datasheet */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable rx int */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg |= MRF24J40_INTCON_RXIE;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrf24j40_reset(FAR struct ieee802154_radio_s *radio)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
struct ieee802154_cca_s cca;
|
||||||
|
int reg;
|
||||||
|
|
||||||
|
/* Software reset */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_SOFTRST , 0x07); /* 00000111 Reset */
|
||||||
|
while(mrf24j40_getreg(dev->spi, MRF24J40_SOFTRST) & 0x07);
|
||||||
|
|
||||||
|
/* Apply recommended settings */
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_PACON2 , 0x98); /* 10011000 Enable FIFO (default), TXONTS=6 (recommended), TXONT<8:7>=0 */
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXSTBL , 0x95); /* 10010101 set the SIFS period. RFSTBL=9, MSIFS=5, aMinSIFSPeriod=14 (min 12) */
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXPEND , 0x7C); /* 01111100 set the LIFS period, MLIFS=1Fh=31 aMinLIFSPeriod=40 (min 40) */
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXTIME , 0x30); /* 00110000 set the turnaround time, TURNTIME=3 aTurnAroundTime=12 */
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCON1 , 0x02); /* 00000010 VCO optimization, recommended value */
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCON2 , 0x80); /* 10000000 Enable PLL */
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCON6 , 0x90); /* 10010000 TX filter enable, fast 20M recovery, No bat monitor*/
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCON7 , 0x80); /* 10000000 Sleep clock on internal 100 kHz */
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCON8 , 0x10); /* 00010000 VCO control bit, as recommended */
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BBREG6 , 0x40); /* 01000000 Append RSSI to rx packets */
|
||||||
|
|
||||||
|
/* Calibrate the Sleep Clock (SLPCLK) frequency. Refer to Section 3.15.1.2
|
||||||
|
* “Sleep Clock Calibration”.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_slpclkcal(dev);
|
||||||
|
|
||||||
|
/* For now, we want to always just have the frame pending bit set when
|
||||||
|
* acknowledging a Data Request command. The standard says that the coordinator
|
||||||
|
* can do this if it needs time to figure out whether it has data or not
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_ACKTMOUT, 0x39 | MRF24J40_ACKTMOUT_DRPACK);
|
||||||
|
|
||||||
|
/* Set WAKETIME to recommended value for 100kHz SLPCLK Source.
|
||||||
|
*
|
||||||
|
* NOTE!!!: The datasheet specifies that WAKETIME > WAKECNT. It appears that
|
||||||
|
* it is even sensitive to the order in which you set WAKECNT and WAKETIME.
|
||||||
|
* Meaning, if you set WAKECNT first and it goes higher than WAKETIME, and
|
||||||
|
* then raise WAKETIME above WAKECNT, the device will not function correctly.
|
||||||
|
* Therefore, be careful when changing these registers
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_WAKETIMEL, 0xD2);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_WAKETIMEH, 0x00);
|
||||||
|
|
||||||
|
/* Set WAKECNT (SLPACK 0x35<6:0>) value = 0x5F to set the main oscillator
|
||||||
|
* (20 MHz) start-up timer value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_SLPACK, (0x0C8 & MRF24J40_SLPACK_WAKECNT0_6));
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_RFCTL);
|
||||||
|
reg &= ~MRF24J40_RFCTRL_WAKECNT7_8;
|
||||||
|
reg |= ((0x0C8 >> 7) & 0x03) << 3;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RFCTL, reg);
|
||||||
|
|
||||||
|
/* Enable the SLPIF and WAKEIF flags */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
|
||||||
|
reg &= ~(MRF24J40_INTCON_SLPIE | MRF24J40_INTCON_WAKEIE);
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
|
||||||
|
|
||||||
|
mrf24j40_setorder(dev, 15, 15);
|
||||||
|
|
||||||
|
dev->rxenabled = false;
|
||||||
|
|
||||||
|
mrf24j40_setchannel(dev, 11);
|
||||||
|
mrf24j40_setpanid(dev, g_allones);
|
||||||
|
mrf24j40_setsaddr(dev, g_allones);
|
||||||
|
mrf24j40_seteaddr(dev, g_allones);
|
||||||
|
|
||||||
|
dev->max_frame_waittime = MRF24J40_DEFAULT_MAX_FRAME_WAITTIME;
|
||||||
|
dev->bsn = 0;
|
||||||
|
|
||||||
|
/* Default device params */
|
||||||
|
|
||||||
|
cca.use_ed = 1;
|
||||||
|
cca.use_cs = 0;
|
||||||
|
cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */
|
||||||
|
mrf24j40_setcca(dev, &cca);
|
||||||
|
|
||||||
|
mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL);
|
||||||
|
|
||||||
|
mrf24j40_settxpower(dev, 0); /*16. Set transmitter power .*/
|
||||||
|
|
||||||
|
mrf24j40_setpamode(dev, MRF24J40_PA_AUTO);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrf24j40_getattr(FAR struct ieee802154_radio_s *radio,
|
||||||
|
enum ieee802154_attr_e attr,
|
||||||
|
FAR union ieee802154_attr_u *attrval)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (attr)
|
||||||
|
{
|
||||||
|
case IEEE802154_ATTR_MAC_EADDR:
|
||||||
|
{
|
||||||
|
memcpy(&attrval->mac.eaddr[0], &dev->addr.eaddr[0], 8);
|
||||||
|
ret = IEEE802154_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_MAC_MAX_FRAME_WAITTIME:
|
||||||
|
{
|
||||||
|
attrval->mac.max_frame_waittime = dev->max_frame_waittime;
|
||||||
|
ret = IEEE802154_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_PHY_SYMBOL_DURATION:
|
||||||
|
{
|
||||||
|
attrval->phy.symdur_picosec = MRF24J40_SYMBOL_DURATION_PS;
|
||||||
|
ret = IEEE802154_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_PHY_CHAN:
|
||||||
|
{
|
||||||
|
attrval->phy.chan = dev->chan;
|
||||||
|
ret = IEEE802154_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrf24j40_setattr(FAR struct ieee802154_radio_s *radio,
|
||||||
|
enum ieee802154_attr_e attr,
|
||||||
|
FAR const union ieee802154_attr_u *attrval)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
int ret = IEEE802154_STATUS_SUCCESS;;
|
||||||
|
|
||||||
|
switch (attr)
|
||||||
|
{
|
||||||
|
case IEEE802154_ATTR_MAC_PANID:
|
||||||
|
{
|
||||||
|
mrf24j40_setpanid(dev, attrval->mac.panid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_MAC_SADDR:
|
||||||
|
{
|
||||||
|
mrf24j40_setsaddr(dev, attrval->mac.saddr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_MAC_EADDR:
|
||||||
|
{
|
||||||
|
mrf24j40_seteaddr(dev, attrval->mac.eaddr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_MAC_COORD_SADDR:
|
||||||
|
{
|
||||||
|
mrf24j40_setcoordsaddr(dev, attrval->mac.coordsaddr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_MAC_COORD_EADDR:
|
||||||
|
{
|
||||||
|
mrf24j40_setcoordeaddr(dev, attrval->mac.coordeaddr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_MAC_PROMISCUOUS_MODE:
|
||||||
|
{
|
||||||
|
if (attrval->mac.promisc_mode)
|
||||||
|
{
|
||||||
|
mrf24j40_setrxmode(dev, MRF24J40_RXMODE_PROMISC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_PHY_CHAN:
|
||||||
|
{
|
||||||
|
mrf24j40_setchannel(dev, attrval->phy.chan);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_MAC_DEVMODE:
|
||||||
|
{
|
||||||
|
mrf24j40_setdevmode(dev, attrval->mac.devmode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR const struct ieee802154_superframespec_s *sfspec,
|
||||||
|
FAR struct ieee802154_beaconframe_s *beacon)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
int reg;
|
||||||
|
|
||||||
|
if (sfspec->pancoord)
|
||||||
|
{
|
||||||
|
/* Set the PANCOORD (RXMCR 0x00<3>) bit = 1to configure as PAN coordinator */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR);
|
||||||
|
reg |= MRF24J40_RXMCR_PANCOORD;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg);
|
||||||
|
|
||||||
|
/* Set the SLOTTED (TXMCR 0x11<5>) bit = 1 to use Slotted CSMA-CA mode */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXMCR);
|
||||||
|
reg |= MRF24J40_TXMCR_SLOTTED;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXMCR, reg);
|
||||||
|
|
||||||
|
/* Load the beacon frame into the TXBFIFO (0x080-0x0FF). */
|
||||||
|
|
||||||
|
mrf24j40_setup_fifo(dev, beacon->bf_data, beacon->bf_len, MRF24J40_BEACON_FIFO);
|
||||||
|
|
||||||
|
/* The radio layer is responsible for setting the BSN. */
|
||||||
|
|
||||||
|
dev->bsn = 0;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_BEACON_FIFO + 4, dev->bsn++);
|
||||||
|
|
||||||
|
/* Set the TXBMSK (TXBCON1 0x25<7>) bit = 1 to mask the beacon interrupt
|
||||||
|
* mask
|
||||||
|
*/
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXBCON1);
|
||||||
|
reg |= MRF24J40_TXBCON1_TXBMSK;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXBCON1, reg);
|
||||||
|
|
||||||
|
/* Set INTL (WAKECON 0x22<5:0>) value to 0x03. */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_WAKECON);
|
||||||
|
reg &= ~MRF24J40_WAKECON_INTL;
|
||||||
|
reg |= 0x03 & MRF24J40_WAKECON_INTL;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_WAKECON, reg);
|
||||||
|
|
||||||
|
/* Program the CAP end slot (ESLOTG1 0x13<3:0>) value. */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_ESLOTG1);
|
||||||
|
reg &= ~MRF24J40_ESLOTG1_CAP;
|
||||||
|
reg |= sfspec->final_capslot & MRF24J40_ESLOTG1_CAP;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_ESLOTG1, reg);
|
||||||
|
|
||||||
|
/* TODO: Add GTS related code. See pg 100 of datasheet */
|
||||||
|
|
||||||
|
mrf24j40_setorder(dev, sfspec->beaconorder, sfspec->sforder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -ENOTTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrf24j40_beaconupdate(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR struct ieee802154_beaconframe_s *beacon)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
|
||||||
|
mrf24j40_setup_fifo(dev, beacon->bf_data, beacon->bf_len, MRF24J40_BEACON_FIFO);
|
||||||
|
mrf24j40_beacon_trigger(dev);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrf24j40_beaconstop(FAR struct ieee802154_radio_s *radio)
|
||||||
|
{
|
||||||
|
return -ENOTTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrf24j40_sfupdate(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR const struct ieee802154_superframespec_s *sfspec)
|
||||||
|
{
|
||||||
|
FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
|
||||||
|
int reg;
|
||||||
|
|
||||||
|
/* If we are operating on a beacon-enabled network, use slotted CSMA */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXMCR);
|
||||||
|
if (sfspec->beaconorder < 15)
|
||||||
|
{
|
||||||
|
reg |= MRF24J40_TXMCR_SLOTTED;
|
||||||
|
|
||||||
|
if (dev->devmode == IEEE802154_DEVMODE_ENDPOINT)
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_FRMOFFSET, 0x15);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_FRMOFFSET, 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reg &= ~MRF24J40_TXMCR_SLOTTED;
|
||||||
|
}
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_TXMCR, reg);
|
||||||
|
|
||||||
|
mrf24j40_setorder(dev, sfspec->beaconorder, sfspec->sforder);
|
||||||
|
|
||||||
|
/* Program the CAP end slot (ESLOTG1 0x13<3:0>) value. */
|
||||||
|
|
||||||
|
reg = mrf24j40_getreg(dev->spi, MRF24J40_ESLOTG1);
|
||||||
|
reg &= ~MRF24J40_ESLOTG1_CAP;
|
||||||
|
reg |= sfspec->final_capslot & MRF24J40_ESLOTG1_CAP;
|
||||||
|
mrf24j40_setreg(dev->spi, MRF24J40_ESLOTG1, reg);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
72
drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.h
Normal file
72
drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.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_MRF24J40_RADIF_H
|
||||||
|
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_RADIF_H
|
||||||
|
|
||||||
|
int mrf24j40_bind(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR struct ieee802154_radiocb_s *radiocb);
|
||||||
|
|
||||||
|
int mrf24j40_reset(FAR struct ieee802154_radio_s *radio);
|
||||||
|
|
||||||
|
int mrf24j40_getattr(FAR struct ieee802154_radio_s *radio,
|
||||||
|
enum ieee802154_attr_e attr,
|
||||||
|
FAR union ieee802154_attr_u *attrval);
|
||||||
|
|
||||||
|
int mrf24j40_setattr(FAR struct ieee802154_radio_s *radio,
|
||||||
|
enum ieee802154_attr_e attr,
|
||||||
|
FAR const union ieee802154_attr_u *attrval);
|
||||||
|
|
||||||
|
int mrf24j40_txnotify(FAR struct ieee802154_radio_s *radio, bool gts);
|
||||||
|
|
||||||
|
int mrf24j40_txdelayed(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR struct ieee802154_txdesc_s *txdesc,
|
||||||
|
uint32_t symboldelay);
|
||||||
|
|
||||||
|
int mrf24j40_rxenable(FAR struct ieee802154_radio_s *radio, bool enable);
|
||||||
|
|
||||||
|
int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR const struct ieee802154_superframespec_s *sfspec,
|
||||||
|
FAR struct ieee802154_beaconframe_s *beacon);
|
||||||
|
|
||||||
|
int mrf24j40_beaconupdate(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR struct ieee802154_beaconframe_s *beacon);
|
||||||
|
|
||||||
|
int mrf24j40_beaconstop(FAR struct ieee802154_radio_s *radio);
|
||||||
|
|
||||||
|
int mrf24j40_sfupdate(FAR struct ieee802154_radio_s *radio,
|
||||||
|
FAR const struct ieee802154_superframespec_s *sfspec);
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_RADIF_H */
|
@ -1,8 +1,10 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/wireless/ieee802154/mrf24j40.h
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_reg.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||||
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
* Author: Anthony Merlino <anthony@vergeaero.com>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -33,8 +35,8 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H
|
#ifndef __DRIVERS_WIRELESS_IEEE802154_MRF24J40_REG_H
|
||||||
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H
|
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_REG_H
|
||||||
|
|
||||||
/* MRF24J40 Registers *******************************************************/
|
/* MRF24J40 Registers *******************************************************/
|
||||||
|
|
||||||
@ -226,6 +228,11 @@
|
|||||||
#define MRF24J40_TXSTAT_X_SHIFT 6
|
#define MRF24J40_TXSTAT_X_SHIFT 6
|
||||||
#define MRF24J40_TXSTAT_X_MASK (3 << MRF24J40_TXSTAT_X_SHIFT)
|
#define MRF24J40_TXSTAT_X_MASK (3 << MRF24J40_TXSTAT_X_SHIFT)
|
||||||
|
|
||||||
|
/* TXBCON0 bits */
|
||||||
|
|
||||||
|
#define MRF24J40_TXBCON0_TXBTRIG 0x01
|
||||||
|
#define MRF24J40_TXBCON0_TXBSECEN 0x02
|
||||||
|
|
||||||
/* TXBCON1 bits */
|
/* TXBCON1 bits */
|
||||||
|
|
||||||
#define MRF24J40_TXBCON1_RSSINUM 0x30
|
#define MRF24J40_TXBCON1_RSSINUM 0x30
|
||||||
@ -265,6 +272,13 @@
|
|||||||
#define MRF24J40_SLPACK_WAKECNT0_6 0x7F
|
#define MRF24J40_SLPACK_WAKECNT0_6 0x7F
|
||||||
#define MRF24J40_SLPACK_SLPACK 0x80
|
#define MRF24J40_SLPACK_SLPACK 0x80
|
||||||
|
|
||||||
|
/* RFCTL bits */
|
||||||
|
|
||||||
|
#define MRF24J40_RFCTRL_RFRXMODE 0x01
|
||||||
|
#define MRF24J40_RFCTRL_RFTXMODE 0x02
|
||||||
|
#define MRF24J40_RFCTRL_RFRST 0x03
|
||||||
|
#define MRF24J40_RFCTRL_WAKECNT7_8 0x18
|
||||||
|
|
||||||
/* RXFLUSH bits */
|
/* RXFLUSH bits */
|
||||||
|
|
||||||
#define MRF24J40_RXFLUSH_RXFLUSH 0x01
|
#define MRF24J40_RXFLUSH_RXFLUSH 0x01
|
||||||
@ -281,4 +295,8 @@
|
|||||||
#define MRF24J40_RXFLUSH_SHIFT_WAKEPAD 5
|
#define MRF24J40_RXFLUSH_SHIFT_WAKEPAD 5
|
||||||
#define MRF24J40_RXFLUSH_SHIFT_WAKEPOL 6
|
#define MRF24J40_RXFLUSH_SHIFT_WAKEPOL 6
|
||||||
|
|
||||||
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H */
|
/* SLPCON1 bits */
|
||||||
|
|
||||||
|
#define MRF24J40_SLPCON1_CLKOUT_DISABLED 0x20
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_REG_H */
|
191
drivers/wireless/ieee802154/mrf24j40/mrf24j40_regops.c
Normal file
191
drivers/wireless/ieee802154/mrf24j40/mrf24j40_regops.c
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_regops.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||||
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "mrf24j40.h"
|
||||||
|
#include "mrf24j40_regops.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Internal Driver Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_setreg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Define the value of an MRF24J40 device register
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr, uint8_t val)
|
||||||
|
{
|
||||||
|
uint8_t buf[3];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!(addr&0x80000000))
|
||||||
|
{
|
||||||
|
addr &= 0x3F; /* 6-bit address */
|
||||||
|
addr <<= 1;
|
||||||
|
addr |= 0x01; /* writing */
|
||||||
|
buf[0] = addr;
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr &= 0x3FF; /* 10-bit address */
|
||||||
|
addr <<= 5;
|
||||||
|
addr |= 0x8010; /* writing long */
|
||||||
|
buf[0] = (addr >> 8);
|
||||||
|
buf[1] = (addr & 0xFF);
|
||||||
|
len = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[len++] = val;
|
||||||
|
|
||||||
|
mrf24j40_spi_lock(spi);
|
||||||
|
SPI_SELECT(spi, SPIDEV_IEEE802154(0), true);
|
||||||
|
SPI_SNDBLOCK(spi, buf, len);
|
||||||
|
SPI_SELECT(spi, SPIDEV_IEEE802154(0), false);
|
||||||
|
mrf24j40_spi_unlock(spi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_getreg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return the value of an MRF24J40 device register*
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
uint8_t mrf24j40_getreg(FAR struct spi_dev_s *spi, uint32_t addr)
|
||||||
|
{
|
||||||
|
uint8_t buf[3];
|
||||||
|
uint8_t rx[3];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!(addr&0x80000000))
|
||||||
|
{
|
||||||
|
/* 6-bit address */
|
||||||
|
|
||||||
|
addr &= 0x3F;
|
||||||
|
addr <<= 1;
|
||||||
|
buf[0] = addr;
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 10-bit address */
|
||||||
|
|
||||||
|
addr &= 0x3FF;
|
||||||
|
addr <<= 5;
|
||||||
|
addr |= 0x8000;
|
||||||
|
buf[0] = (addr >> 8);
|
||||||
|
buf[1] = (addr & 0xFF);
|
||||||
|
len = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[len++] = 0xFF; /* dummy */
|
||||||
|
|
||||||
|
mrf24j40_spi_lock (spi);
|
||||||
|
SPI_SELECT (spi, SPIDEV_IEEE802154(0), true);
|
||||||
|
SPI_EXCHANGE (spi, buf, rx, len);
|
||||||
|
SPI_SELECT (spi, SPIDEV_IEEE802154(0), false);
|
||||||
|
mrf24j40_spi_unlock(spi);
|
||||||
|
|
||||||
|
/* wlinfo("r[%04X]=%02X\n", addr, rx[len - 1]); */
|
||||||
|
return rx[len - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mrf24j40_regdump
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Display the value of all registers.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mrf24j40_regdump(FAR struct mrf24j40_radio_s *dev)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
char buf[4+16*3+2+1];
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
wlinfo("Short regs:\n");
|
||||||
|
|
||||||
|
for (i = 0; i < 0x40; i++)
|
||||||
|
{
|
||||||
|
if ((i & 15) == 0)
|
||||||
|
{
|
||||||
|
len=sprintf(buf, "%02x: ",i&0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
len += sprintf(buf+len, "%02x ", mrf24j40_getreg(dev->spi, i));
|
||||||
|
if ((i & 15) == 15)
|
||||||
|
{
|
||||||
|
sprintf(buf+len, "\n");
|
||||||
|
wlinfo("%s", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wlinfo("Long regs:\n");
|
||||||
|
|
||||||
|
for (i = 0x80000200; i < 0x80000250; i++)
|
||||||
|
{
|
||||||
|
if ((i & 15) == 0)
|
||||||
|
{
|
||||||
|
len=sprintf(buf, "%02x: ",i&0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
len += sprintf(buf+len, "%02x ", mrf24j40_getreg(dev->spi, i));
|
||||||
|
if ((i & 15) == 15)
|
||||||
|
{
|
||||||
|
sprintf(buf+len, "\n");
|
||||||
|
wlinfo("%s", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
47
drivers/wireless/ieee802154/mrf24j40/mrf24j40_regops.h
Normal file
47
drivers/wireless/ieee802154/mrf24j40/mrf24j40_regops.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_regops.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
|
||||||
|
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||||
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
|
* 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_MRF24J40_REGOPS_H
|
||||||
|
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_REGOPS_H
|
||||||
|
|
||||||
|
void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr, uint8_t val);
|
||||||
|
|
||||||
|
uint8_t mrf24j40_getreg(FAR struct spi_dev_s *spi, uint32_t addr);
|
||||||
|
|
||||||
|
int mrf24j40_regdump(FAR struct mrf24j40_radio_s *dev);
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_REGOPS_H */
|
@ -423,26 +423,30 @@ enum ieee802154_attr_e
|
|||||||
IEEE802154_ATTR_MAC_SADDR,
|
IEEE802154_ATTR_MAC_SADDR,
|
||||||
IEEE802154_ATTR_MAC_SUPERFRAME_ORDER,
|
IEEE802154_ATTR_MAC_SUPERFRAME_ORDER,
|
||||||
IEEE802154_ATTR_MAC_SYNC_SYMBOL_OFFSET,
|
IEEE802154_ATTR_MAC_SYNC_SYMBOL_OFFSET,
|
||||||
IEEE802154_PIB_MAC_TIMESTAMP_SUPPORT,
|
IEEE802154_ATTR_MAC_TIMESTAMP_SUPPORT,
|
||||||
IEEE802154_PIB_MAC_TRANSACTION_PERSIST_TIME,
|
IEEE802154_ATTR_MAC_TRANSACTION_PERSIST_TIME,
|
||||||
IEEE802154_PIB_MAC_TX_CTRL_ACTIVE_DUR,
|
IEEE802154_ATTR_MAC_TX_CTRL_ACTIVE_DUR,
|
||||||
IEEE802154_PIB_MAC_TX_CTRL_PAUSE_DUR,
|
IEEE802154_ATTR_MAC_TX_CTRL_PAUSE_DUR,
|
||||||
IEEE802154_PIB_MAC_TX_TOTAL_DUR,
|
IEEE802154_ATTR_MAC_TX_TOTAL_DUR,
|
||||||
IEEE802154_ATTR_MAC_DEVMODE, /* Non-standard */
|
IEEE802154_ATTR_MAC_DEVMODE, /* Non-standard */
|
||||||
|
|
||||||
/* MAC Security Attributes */
|
/* MAC Security Attributes */
|
||||||
|
|
||||||
IEEE802154_PIB_MAC_KEY_TABLE = 0x70,
|
IEEE802154_ATTR_MAC_KEY_TABLE = 0x70,
|
||||||
IEEE802154_PIB_MAC_DEV_TABLE,
|
IEEE802154_ATTR_MAC_DEV_TABLE,
|
||||||
IEEE802154_PIB_MAC_SEC_LVL_TABLE,
|
IEEE802154_ATTR_MAC_SEC_LVL_TABLE,
|
||||||
IEEE802154_PIB_MAC_FRAME_COUNTER,
|
IEEE802154_ATTR_MAC_FRAME_COUNTER,
|
||||||
IEEE802154_PIB_MAC_AUTOREQ_SEC_LVL,
|
IEEE802154_ATTR_MAC_AUTOREQ_SEC_LVL,
|
||||||
IEEE802154_PIB_MAC_AUTOREQ_KEY_ID_MODE,
|
IEEE802154_ATTR_MAC_AUTOREQ_KEY_ID_MODE,
|
||||||
IEEE802154_PIB_MAC_AUTOREQ_KEY_SOURCE,
|
IEEE802154_ATTR_MAC_AUTOREQ_KEY_SOURCE,
|
||||||
IEEE802154_PIB_MAC_AUTOREQ_KEY_INDEX,
|
IEEE802154_ATTR_MAC_AUTOREQ_KEY_INDEX,
|
||||||
IEEE802154_PIB_MAC_DEFAULT_KEY_SRC,
|
IEEE802154_ATTR_MAC_DEFAULT_KEY_SRC,
|
||||||
IEEE802154_PIB_MAC_PANCOORD_EXT_ADDR,
|
IEEE802154_ATTR_MAC_PANCOORD_EXT_ADDR,
|
||||||
IEEE802154_PIB_MAC_PANCOORD_SHORT_ADDR,
|
IEEE802154_ATTR_MAC_PANCOORD_SHORT_ADDR,
|
||||||
|
|
||||||
|
/* Special Attributes */
|
||||||
|
|
||||||
|
IEEE802154_ATTR_RADIO_REGDUMP = 0xF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Frame Type */
|
/* Frame Type */
|
||||||
@ -564,11 +568,10 @@ struct ieee802154_capability_info_s
|
|||||||
|
|
||||||
struct ieee802154_superframespec_s
|
struct ieee802154_superframespec_s
|
||||||
{
|
{
|
||||||
uint16_t beaconorder : 4; /* Transmission interval of beacon */
|
uint16_t beaconorder : 4; /* Transmission interval of beacon */
|
||||||
uint16_t sforder : 4; /* Length of active portion of superframe */
|
uint16_t sforder : 4; /* Length of active portion of superframe */
|
||||||
uint16_t final_capslot : 4; /* Last slot utilized by CAP */
|
uint16_t final_capslot : 4; /* Last slot utilized by CAP */
|
||||||
uint16_t ble : 1; /* Battery Life Extension (BLE) */
|
uint16_t ble : 1; /* Battery Life Extension (BLE) */
|
||||||
uint16_t reserved : 1; /* Reserved bit */
|
|
||||||
uint16_t pancoord : 1; /* 1 if beacon sent by pan coordinator */
|
uint16_t pancoord : 1; /* 1 if beacon sent by pan coordinator */
|
||||||
uint16_t assocpermit : 1; /* 1 if coordinator is accepting associaton */
|
uint16_t assocpermit : 1; /* 1 if coordinator is accepting associaton */
|
||||||
};
|
};
|
||||||
@ -593,19 +596,10 @@ struct ieee802154_pandesc_s
|
|||||||
* in symbols */
|
* in symbols */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ieee802154_pend_addr_s
|
struct ieee802154_pendaddr_s
|
||||||
{
|
{
|
||||||
union
|
uint8_t nsaddr : 3; /* Number of short addresses pending */
|
||||||
{
|
uint8_t neaddr : 3; /* Number of extended addresses pending */
|
||||||
uint8_t pa_spec;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint8_t num_short_addr : 3; /* Number of short addresses pending */
|
|
||||||
uint8_t reserved_3 : 1; /* Reserved bit */
|
|
||||||
uint8_t num_ext_addr : 3; /* Number of extended addresses pending */
|
|
||||||
uint8_t reserved_7 : 1; /* Reserved bit */
|
|
||||||
} pa_addr;
|
|
||||||
} u;
|
|
||||||
struct ieee802154_addr_s addr[7]; /* Array of at most 7 addresses */
|
struct ieee802154_addr_s addr[7]; /* Array of at most 7 addresses */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -632,17 +626,16 @@ union ieee802154_macattr_u
|
|||||||
|
|
||||||
bool is_assoc;
|
bool is_assoc;
|
||||||
bool assocpermit;
|
bool assocpermit;
|
||||||
bool auto_req;
|
bool autoreq;
|
||||||
bool batt_life_ext;
|
bool batt_life_ext;
|
||||||
bool gts_permit;
|
bool gts_permit;
|
||||||
bool promisc_mode;
|
bool promisc_mode;
|
||||||
bool rng_support;
|
bool rng_support;
|
||||||
bool resp_waittime;
|
|
||||||
bool rxonidle;
|
bool rxonidle;
|
||||||
bool sec_enabled;
|
bool sec_enabled;
|
||||||
bool timestamp_support;
|
bool timestamp_support;
|
||||||
|
|
||||||
uint32_t ack_wait_dur;
|
uint32_t ack_waitdur;
|
||||||
uint8_t batt_life_ext_periods;
|
uint8_t batt_life_ext_periods;
|
||||||
uint8_t max_csma_backoffs : 3;
|
uint8_t max_csma_backoffs : 3;
|
||||||
uint8_t max_be : 4;
|
uint8_t max_be : 4;
|
||||||
@ -656,6 +649,7 @@ union ieee802154_macattr_u
|
|||||||
uint32_t tx_ctrl_active_dur;
|
uint32_t tx_ctrl_active_dur;
|
||||||
uint32_t tx_ctrl_pause_dur;
|
uint32_t tx_ctrl_pause_dur;
|
||||||
uint32_t tx_total_dur;
|
uint32_t tx_total_dur;
|
||||||
|
uint8_t resp_waittime;
|
||||||
|
|
||||||
uint8_t beacon_payload[IEEE802154_ATTR_MAC_BEACON_PAYLOAD_LEN];
|
uint8_t beacon_payload[IEEE802154_ATTR_MAC_BEACON_PAYLOAD_LEN];
|
||||||
uint8_t beacon_payload_len;
|
uint8_t beacon_payload_len;
|
||||||
@ -706,17 +700,17 @@ enum ieee802154_scantype_e
|
|||||||
|
|
||||||
struct ieee802154_frame_meta_s
|
struct ieee802154_frame_meta_s
|
||||||
{
|
{
|
||||||
enum ieee802154_addrmode_e srcaddr_mode; /* Source Address Mode */
|
enum ieee802154_addrmode_e srcmode; /* Source Address Mode */
|
||||||
struct ieee802154_addr_s destaddr; /* Destination Address */
|
struct ieee802154_addr_s destaddr; /* Destination Address */
|
||||||
|
|
||||||
uint8_t msdu_handle; /* Handle assoc. with MSDU */
|
uint8_t handle; /* User-specified handle identifier */
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t ack_tx : 1; /* Acknowledge TX? */
|
uint8_t ackreq : 1;
|
||||||
uint8_t gts_tx : 1; /* 1=GTS used for TX, 0=CAP used for TX */
|
uint8_t usegts : 1;
|
||||||
uint8_t indirect_tx : 1; /* Should indirect transmission be used? */
|
uint8_t indirect : 1;
|
||||||
} msdu_flags;
|
} flags;
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE802154_SECURITY
|
#ifdef CONFIG_IEEE802154_SECURITY
|
||||||
/* Security information if enabled */
|
/* Security information if enabled */
|
||||||
@ -727,7 +721,7 @@ struct ieee802154_frame_meta_s
|
|||||||
#ifdef CONFIG_IEEE802154_UWB
|
#ifdef CONFIG_IEEE802154_UWB
|
||||||
/* The UWB Pulse Repetition Frequency to be used for the transmission */
|
/* The UWB Pulse Repetition Frequency to be used for the transmission */
|
||||||
|
|
||||||
enum ieee802154_uwbprf_e uwb_prf;
|
enum ieee802154_uwbprf_e uwbprf;
|
||||||
|
|
||||||
/* The UWB preamble symbol repititions
|
/* The UWB preamble symbol repititions
|
||||||
* Should be one of:
|
* Should be one of:
|
||||||
@ -738,7 +732,7 @@ struct ieee802154_frame_meta_s
|
|||||||
|
|
||||||
/* The UWB Data Rate to be used for the transmission */
|
/* The UWB Data Rate to be used for the transmission */
|
||||||
|
|
||||||
enum ieee802154_uwb_datarate_e data_rate;
|
enum ieee802154_uwb_datarate_e datarate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum ieee802154_ranging_e ranging;
|
enum ieee802154_ranging_e ranging;
|
||||||
@ -1112,7 +1106,7 @@ struct ieee802154_disassoc_conf_s
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
struct ieee802154_beaconnotify_ind_s
|
struct ieee802154_beacon_ind_s
|
||||||
{
|
{
|
||||||
uint8_t bsn; /* Beacon sequence number */
|
uint8_t bsn; /* Beacon sequence number */
|
||||||
|
|
||||||
@ -1122,20 +1116,11 @@ struct ieee802154_beaconnotify_ind_s
|
|||||||
|
|
||||||
/* Beacon pending addresses */
|
/* Beacon pending addresses */
|
||||||
|
|
||||||
struct ieee802154_pend_addr_s pend_addr;
|
struct ieee802154_pendaddr_s pendaddr;
|
||||||
|
uint8_t payloadlength; /* # of octets contained in the beacon payload */
|
||||||
uint8_t sdu_length; /* Number of octets contained in the beacon
|
uint8_t payload[IEEE802154_MAX_BEACON_PAYLOAD_LEN];
|
||||||
* payload of the received beacond frame */
|
|
||||||
|
|
||||||
/* Beacon payload */
|
|
||||||
|
|
||||||
uint8_t sdu[IEEE802154_MAX_BEACON_PAYLOAD_LEN];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIZEOF_IEEE802154_BEACONNOTIFY_IND_S(n) \
|
|
||||||
(sizeof(struct ieee802154_beaconnotify_ind_s) \
|
|
||||||
- IEEE802154_MAX_BEACON_PAYLOAD_LEN + (n))
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Primitive: MLME-COMM-STATUS.indication
|
* Primitive: MLME-COMM-STATUS.indication
|
||||||
*
|
*
|
||||||
@ -1265,7 +1250,7 @@ struct ieee802154_orphan_resp_s
|
|||||||
|
|
||||||
struct ieee802154_reset_req_s
|
struct ieee802154_reset_req_s
|
||||||
{
|
{
|
||||||
bool rst_pibattr;
|
bool resetattr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -1538,21 +1523,21 @@ union ieee802154_notif_u
|
|||||||
|
|
||||||
/* MLME Notifications */
|
/* MLME Notifications */
|
||||||
|
|
||||||
struct ieee802154_assoc_conf_s assocconf;
|
struct ieee802154_assoc_conf_s assocconf;
|
||||||
struct ieee802154_disassoc_conf_s disassocconf;
|
struct ieee802154_disassoc_conf_s disassocconf;
|
||||||
struct ieee802154_gts_conf_s gtsconf;
|
struct ieee802154_gts_conf_s gtsconf;
|
||||||
struct ieee802154_rxenable_conf_s rxenableconf;
|
struct ieee802154_rxenable_conf_s rxenableconf;
|
||||||
struct ieee802154_scan_conf_s scanconf;
|
struct ieee802154_scan_conf_s scanconf;
|
||||||
struct ieee802154_start_conf_s startconf;
|
struct ieee802154_start_conf_s startconf;
|
||||||
struct ieee802154_poll_conf_s pollconf;
|
struct ieee802154_poll_conf_s pollconf;
|
||||||
|
|
||||||
struct ieee802154_assoc_ind_s assocind;
|
struct ieee802154_assoc_ind_s assocind;
|
||||||
struct ieee802154_disassoc_ind_s disassocind;
|
struct ieee802154_disassoc_ind_s disassocind;
|
||||||
struct ieee802154_beaconnotify_ind_s beaconnotifyind;
|
struct ieee802154_beacon_ind_s beaconind;
|
||||||
struct ieee802154_gts_ind_s gtsind;
|
struct ieee802154_gts_ind_s gtsind;
|
||||||
struct ieee802154_orphan_ind_s orphanind;
|
struct ieee802154_orphan_ind_s orphanind;
|
||||||
struct ieee802154_commstatus_ind_s commstatusind;
|
struct ieee802154_commstatus_ind_s commstatusind;
|
||||||
struct ieee802154_syncloss_ind_s synclossind;
|
struct ieee802154_syncloss_ind_s synclossind;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ieee802154_notif_s
|
struct ieee802154_notif_s
|
||||||
|
@ -80,11 +80,15 @@ struct ieee802154_txdesc_s
|
|||||||
|
|
||||||
FAR struct ieee802154_data_conf_s *conf;
|
FAR struct ieee802154_data_conf_s *conf;
|
||||||
|
|
||||||
enum ieee802154_frametype_e frametype; /* Frame type. Used by MAC layer to
|
/* Frame type. Used by MAC layer to control how tx done is handled */
|
||||||
* control how tx done is handled */
|
|
||||||
bool framepending; /* Did the ACK have the frame pending bit
|
enum ieee802154_frametype_e frametype;
|
||||||
* bit set */
|
|
||||||
uint32_t purge_time; /* Time to purge transaction */
|
bool framepending; /* Did the ACK have the frame pending bit set */
|
||||||
|
uint32_t purgetime; /* Time to purge transaction */
|
||||||
|
uint8_t retrycount; /* Number of remaining retries. Set to macMaxFrameRetries
|
||||||
|
* when txdescriptor is allocated
|
||||||
|
*/
|
||||||
|
|
||||||
/* TODO: Add slotting information for GTS transactions */
|
/* TODO: Add slotting information for GTS transactions */
|
||||||
};
|
};
|
||||||
@ -119,20 +123,18 @@ struct ieee802154_radio_s
|
|||||||
{
|
{
|
||||||
CODE int (*bind) (FAR struct ieee802154_radio_s *radio,
|
CODE int (*bind) (FAR struct ieee802154_radio_s *radio,
|
||||||
FAR struct ieee802154_radiocb_s *radiocb);
|
FAR struct ieee802154_radiocb_s *radiocb);
|
||||||
|
CODE int (*reset) (FAR struct ieee802154_radio_s *radio);
|
||||||
|
CODE int (*getattr) (FAR struct ieee802154_radio_s *radio,
|
||||||
|
enum ieee802154_attr_e ,
|
||||||
|
FAR union ieee802154_attr_u *attrval);
|
||||||
|
CODE int (*setattr) (FAR struct ieee802154_radio_s *radio,
|
||||||
|
enum ieee802154_attr_e ,
|
||||||
|
FAR const union ieee802154_attr_u *attrval);
|
||||||
CODE int (*txnotify)(FAR struct ieee802154_radio_s *radio, bool gts);
|
CODE int (*txnotify)(FAR struct ieee802154_radio_s *radio, bool gts);
|
||||||
CODE int (*txdelayed)(FAR struct ieee802154_radio_s *radio,
|
CODE int (*txdelayed)(FAR struct ieee802154_radio_s *radio,
|
||||||
FAR struct ieee802154_txdesc_s *txdesc,
|
FAR struct ieee802154_txdesc_s *txdesc,
|
||||||
uint32_t symboldelay);
|
uint32_t symboldelay);
|
||||||
CODE int (*reset_attrs) (FAR struct ieee802154_radio_s *radio);
|
|
||||||
CODE int (*get_attr) (FAR struct ieee802154_radio_s *radio,
|
|
||||||
enum ieee802154_attr_e ,
|
|
||||||
FAR union ieee802154_attr_u *attrval);
|
|
||||||
CODE int (*set_attr) (FAR struct ieee802154_radio_s *radio,
|
|
||||||
enum ieee802154_attr_e ,
|
|
||||||
FAR const union ieee802154_attr_u *attrval);
|
|
||||||
CODE int (*rxenable) (FAR struct ieee802154_radio_s *radio, bool enable);
|
CODE int (*rxenable) (FAR struct ieee802154_radio_s *radio, bool enable);
|
||||||
CODE int (*req_rxenable)(FAR struct ieee802154_radio_s *radio,
|
|
||||||
FAR struct ieee802154_rxenable_req_s *req);
|
|
||||||
CODE int (*beaconstart)(FAR struct ieee802154_radio_s *radio,
|
CODE int (*beaconstart)(FAR struct ieee802154_radio_s *radio,
|
||||||
FAR const struct ieee802154_superframespec_s *sfspec,
|
FAR const struct ieee802154_superframespec_s *sfspec,
|
||||||
FAR struct ieee802154_beaconframe_s *beacon);
|
FAR struct ieee802154_beaconframe_s *beacon);
|
||||||
|
@ -163,9 +163,9 @@ int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee,
|
|||||||
|
|
||||||
/* Source address mode */
|
/* Source address mode */
|
||||||
|
|
||||||
meta->srcaddr_mode = pktmeta->sextended != 0?
|
meta->srcmode = pktmeta->sextended != 0?
|
||||||
IEEE802154_ADDRMODE_EXTENDED :
|
IEEE802154_ADDRMODE_EXTENDED :
|
||||||
IEEE802154_ADDRMODE_SHORT;
|
IEEE802154_ADDRMODE_SHORT;
|
||||||
|
|
||||||
/* Check for a broadcast destination address (all zero) */
|
/* Check for a broadcast destination address (all zero) */
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee,
|
|||||||
|
|
||||||
if (rcvrnull)
|
if (rcvrnull)
|
||||||
{
|
{
|
||||||
meta->msdu_flags.ack_tx = TRUE;
|
meta->flags.ackreq = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destination address */
|
/* Destination address */
|
||||||
@ -223,7 +223,7 @@ int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee,
|
|||||||
* fragment of a disassembled packet.
|
* fragment of a disassembled packet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
meta->msdu_handle = ieee->i_msdu_handle++;
|
meta->handle = ieee->i_msdu_handle++;
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE802154_SECURITY
|
#ifdef CONFIG_IEEE802154_SECURITY
|
||||||
# warning CONFIG_IEEE802154_SECURITY not yet supported
|
# warning CONFIG_IEEE802154_SECURITY not yet supported
|
||||||
|
@ -83,6 +83,20 @@ config MAC802154_NPANDESC
|
|||||||
information for all unique beacons received. This is the number of unique
|
information for all unique beacons received. This is the number of unique
|
||||||
descriptors that can be held before the scan cancels with LIMIT_REACHED.
|
descriptors that can be held before the scan cancels with LIMIT_REACHED.
|
||||||
|
|
||||||
|
config MAC802154_SFEVENT_VERBOSE
|
||||||
|
bool "Verbose logging related to superframe events"
|
||||||
|
default n
|
||||||
|
depends on DEBUG_WIRELESS_INFO
|
||||||
|
---help---
|
||||||
|
Enable verbose logging of superframe events Default: false
|
||||||
|
|
||||||
|
config MAC802154_LOCK_VERBOSE
|
||||||
|
bool "Verbose logging related to MAC lock management"
|
||||||
|
default n
|
||||||
|
depends on DEBUG_WIRELESS_INFO
|
||||||
|
---help---
|
||||||
|
Enable verbose logging of MAC lock management. Default: false
|
||||||
|
|
||||||
config IEEE802154_IND_PREALLOC
|
config IEEE802154_IND_PREALLOC
|
||||||
int "Number of pre-allocated meta-data structures"
|
int "Number of pre-allocated meta-data structures"
|
||||||
default 20
|
default 20
|
||||||
|
@ -37,7 +37,7 @@ ifeq ($(CONFIG_WIRELESS_IEEE802154),y)
|
|||||||
|
|
||||||
# Include IEEE 802.15.4 support
|
# Include IEEE 802.15.4 support
|
||||||
|
|
||||||
CSRCS += mac802154.c mac802154_indalloc.c mac802154_assoc.c mac802154_disassoc.c
|
CSRCS += ieee802154_indalloc.c mac802154.c mac802154_assoc.c mac802154_disassoc.c
|
||||||
CSRCS += mac802154_bind.c mac802154_data.c mac802154_get_mhrlen.c
|
CSRCS += mac802154_bind.c mac802154_data.c mac802154_get_mhrlen.c
|
||||||
CSRCS += mac802154_getset.c mac802154_gts.c mac802154_ioctl.c
|
CSRCS += mac802154_getset.c mac802154_gts.c mac802154_ioctl.c
|
||||||
CSRCS += mac802154_notif.c mac802154_orphan.c mac802154_poll.c mac802154_purge.c
|
CSRCS += mac802154_notif.c mac802154_orphan.c mac802154_poll.c mac802154_purge.c
|
||||||
|
@ -92,13 +92,6 @@ static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb,
|
|||||||
|
|
||||||
static void mac802154_purge_worker(FAR void *arg);
|
static void mac802154_purge_worker(FAR void *arg);
|
||||||
|
|
||||||
/* Watchdog Timeout Functions */
|
|
||||||
|
|
||||||
static void mac802154_timeout_expiry(int argc, wdparm_t arg, ...);
|
|
||||||
|
|
||||||
static uint32_t mac802154_symtoticks(FAR struct ieee802154_privmac_s *priv,
|
|
||||||
uint32_t symbols);
|
|
||||||
|
|
||||||
static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv,
|
static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv,
|
||||||
FAR struct ieee802154_data_ind_s *ind);
|
FAR struct ieee802154_data_ind_s *ind);
|
||||||
static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv,
|
static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv,
|
||||||
@ -184,7 +177,7 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
{
|
{
|
||||||
/* Unlock MAC so that other work can be done to free a notification */
|
/* Unlock MAC so that other work can be done to free a notification */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Take a count from the tx desc semaphore, waiting if necessary. We
|
/* Take a count from the tx desc semaphore, waiting if necessary. We
|
||||||
* only return from here with an error if we are allowing interruptions
|
* only return from here with an error if we are allowing interruptions
|
||||||
@ -204,7 +197,7 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
* MAC in order to ensure this happens correctly.
|
* MAC in order to ensure this happens correctly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = mac802154_takesem(&priv->exclsem, allow_interrupt);
|
ret = mac802154_lock(priv, allow_interrupt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
wlwarn("WARNING: mac802154_takesem failed: %d\n", ret);
|
wlwarn("WARNING: mac802154_takesem failed: %d\n", ret);
|
||||||
@ -236,6 +229,9 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(*txdesc)->purgetime = 0;
|
||||||
|
(*txdesc)->retrycount = priv->maxretries;
|
||||||
|
|
||||||
(*txdesc)->conf = ¬if->u.dataconf;
|
(*txdesc)->conf = ¬if->u.dataconf;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -354,9 +350,9 @@ void mac802154_createdatareq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
memcpy(&txdesc->destaddr, &coordaddr, sizeof(struct ieee802154_addr_s));
|
memcpy(&txdesc->destaddr, &coordaddr, sizeof(struct ieee802154_addr_s));
|
||||||
|
|
||||||
/* Copy the IOB reference to the descriptor */
|
/* Save a reference of the tx descriptor */
|
||||||
|
|
||||||
txdesc->frame = iob;
|
priv->cmd_desc = txdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -417,9 +413,11 @@ void mac802154_updatebeacon(FAR struct ieee802154_privmac_s *priv)
|
|||||||
IEEE802154_SETSADDRMODE(beacon->bf_data, 0, priv->addr.mode);
|
IEEE802154_SETSADDRMODE(beacon->bf_data, 0, priv->addr.mode);
|
||||||
IEEE802154_SETVERSION(beacon->bf_data, 0, 1);
|
IEEE802154_SETVERSION(beacon->bf_data, 0, 1);
|
||||||
|
|
||||||
/* Copy in and increment the beacon sequence number */
|
/* The beacon sequence number has to be taken care of by the radio layer, since
|
||||||
|
* we only want to update the whole frame when more changes than just the bsn.
|
||||||
|
*/
|
||||||
|
|
||||||
beacon->bf_data[beacon->bf_len++] = priv->bsn++;
|
beacon->bf_len++;
|
||||||
|
|
||||||
IEEE802154_PANIDCOPY(&beacon->bf_data[beacon->bf_len], priv->addr.panid);
|
IEEE802154_PANIDCOPY(&beacon->bf_data[beacon->bf_len], priv->addr.panid);
|
||||||
beacon->bf_len += IEEE802154_PANIDSIZE;
|
beacon->bf_len += IEEE802154_PANIDSIZE;
|
||||||
@ -561,7 +559,7 @@ void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
ticks = mac802154_symtoticks(priv, symbols);
|
ticks = mac802154_symtoticks(priv, symbols);
|
||||||
|
|
||||||
txdesc->purge_time = clock_systimer() + ticks;
|
txdesc->purgetime = clock_systimer() + ticks;
|
||||||
|
|
||||||
/* Make sure the beacon gets updated */
|
/* Make sure the beacon gets updated */
|
||||||
|
|
||||||
@ -580,8 +578,8 @@ void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
if (work_available(&priv->purge_work))
|
if (work_available(&priv->purge_work))
|
||||||
{
|
{
|
||||||
//work_queue(MAC802154_WORK, &priv->purge_work, mac802154_purge_worker,
|
work_queue(MAC802154_WORK, &priv->purge_work, mac802154_purge_worker,
|
||||||
// (FAR void *)priv, ticks);
|
(FAR void *)priv, ticks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +605,7 @@ static void mac802154_purge_worker(FAR void *arg)
|
|||||||
* signals so don't allow interruptions
|
* signals so don't allow interruptions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -622,12 +620,12 @@ static void mac802154_purge_worker(FAR void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Should probably check a little ahead and remove the transaction if it is within
|
/* Should probably check a little ahead and remove the transaction if it is within
|
||||||
* a certain number of clock ticks away. There is no since in scheduling the
|
* a certain number of clock ticks away. There is no since in scheduling the
|
||||||
* timer to expire in only a few ticks.
|
* timer to expire in only a few ticks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (clock_systimer() >= txdesc->purge_time)
|
if (clock_systimer() >= txdesc->purgetime)
|
||||||
{
|
{
|
||||||
/* Unlink the transaction */
|
/* Unlink the transaction */
|
||||||
|
|
||||||
@ -636,8 +634,8 @@ static void mac802154_purge_worker(FAR void *arg)
|
|||||||
/* Free the IOB, the notification, and the tx descriptor */
|
/* Free the IOB, the notification, and the tx descriptor */
|
||||||
|
|
||||||
iob_free(txdesc->frame);
|
iob_free(txdesc->frame);
|
||||||
((FAR struct mac802154_notif_s *)txdesc->conf)->flink = priv->notif_free;
|
mac802154_notif_free_locked(priv,
|
||||||
priv->notif_free = ((FAR struct mac802154_notif_s *)txdesc->conf);
|
(FAR struct ieee802154_notif_s *)txdesc->conf);
|
||||||
mac802154_txdesc_free(priv, txdesc);
|
mac802154_txdesc_free(priv, txdesc);
|
||||||
priv->beaconupdate = true;
|
priv->beaconupdate = true;
|
||||||
|
|
||||||
@ -648,10 +646,12 @@ static void mac802154_purge_worker(FAR void *arg)
|
|||||||
/* Reschedule the transaction for the next timeout */
|
/* Reschedule the transaction for the next timeout */
|
||||||
|
|
||||||
work_queue(MAC802154_WORK, &priv->purge_work, mac802154_purge_worker,
|
work_queue(MAC802154_WORK, &priv->purge_work, mac802154_purge_worker,
|
||||||
(FAR void *)priv, txdesc->purge_time - clock_systimer());
|
(FAR void *)priv, txdesc->purgetime - clock_systimer());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mac802154_unlock(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -677,7 +677,7 @@ static int mac802154_radiopoll(FAR const struct ieee802154_radiocb_s *radiocb,
|
|||||||
|
|
||||||
/* Get exclusive access to the driver structure. Ignore any EINTR signals */
|
/* Get exclusive access to the driver structure. Ignore any EINTR signals */
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
if (gts)
|
if (gts)
|
||||||
{
|
{
|
||||||
@ -692,7 +692,7 @@ static int mac802154_radiopoll(FAR const struct ieee802154_radiocb_s *radiocb,
|
|||||||
*txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->csma_queue);
|
*txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->csma_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
if (*txdesc != NULL)
|
if (*txdesc != NULL)
|
||||||
{
|
{
|
||||||
@ -729,11 +729,11 @@ static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb,
|
|||||||
* signals so don't allow interruptions
|
* signals so don't allow interruptions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
sq_addlast((FAR sq_entry_t *)txdesc, &priv->txdone_queue);
|
sq_addlast((FAR sq_entry_t *)txdesc, &priv->txdone_queue);
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Schedule work with the work queue to process the completion further */
|
/* Schedule work with the work queue to process the completion further */
|
||||||
|
|
||||||
@ -760,13 +760,12 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
(FAR struct ieee802154_privmac_s *)arg;
|
(FAR struct ieee802154_privmac_s *)arg;
|
||||||
FAR struct ieee802154_txdesc_s *txdesc;
|
FAR struct ieee802154_txdesc_s *txdesc;
|
||||||
FAR struct ieee802154_notif_s *notif;
|
FAR struct ieee802154_notif_s *notif;
|
||||||
FAR struct mac802154_notif_s *privnotif;
|
|
||||||
|
|
||||||
/* Get exclusive access to the driver structure. We don't care about any
|
/* Get exclusive access to the driver structure. We don't care about any
|
||||||
* signals so don't allow interruptions
|
* signals so don't allow interruptions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -781,8 +780,9 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
* notification structure to make it easier to use.
|
* notification structure to make it easier to use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
privnotif = (FAR struct mac802154_notif_s *)txdesc->conf;
|
notif =(FAR struct ieee802154_notif_s *)txdesc->conf;
|
||||||
notif = &privnotif->pub;
|
|
||||||
|
wlinfo("Tx status: %s\n", IEEE802154_STATUS_STRING[txdesc->conf->status]);
|
||||||
|
|
||||||
switch(txdesc->frametype)
|
switch(txdesc->frametype)
|
||||||
{
|
{
|
||||||
@ -792,9 +792,9 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
|
|
||||||
/* Release the MAC, call the callback, get exclusive access again */
|
/* Release the MAC, call the callback, get exclusive access again */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
mac802154_notify(priv, notif);
|
mac802154_notify(priv, notif);
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -857,14 +857,7 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* We can deallocate the data conf notification as it is no
|
mac802154_notif_free_locked(priv, notif);
|
||||||
* longer needed. We can't use the public function here
|
|
||||||
* since we already have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
|
||||||
priv->notif_free = privnotif;
|
|
||||||
priv->nnotif = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -872,13 +865,7 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/* We can deallocate the data conf notification as it is no longer
|
mac802154_notif_free_locked(priv, notif);
|
||||||
* needed. We can't use the public function here since we already
|
|
||||||
* have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
|
||||||
priv->notif_free = privnotif;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -889,7 +876,7 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
mac802154_txdesc_free(priv, txdesc);
|
mac802154_txdesc_free(priv, txdesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -920,15 +907,15 @@ static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb,
|
|||||||
* signals so if we see one, just go back to trying to get access again.
|
* signals so if we see one, just go back to trying to get access again.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
/* Push the iob onto the tail of the frame list for processing */
|
/* Push the iob onto the tail of the frame list for processing */
|
||||||
|
|
||||||
sq_addlast((FAR sq_entry_t *)ind, &priv->dataind_queue);
|
sq_addlast((FAR sq_entry_t *)ind, &priv->dataind_queue);
|
||||||
|
|
||||||
wlinfo("frame received\n");
|
wlinfo("Frame received\n");
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Schedule work with the work queue to process the completion further */
|
/* Schedule work with the work queue to process the completion further */
|
||||||
|
|
||||||
@ -966,7 +953,7 @@ static void mac802154_rxframe_worker(FAR void *arg)
|
|||||||
* signals so if we see one, just go back to trying to get access again.
|
* signals so if we see one, just go back to trying to get access again.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
/* Pop the iob from the head of the frame list for processing */
|
/* Pop the iob from the head of the frame list for processing */
|
||||||
|
|
||||||
@ -974,7 +961,7 @@ static void mac802154_rxframe_worker(FAR void *arg)
|
|||||||
|
|
||||||
/* Once we pop off the indication, we don't need to keep the mac locked */
|
/* Once we pop off the indication, we don't need to keep the mac locked */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
if (ind == NULL)
|
if (ind == NULL)
|
||||||
{
|
{
|
||||||
@ -1100,7 +1087,6 @@ static void mac802154_rxframe_worker(FAR void *arg)
|
|||||||
case IEEE802154_CMD_ORPHAN_NOT:
|
case IEEE802154_CMD_ORPHAN_NOT:
|
||||||
wlinfo("Orphan notif received\n");
|
wlinfo("Orphan notif received\n");
|
||||||
break;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case IEEE802154_CMD_BEACON_REQ:
|
case IEEE802154_CMD_BEACON_REQ:
|
||||||
wlinfo("Beacon request received\n");
|
wlinfo("Beacon request received\n");
|
||||||
@ -1123,7 +1109,7 @@ static void mac802154_rxframe_worker(FAR void *arg)
|
|||||||
|
|
||||||
case IEEE802154_FRAME_BEACON:
|
case IEEE802154_FRAME_BEACON:
|
||||||
{
|
{
|
||||||
wlinfo("Beacon frame received\n");
|
wlinfo("Beacon frame received. BSN: 0x%02X\n", ind->dsn);
|
||||||
mac802154_rxbeaconframe(priv, ind);
|
mac802154_rxbeaconframe(priv, ind);
|
||||||
ieee802154_ind_free(ind);
|
ieee802154_ind_free(ind);
|
||||||
}
|
}
|
||||||
@ -1159,7 +1145,7 @@ static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
/* If we are currently performing a POLL operation and we've
|
/* If we are currently performing a POLL operation and we've
|
||||||
* received a data response, use the addressing information
|
* received a data response, use the addressing information
|
||||||
@ -1178,7 +1164,9 @@ static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv,
|
|||||||
* FIXME: Fix documentation
|
* FIXME: Fix documentation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (priv->curr_op == MAC802154_OP_POLL || priv->curr_op == MAC802154_OP_ASSOC)
|
if (priv->curr_op == MAC802154_OP_POLL ||
|
||||||
|
priv->curr_op == MAC802154_OP_ASSOC ||
|
||||||
|
priv->curr_op == MAC802154_OP_AUTOEXTRACT)
|
||||||
{
|
{
|
||||||
/* If we are in promiscuous mode, we need to check if the
|
/* If we are in promiscuous mode, we need to check if the
|
||||||
* frame is even for us first. If the address is not ours,
|
* frame is even for us first. If the address is not ours,
|
||||||
@ -1232,7 +1220,8 @@ static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If we've gotten this far, the frame is our extracted data. Cancel the
|
/* If we've gotten this far, the frame is our extracted data. Cancel the
|
||||||
* timeout */
|
* timeout
|
||||||
|
*/
|
||||||
|
|
||||||
mac802154_timercancel(priv);
|
mac802154_timercancel(priv);
|
||||||
|
|
||||||
@ -1275,7 +1264,7 @@ static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Release the MAC */
|
/* Release the MAC */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
mac802154_notify(priv, notif);
|
mac802154_notify(priv, notif);
|
||||||
|
|
||||||
/* If there was data, pass it along */
|
/* If there was data, pass it along */
|
||||||
@ -1291,7 +1280,7 @@ static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
notify_with_lock:
|
notify_with_lock:
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
notify_without_lock:
|
notify_without_lock:
|
||||||
|
|
||||||
@ -1350,7 +1339,7 @@ static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
/* Search the list of indirect transactions to see if there are any waiting
|
/* Search the list of indirect transactions to see if there are any waiting
|
||||||
* for the requesting device.
|
* for the requesting device.
|
||||||
@ -1376,11 +1365,20 @@ static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
sq_rem((FAR sq_entry_t *)txdesc, &priv->indirect_queue);
|
sq_rem((FAR sq_entry_t *)txdesc, &priv->indirect_queue);
|
||||||
|
|
||||||
|
/* NOTE: We don't do anything with the purge timeout, because
|
||||||
|
* we really don't need to. As of now, I see no disadvantage
|
||||||
|
* to just letting the timeout expire, which won't purge the
|
||||||
|
* transaction since it is no longer on the list, and then it
|
||||||
|
* will reschedule the next timeout appropriately. The logic
|
||||||
|
* otherwise may get complicated even though it may save a few
|
||||||
|
* clock cycles.
|
||||||
|
*/
|
||||||
|
|
||||||
/* The addresses match, send the transaction immediately */
|
/* The addresses match, send the transaction immediately */
|
||||||
|
|
||||||
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
||||||
priv->beaconupdate = true;
|
priv->beaconupdate = true;
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1397,7 +1395,7 @@ static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
||||||
priv->beaconupdate = true;
|
priv->beaconupdate = true;
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1503,7 +1501,7 @@ static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
txdesc->frame = iob;
|
txdesc->frame = iob;
|
||||||
txdesc->frametype = IEEE802154_FRAME_DATA;
|
txdesc->frametype = IEEE802154_FRAME_DATA;
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
||||||
}
|
}
|
||||||
@ -1522,18 +1520,31 @@ static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb,
|
|||||||
* signals so if we see one, just go back to trying to get access again.
|
* signals so if we see one, just go back to trying to get access again.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
/* Check if there is any reason to update the beacon */
|
switch (sfevent)
|
||||||
|
|
||||||
if (priv->beaconupdate)
|
|
||||||
{
|
{
|
||||||
mac802154_updatebeacon(priv);
|
case IEEE802154_SFEVENT_ENDOFACTIVE:
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MAC802154_SFEVENT_VERBOSE
|
||||||
|
wlinfo("End of superframe\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
priv->radio->beaconupdate(priv->radio, &priv->beaconframe[priv->bf_ind]);
|
/* Check if there is any reason to update the beacon */
|
||||||
|
|
||||||
|
if (priv->beaconupdate)
|
||||||
|
{
|
||||||
|
mac802154_updatebeacon(priv);
|
||||||
|
|
||||||
|
priv->radio->beaconupdate(priv->radio, &priv->beaconframe[priv->bf_ind]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1543,51 +1554,182 @@ static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb,
|
|||||||
* Function called from the generic RX Frame worker to parse and handle the
|
* Function called from the generic RX Frame worker to parse and handle the
|
||||||
* reception of a beacon frame.
|
* reception of a beacon frame.
|
||||||
*
|
*
|
||||||
|
* Assumptions: MAC is locked
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv,
|
static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv,
|
||||||
FAR struct ieee802154_data_ind_s *ind)
|
FAR struct ieee802154_data_ind_s *ind)
|
||||||
{
|
{
|
||||||
FAR struct iob_s *iob = ind->frame;
|
|
||||||
struct ieee802154_pandesc_s pandesc;
|
|
||||||
FAR struct ieee802154_txdesc_s *respdesc;
|
FAR struct ieee802154_txdesc_s *respdesc;
|
||||||
uint8_t numgtsdesc;
|
FAR struct ieee802154_notif_s *notif;
|
||||||
|
FAR struct ieee802154_beacon_ind_s *beacon;
|
||||||
|
FAR struct iob_s *iob = ind->frame;
|
||||||
|
uint8_t ngtsdesc;
|
||||||
uint8_t gtsdirmask;
|
uint8_t gtsdirmask;
|
||||||
uint8_t npendsaddr;
|
bool pending_saddr = false;
|
||||||
uint8_t npendeaddr;
|
bool pending_eaddr = false;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Even though we may not use the notification, we use a notification to
|
||||||
|
* hold all the parsed beacon information. Freeing the notification is quick,
|
||||||
|
* so it's worth saving a copy (If you were to parse all the info in locally,
|
||||||
|
* you would have to copy the data over in the case that you actually need
|
||||||
|
* to notify the next highest layer)
|
||||||
|
*/
|
||||||
|
|
||||||
|
mac802154_notif_alloc(priv, ¬if, false);
|
||||||
|
beacon = ¬if->u.beaconind;
|
||||||
|
|
||||||
|
/* Make sure there is another 2 bytes to process */
|
||||||
|
|
||||||
|
if (iob->io_len < iob->io_offset + 2)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the coordinator address and channel info into the pan descriptor */
|
/* Copy the coordinator address and channel info into the pan descriptor */
|
||||||
|
|
||||||
memcpy(&pandesc.coordaddr, &ind->src, sizeof(struct ieee802154_addr_s));
|
memcpy(&beacon->pandesc.coordaddr, &ind->src, sizeof(struct ieee802154_addr_s));
|
||||||
pandesc.chan = priv->currscan.channels[priv->scanindex];
|
beacon->pandesc.chan = priv->currscan.channels[priv->scanindex];
|
||||||
pandesc.chpage = priv->currscan.chpage;
|
beacon->pandesc.chpage = priv->currscan.chpage;
|
||||||
pandesc.lqi = ind->lqi;
|
beacon->pandesc.lqi = ind->lqi;
|
||||||
pandesc.timestamp = ind->timestamp;
|
beacon->pandesc.timestamp = ind->timestamp;
|
||||||
|
|
||||||
/* Parse the superframe specification field */
|
/* Parse the superframe specification field */
|
||||||
|
|
||||||
pandesc.sfspec.beaconorder = IEEE802154_GETBEACONORDER(iob->io_data,
|
beacon->pandesc.sfspec.beaconorder = IEEE802154_GETBEACONORDER(iob->io_data,
|
||||||
iob->io_offset);
|
iob->io_offset);
|
||||||
|
|
||||||
|
beacon->pandesc.sfspec.sforder =
|
||||||
|
IEEE802154_GETSFORDER(iob->io_data, iob->io_offset);
|
||||||
|
|
||||||
|
beacon->pandesc.sfspec.final_capslot =
|
||||||
|
IEEE802154_GETFINCAPSLOT(iob->io_data, iob->io_offset);
|
||||||
|
|
||||||
|
beacon->pandesc.sfspec.ble =
|
||||||
|
IEEE802154_GETBLE(iob->io_data, iob->io_offset);
|
||||||
|
|
||||||
|
beacon->pandesc.sfspec.pancoord =
|
||||||
|
IEEE802154_GETPANCOORD(iob->io_data, iob->io_offset);
|
||||||
|
|
||||||
|
beacon->pandesc.sfspec.assocpermit =
|
||||||
|
IEEE802154_GETASSOCPERMIT(iob->io_data, iob->io_offset);
|
||||||
|
|
||||||
pandesc.sfspec.sforder = IEEE802154_GETSFORDER(iob->io_data, iob->io_offset);
|
|
||||||
pandesc.sfspec.final_capslot = IEEE802154_GETFINCAPSLOT(iob->io_data,
|
|
||||||
iob->io_offset);
|
|
||||||
pandesc.sfspec.ble = IEEE802154_GETBLE(iob->io_data, iob->io_offset);
|
|
||||||
pandesc.sfspec.pancoord = IEEE802154_GETPANCOORD(iob->io_data, iob->io_offset);
|
|
||||||
pandesc.sfspec.assocpermit = IEEE802154_GETASSOCPERMIT(iob->io_data,
|
|
||||||
iob->io_offset);
|
|
||||||
iob->io_offset += 2;
|
iob->io_offset += 2;
|
||||||
|
|
||||||
|
/* Make sure there is another byte to process (GTS Spec) */
|
||||||
|
|
||||||
|
if (iob->io_len < iob->io_offset + 1)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the GTS Specification field */
|
/* Parse the GTS Specification field */
|
||||||
|
|
||||||
numgtsdesc = IEEE802154_GETGTSDESCCOUNT(iob->io_data, iob->io_offset);
|
ngtsdesc = IEEE802154_GETGTSDESCCOUNT(iob->io_data, iob->io_offset);
|
||||||
pandesc.gtspermit = IEEE802154_GETGTSPERMIT(iob->io_data, iob->io_offset);
|
beacon->pandesc.gtspermit = IEEE802154_GETGTSPERMIT(iob->io_data, iob->io_offset);
|
||||||
iob->io_offset++;
|
iob->io_offset++;
|
||||||
|
|
||||||
/* We only need to parse the rest of the frame if we are not performing a
|
/* If there are any GTS descriptors, handle the GTS Dir and GTS List fields */
|
||||||
* scan
|
|
||||||
*/
|
if (ngtsdesc > 0)
|
||||||
|
{
|
||||||
|
/* Make sure there is another bytes to process (GTS Direction) */
|
||||||
|
|
||||||
|
if (iob->io_len < iob->io_offset + 1)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtsdirmask = IEEE802154_GETGTSDIRMASK(iob->io_data, iob->io_offset);
|
||||||
|
UNUSED(gtsdirmask);
|
||||||
|
iob->io_offset++;
|
||||||
|
|
||||||
|
/* Make sure there are enough bytes left to represent the GTS List */
|
||||||
|
|
||||||
|
if (iob->io_len < iob->io_offset + (3 * ngtsdesc))
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ngtsdesc; i++)
|
||||||
|
{
|
||||||
|
/* For now we just discard the data by skipping over it */
|
||||||
|
|
||||||
|
iob->io_offset += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pending address fields. Min 1 byte, the Pending Address Specification */
|
||||||
|
|
||||||
|
if (iob->io_len < iob->io_offset + 1)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
beacon->pendaddr.nsaddr = IEEE802154_GETNPENDSADDR(iob->io_data, iob->io_offset);
|
||||||
|
beacon->pendaddr.neaddr = IEEE802154_GETNPENDEADDR(iob->io_data, iob->io_offset);
|
||||||
|
iob->io_offset++;
|
||||||
|
|
||||||
|
/* Make sure there are enough bytes left to represent the address list */
|
||||||
|
|
||||||
|
if (iob->io_len < (iob->io_offset +
|
||||||
|
(IEEE802154_SADDRSIZE * beacon->pendaddr.nsaddr) +
|
||||||
|
(IEEE802154_EADDRSIZE * beacon->pendaddr.neaddr)))
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy in the pending addresses */
|
||||||
|
|
||||||
|
for (i = 0; i < beacon->pendaddr.nsaddr; i++)
|
||||||
|
{
|
||||||
|
beacon->pendaddr.addr[i].mode = IEEE802154_ADDRMODE_SHORT;
|
||||||
|
mac802154_takesaddr(iob, beacon->pendaddr.addr[i].saddr);
|
||||||
|
|
||||||
|
/* Check if the short address matches our short address */
|
||||||
|
|
||||||
|
if (IEEE802154_SADDRCMP(beacon->pendaddr.addr[i].saddr, priv->addr.saddr))
|
||||||
|
{
|
||||||
|
/* Wait to actually decide how to handle this until we parse
|
||||||
|
* the rest of the frame
|
||||||
|
*/
|
||||||
|
wlinfo("Data pending for us in coord\n");
|
||||||
|
pending_saddr = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = beacon->pendaddr.nsaddr;
|
||||||
|
i < (beacon->pendaddr.nsaddr + beacon->pendaddr.neaddr);
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
beacon->pendaddr.addr[i].mode = IEEE802154_ADDRMODE_EXTENDED;
|
||||||
|
|
||||||
|
mac802154_takeeaddr(iob, beacon->pendaddr.addr[i].eaddr);
|
||||||
|
|
||||||
|
/* If the extended address matches our extended address */
|
||||||
|
|
||||||
|
if (IEEE802154_EADDRCMP(beacon->pendaddr.addr[i].eaddr, priv->addr.eaddr))
|
||||||
|
{
|
||||||
|
/* Wait to actually decide how to handle this until we parse
|
||||||
|
* the rest of the frame
|
||||||
|
*/
|
||||||
|
wlinfo("Data pending for us in coord\n");
|
||||||
|
pending_eaddr = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is anything left in the frame, process it as the beacon payload */
|
||||||
|
|
||||||
|
beacon->payloadlength = iob->io_len - iob->io_offset;
|
||||||
|
|
||||||
|
if (beacon->payloadlength > 0)
|
||||||
|
{
|
||||||
|
memcpy(beacon->payload, &iob->io_data[iob->io_offset], beacon->payloadlength);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point, we have extracted all relevant info from the incoming frame */
|
||||||
|
|
||||||
if (priv->curr_op == MAC802154_OP_SCAN)
|
if (priv->curr_op == MAC802154_OP_SCAN)
|
||||||
{
|
{
|
||||||
@ -1601,19 +1743,31 @@ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(&ind->src, &priv->pandescs[i].coordaddr,
|
if (memcmp(&ind->src, &priv->pandescs[i].coordaddr,
|
||||||
sizeof(struct ieee802154_addr_s)))
|
sizeof(struct ieee802154_addr_s)) != 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The beacon is the same as another, so discard it */
|
/* The beacon is the same as another, so discard it */
|
||||||
|
|
||||||
|
mac802154_notif_free_locked(priv, notif);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: There is supposed to be different logic for the scanning procedure
|
||||||
|
* based on the macAutoRequest attribute. Currently, we perform scan
|
||||||
|
* operations as if macAutoRequest is set to TRUE, without actually checking
|
||||||
|
* the value. Basically, if macAutoRequest is TRUE, we are supposed to
|
||||||
|
* round up all of the pandesc results and pass them all up via the
|
||||||
|
* SCAN.confirm primitive. If macAutoRequest is FALSE, we are supposed
|
||||||
|
* to notify the next highest layer each time a unique beacon is received
|
||||||
|
* via the BEACON.notify primitive, and pass a NULLed out list of pandesc
|
||||||
|
* when SCAN.confirm is sent.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Copy the pan desc to the list of pan desc */
|
/* Copy the pan desc to the list of pan desc */
|
||||||
|
|
||||||
memcpy(&priv->pandescs[priv->npandesc], &pandesc,
|
memcpy(&priv->pandescs[priv->npandesc], &beacon->pandesc,
|
||||||
sizeof(struct ieee802154_pandesc_s));
|
sizeof(struct ieee802154_pandesc_s));
|
||||||
priv->npandesc++;
|
priv->npandesc++;
|
||||||
|
|
||||||
@ -1622,69 +1776,101 @@ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv,
|
|||||||
mac802154_scanfinish(priv, IEEE802154_STATUS_LIMITREACHED);
|
mac802154_scanfinish(priv, IEEE802154_STATUS_LIMITREACHED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we are not performing a SCAN operation */
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* If there are any GTS descriptors, handle the GTS Directions and
|
/* Check the superframe structure and update the appropriate attributes. */
|
||||||
* GTS List fields
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (numgtsdesc > 0)
|
if (memcmp(&priv->sfspec, &beacon->pandesc.sfspec,
|
||||||
|
sizeof(struct ieee802154_superframespec_s)) != 0)
|
||||||
{
|
{
|
||||||
gtsdirmask = IEEE802154_GETGTSDIRMASK(iob->io_data, iob->io_offset);
|
/* Copy in the new superframe spec */
|
||||||
iob->io_offset++;
|
|
||||||
|
|
||||||
for (i = 0; i < numgtsdesc; i++)
|
memcpy(&priv->sfspec, &beacon->pandesc.sfspec,
|
||||||
{
|
sizeof(struct ieee802154_superframespec_s));
|
||||||
/* For now we just discard the data by skipping over it */
|
|
||||||
|
|
||||||
iob->io_offset += 3;
|
/* Tell the radio layer about the superframe spec update */
|
||||||
}
|
|
||||||
|
priv->radio->sfupdate(priv->radio, &priv->sfspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pending address fields. Min 1 byte, the Pending Address Specification */
|
/* If we are performing an association and there is data pending for us
|
||||||
|
* we ignore the autoRequest logic and just extract it. We also don't
|
||||||
npendsaddr = IEEE802154_GETNPENDSADDR(iob->io_data, iob->io_offset);
|
* send a BEACON-NOTFIY.indication in this case, not sure if that
|
||||||
npendeaddr = IEEE802154_GETNPENDEADDR(iob->io_data, iob->io_offset);
|
* is the right thing to do, can't find anything definitive in standard.
|
||||||
iob->io_offset++;
|
|
||||||
|
|
||||||
/* The pending address field tells us whether or not there is any data
|
|
||||||
* pending for us.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < npendsaddr; i++)
|
if (priv->curr_op == MAC802154_OP_ASSOC && pending_eaddr)
|
||||||
{
|
{
|
||||||
/* If the short address matches our short address */
|
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
|
||||||
|
mac802154_txdesc_alloc(priv, &respdesc, false);
|
||||||
|
mac802154_createdatareq(priv, &priv->pandesc.coordaddr,
|
||||||
|
IEEE802154_ADDRMODE_EXTENDED, respdesc);
|
||||||
|
|
||||||
if (IEEE802154_SADDRCMP(&iob->io_data[iob->io_offset], priv->addr.saddr))
|
/* Link the transaction into the CSMA transaction list */
|
||||||
{
|
|
||||||
/* TODO: Handle data pending in coordinator for us */
|
sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue);
|
||||||
}
|
|
||||||
iob->io_offset += IEEE802154_SADDRSIZE;
|
/* Notify the radio driver that there is data available */
|
||||||
|
|
||||||
|
priv->radio->txnotify(priv->radio, false);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
for (i = 0; i < npendeaddr; i++)
|
|
||||||
{
|
{
|
||||||
/* If the extended address matches our extended address */
|
if (priv->autoreq || priv->curr_op == MAC802154_OP_POLL)
|
||||||
|
|
||||||
if (IEEE802154_EADDRCMP(&iob->io_data[iob->io_offset], priv->addr.eaddr))
|
|
||||||
{
|
{
|
||||||
/* If we are associating, polling, or if macAutoRequest is TRUE,
|
/* If a beacon frame is received and macAutoRequest is set to
|
||||||
* extract the data.
|
* TRUE, the MLME shall first issue the MLME-
|
||||||
|
* BEACON-NOTIFY.indication primitive if the beacon contains any
|
||||||
|
* payload.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((priv->autoreq) || (priv->curr_op == MAC802154_OP_ASSOC) ||
|
if (beacon->payloadlength > 0)
|
||||||
(priv->curr_op == MAC802154_OP_POLL))
|
{
|
||||||
|
/* Unlock the MAC, notify, then lock again */
|
||||||
|
|
||||||
|
mac802154_unlock(priv)
|
||||||
|
mac802154_notify(priv, notif);
|
||||||
|
mac802154_lock(priv, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have data pending for us, attempt to extract it. If for some
|
||||||
|
* reason we have data pending under our short address and our
|
||||||
|
* extended address, let the short address arbitrarily take precedence
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (pending_saddr | pending_eaddr)
|
||||||
{
|
{
|
||||||
mac802154_txdesc_alloc(priv, &respdesc, false);
|
mac802154_txdesc_alloc(priv, &respdesc, false);
|
||||||
|
|
||||||
mac802154_createdatareq(priv, &priv->pandesc.coordaddr,
|
if (priv->curr_op == MAC802154_OP_POLL)
|
||||||
IEEE802154_ADDRMODE_EXTENDED, respdesc);
|
|
||||||
|
|
||||||
if (priv->curr_op == MAC802154_OP_ASSOC ||
|
|
||||||
priv->curr_op == MAC802154_OP_POLL)
|
|
||||||
{
|
{
|
||||||
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
|
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
|
||||||
}
|
}
|
||||||
|
else if (priv->curr_op == MAC802154_OP_ASSOC)
|
||||||
|
{
|
||||||
|
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
|
||||||
|
}
|
||||||
|
else if (priv->curr_op == MAC802154_OP_NONE)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(priv->opsem.semcount == 1);
|
||||||
|
mac802154_takesem(&priv->opsem, false);
|
||||||
|
priv->curr_op = MAC802154_OP_AUTOEXTRACT;
|
||||||
|
priv->curr_cmd = IEEE802154_CMD_DATA_REQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending_saddr)
|
||||||
|
{
|
||||||
|
mac802154_createdatareq(priv, &priv->pandesc.coordaddr,
|
||||||
|
IEEE802154_ADDRMODE_SHORT, respdesc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mac802154_createdatareq(priv, &priv->pandesc.coordaddr,
|
||||||
|
IEEE802154_ADDRMODE_EXTENDED, respdesc);
|
||||||
|
}
|
||||||
|
|
||||||
/* Link the transaction into the CSMA transaction list */
|
/* Link the transaction into the CSMA transaction list */
|
||||||
|
|
||||||
@ -1694,146 +1880,39 @@ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
priv->radio->txnotify(priv->radio, false);
|
priv->radio->txnotify(priv->radio, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there was a beacon payload, we used the notification, so
|
||||||
|
* return here to make sure we don't free the notification.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (beacon->payloadlength > 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
iob->io_offset += IEEE802154_EADDRSIZE;
|
else
|
||||||
}
|
{
|
||||||
|
/* If a valid beacon frame is received and macAutoRequest is set to FALSE,
|
||||||
|
* the MLME shall indicate the beacon parameters to the next higher layer
|
||||||
|
* by issuing the MLME-BEACON-NOTIFY.indication primitive. [1] pg. 38
|
||||||
|
*/
|
||||||
|
|
||||||
/* TODO: Process incoming beacon payload
|
/* Unlock the MAC, notify, then lock again */
|
||||||
* If there is anything left in the frame, process it as the beacon payload
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Check the superframe structure and update the appropriate attributes. */
|
mac802154_unlock(priv)
|
||||||
|
mac802154_notify(priv, notif);
|
||||||
if (memcmp(&priv->sfspec, &pandesc.sfspec,
|
mac802154_lock(priv, false);
|
||||||
sizeof(struct ieee802154_superframespec_s)) != 0)
|
return; /* Return so that we don't free the notificaiton */
|
||||||
{
|
}
|
||||||
/* Copy in the new superframe spec */
|
|
||||||
|
|
||||||
memcpy(&priv->sfspec, &pandesc.sfspec,
|
|
||||||
sizeof(struct ieee802154_superframespec_s));
|
|
||||||
|
|
||||||
/* Tell the radio layer about the superframe spec update */
|
|
||||||
|
|
||||||
priv->radio->sfupdate(priv->radio, &pandesc.sfspec);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
mac802154_notif_free_locked(priv, notif);
|
||||||
* Name: mac802154_symtoticks
|
return;
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Helper function for converting symbols to system clock ticks
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* priv MAC struct is locked when calling.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static uint32_t mac802154_symtoticks(FAR struct ieee802154_privmac_s *priv,
|
errout:
|
||||||
uint32_t symbols)
|
wlwarn("Received beacon with bad format\n");
|
||||||
{
|
mac802154_notif_free_locked(priv, notif);
|
||||||
union ieee802154_attr_u attrval;
|
|
||||||
uint32_t ret;
|
|
||||||
|
|
||||||
/* First, get the symbol duration from the radio layer. Symbol duration is
|
|
||||||
* returned in picoseconds to ensure precision is kept when multiplying to
|
|
||||||
* get overall times.
|
|
||||||
*/
|
|
||||||
|
|
||||||
priv->radio->get_attr(priv->radio, IEEE802154_ATTR_PHY_SYMBOL_DURATION,
|
|
||||||
&attrval);
|
|
||||||
|
|
||||||
/* After this step, ret represents microseconds */
|
|
||||||
|
|
||||||
ret = ((uint64_t)attrval.phy.symdur_picosec * symbols) / (1000 * 1000);
|
|
||||||
|
|
||||||
/* This method should only be used for things that can be late. For instance,
|
|
||||||
* it's always okay to wait a little longer before disabling your receiver.
|
|
||||||
* Therefore, we force the tick count to round up.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ret % USEC_PER_TICK == 0)
|
|
||||||
{
|
|
||||||
ret = ret/USEC_PER_TICK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = ret/USEC_PER_TICK;
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: mac802154_timerstart
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Helper function wrapping the watchdog timer interface. Helps isolate
|
|
||||||
* different operations from having to worry about work queues and watchdog
|
|
||||||
* timers.
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* priv MAC struct is locked when calling.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv,
|
|
||||||
uint32_t numsymbols, mac802154_worker_t worker)
|
|
||||||
{
|
|
||||||
/* TODO: Add check to make sure timer is not already being used. I'd like to
|
|
||||||
* design this so that it absolutely never happens */
|
|
||||||
|
|
||||||
/* Convert the number of symbols to the number of CPU ticks */
|
|
||||||
|
|
||||||
uint32_t ticks = mac802154_symtoticks(priv, numsymbols);
|
|
||||||
|
|
||||||
/* Save the function pointer to call if the timeout expires */
|
|
||||||
|
|
||||||
priv->timeout_worker = worker;
|
|
||||||
|
|
||||||
/* Start the watchdog */
|
|
||||||
|
|
||||||
wd_start(priv->timeout, (int32_t)ticks, mac802154_timeout_expiry,
|
|
||||||
1, (wdparm_t)priv);
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Function: mac802154_timeout_expiry
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* The watchdog timed out. Called from the timer interrupt handler.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* argc - The number of available arguments
|
|
||||||
* arg - The first argument
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* Global interrupts are disabled by the watchdog logic.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static void mac802154_timeout_expiry(int argc, wdparm_t arg, ...)
|
|
||||||
{
|
|
||||||
FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)arg;
|
|
||||||
|
|
||||||
/* There should never be a case where the timeout is used twice at the same
|
|
||||||
* time. */
|
|
||||||
|
|
||||||
DEBUGASSERT(work_available(&priv->timeout_work));
|
|
||||||
|
|
||||||
/* Check to make sure the function pointer is still valid */
|
|
||||||
|
|
||||||
DEBUGASSERT(priv->timeout_worker != NULL);
|
|
||||||
|
|
||||||
work_queue(MAC802154_WORK, &priv->timeout_work, (worker_t)priv->timeout_worker,
|
|
||||||
priv, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1879,6 +1958,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
|||||||
|
|
||||||
if (mac == NULL)
|
if (mac == NULL)
|
||||||
{
|
{
|
||||||
|
wlinfo("Failed allocation privmac structure\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1890,16 +1970,10 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
|||||||
|
|
||||||
sem_init(&mac->opsem, 0, 1);
|
sem_init(&mac->opsem, 0, 1);
|
||||||
|
|
||||||
/* Setup watchdog for extraction timeout */
|
|
||||||
|
|
||||||
mac->timeout = wd_create();
|
|
||||||
|
|
||||||
/* Initialize fields */
|
/* Initialize fields */
|
||||||
|
|
||||||
mac->radio = radiodev;
|
mac->radio = radiodev;
|
||||||
|
|
||||||
mac802154_req_reset((MACHANDLE)mac, true);
|
|
||||||
|
|
||||||
/* Initialize the Radio callbacks */
|
/* Initialize the Radio callbacks */
|
||||||
|
|
||||||
mac->radiocb.priv = mac;
|
mac->radiocb.priv = mac;
|
||||||
@ -1919,6 +1993,8 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
|||||||
ieee802154_indpool_initialize();
|
ieee802154_indpool_initialize();
|
||||||
mac802154_resetqueues(mac);
|
mac802154_resetqueues(mac);
|
||||||
|
|
||||||
|
mac802154_req_reset((MACHANDLE)mac, true);
|
||||||
|
|
||||||
/* Set the default extended address */
|
/* Set the default extended address */
|
||||||
|
|
||||||
for (i = 0; i < IEEE802154_EADDRSIZE; i++)
|
for (i = 0; i < IEEE802154_EADDRSIZE; i++)
|
||||||
@ -1926,9 +2002,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
|||||||
eaddr[i] = (CONFIG_IEEE802154_DEFAULT_EADDR >> (8 * i)) & 0xFF;
|
eaddr[i] = (CONFIG_IEEE802154_DEFAULT_EADDR >> (8 * i)) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEEE802154_EADDRCOPY(mac->addr.eaddr, eaddr);
|
mac802154_seteaddr(mac, eaddr);
|
||||||
mac->radio->set_attr(mac->radio, IEEE802154_ATTR_MAC_EADDR,
|
|
||||||
(union ieee802154_attr_u *)&eaddr[0]);
|
|
||||||
|
|
||||||
return (MACHANDLE)mac;
|
return (MACHANDLE)mac;
|
||||||
}
|
}
|
||||||
|
@ -223,11 +223,11 @@ int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req);
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* mac - Handle to the MAC layer instance
|
* mac - Handle to the MAC layer instance
|
||||||
* rst_pibattr - Whether or not to reset the MAC PIB attributes to defaults
|
* reset_attr - Whether or not to reset the MAC PIB attributes to defaults
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr);
|
int mac802154_req_reset(MACHANDLE mac, bool restattr);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mac802154_req_rxenable
|
* Name: mac802154_req_rxenable
|
||||||
@ -368,7 +368,7 @@ int mac802154_resp_orphan(MACHANDLE mac,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mac802154_notif_free(MACHANDLE mac,
|
void mac802154_notif_free(MACHANDLE mac,
|
||||||
FAR struct ieee802154_notif_s *notif);
|
FAR struct ieee802154_notif_s *notif);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void mac802154_assoctimeout(FAR struct ieee802154_privmac_s *priv);
|
static void mac802154_assoctimeout(FAR void *arg);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public MAC Functions
|
* Public MAC Functions
|
||||||
@ -86,8 +86,8 @@ int mac802154_req_associate(MACHANDLE mac,
|
|||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
FAR struct ieee802154_txdesc_s *txdesc;
|
FAR struct ieee802154_txdesc_s *txdesc;
|
||||||
FAR struct iob_s *iob;
|
FAR struct iob_s *iob;
|
||||||
bool rxonidle;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (req->coordaddr.mode == IEEE802154_ADDRMODE_NONE)
|
if (req->coordaddr.mode == IEEE802154_ADDRMODE_NONE)
|
||||||
{
|
{
|
||||||
@ -111,7 +111,7 @@ int mac802154_req_associate(MACHANDLE mac,
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
ret = mac802154_takesem(&priv->exclsem, true);
|
ret = mac802154_lock(priv, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
mac802154_givesem(&priv->opsem);
|
mac802154_givesem(&priv->opsem);
|
||||||
@ -127,27 +127,22 @@ int mac802154_req_associate(MACHANDLE mac,
|
|||||||
|
|
||||||
mac802154_setcoordaddr(priv, &req->coordaddr);
|
mac802154_setcoordaddr(priv, &req->coordaddr);
|
||||||
|
|
||||||
/* TODO: Need to send coordinator address to radio layer */
|
|
||||||
|
|
||||||
/* Copy the coordinator PAN ID to our PAN ID */
|
/* Copy the coordinator PAN ID to our PAN ID */
|
||||||
|
|
||||||
mac802154_setpanid(priv, req->coordaddr.panid);
|
mac802154_setpanid(priv, req->coordaddr.panid);
|
||||||
|
|
||||||
/* Copy in the capabilities information bitfield */
|
/* Copy in the capabilities information bitfield */
|
||||||
|
|
||||||
priv->devmode = (req->capabilities.devtype) ?
|
if (req->capabilities.devtype)
|
||||||
IEEE802154_DEVMODE_COORD : IEEE802154_DEVMODE_ENDPOINT;
|
{
|
||||||
|
mac802154_setdevmode(priv, IEEE802154_DEVMODE_COORD);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mac802154_setdevmode(priv, IEEE802154_DEVMODE_ENDPOINT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Unlike other attributes, we can't simply cast this one since it is a bit
|
mac802154_setrxonidle(priv, req->capabilities.rxonidle);
|
||||||
* in a bitfield. Casting it will give us unpredicatble results. Instead
|
|
||||||
* of creating a ieee802154_attr_u, we use a local bool. Allocating the
|
|
||||||
* ieee802154_attr_u value would take up more room on the stack since it is
|
|
||||||
* as large as the largest attribute type.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rxonidle = req->capabilities.rxonidle;
|
|
||||||
priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE,
|
|
||||||
(FAR const union ieee802154_attr_u *)&rxonidle);
|
|
||||||
|
|
||||||
/* Allocate an IOB to put the frame in */
|
/* Allocate an IOB to put the frame in */
|
||||||
|
|
||||||
@ -165,7 +160,7 @@ int mac802154_req_associate(MACHANDLE mac,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
iob_free(iob);
|
iob_free(iob);
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
mac802154_givesem(&priv->opsem);
|
mac802154_givesem(&priv->opsem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -250,13 +245,67 @@ int mac802154_req_associate(MACHANDLE mac,
|
|||||||
|
|
||||||
priv->cmd_desc = txdesc;
|
priv->cmd_desc = txdesc;
|
||||||
|
|
||||||
|
/* Search the list of PAN descriptors, that would have been populated by the
|
||||||
|
* latest scan procedure. If we have seen a beacon from the coordinator that
|
||||||
|
* we are about to associate with, we can check the beacon order to determine
|
||||||
|
* whether we can send the command during the CAP. If we haven't received
|
||||||
|
* a beacon frame from the desired coordinator address, we have to just
|
||||||
|
* send the frame out immediately.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0; i < priv->npandesc; i++)
|
||||||
|
{
|
||||||
|
/* Check to make sure the beacon is from the same channel as the request */
|
||||||
|
|
||||||
|
if (req->chan != priv->pandescs[i].chan)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(&req->coordaddr, &priv->pandescs[i].coordaddr,
|
||||||
|
sizeof(struct ieee802154_addr_s)) == 0)
|
||||||
|
{
|
||||||
|
wlinfo("Found matching beacon to use for settings\n");
|
||||||
|
|
||||||
|
/* We have a beacon frame from this coordinator, we can set the
|
||||||
|
* sfspec and send accordingly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copy in the new superframe spec */
|
||||||
|
|
||||||
|
memcpy(&priv->sfspec, &priv->pandescs[i].sfspec,
|
||||||
|
sizeof(struct ieee802154_superframespec_s));
|
||||||
|
|
||||||
|
/* Tell the radio layer about the superframe spec update */
|
||||||
|
|
||||||
|
priv->radio->sfupdate(priv->radio, &priv->pandescs[i].sfspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->sfspec.beaconorder == 15)
|
||||||
|
{
|
||||||
|
wlinfo("Transmitting assoc request\n");
|
||||||
|
|
||||||
|
/* Association Request command gets sent out immediately */
|
||||||
|
|
||||||
|
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wlinfo("Queuing assoc request for CAP\n");
|
||||||
|
|
||||||
|
/* Link the transaction into the CSMA transaction list */
|
||||||
|
|
||||||
|
sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue);
|
||||||
|
|
||||||
|
/* Notify the radio driver that there is data available */
|
||||||
|
|
||||||
|
priv->radio->txnotify(priv->radio, false);
|
||||||
|
}
|
||||||
|
|
||||||
/* We no longer need to have the MAC layer locked. */
|
/* We no longer need to have the MAC layer locked. */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Association Request command gets sent out immediately */
|
|
||||||
|
|
||||||
priv->radio->txdelayed(priv->radio, txdesc, 0);
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -351,7 +400,7 @@ int mac802154_resp_associate(MACHANDLE mac,
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
ret = mac802154_takesem(&priv->exclsem, true);
|
ret = mac802154_lock(priv, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
iob_free(iob);
|
iob_free(iob);
|
||||||
@ -364,7 +413,7 @@ int mac802154_resp_associate(MACHANDLE mac,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
iob_free(iob);
|
iob_free(iob);
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,7 +426,7 @@ int mac802154_resp_associate(MACHANDLE mac,
|
|||||||
|
|
||||||
mac802154_setupindirect(priv, txdesc);
|
mac802154_setupindirect(priv, txdesc);
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -402,10 +451,9 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
FAR struct ieee802154_txdesc_s *txdesc)
|
FAR struct ieee802154_txdesc_s *txdesc)
|
||||||
{
|
{
|
||||||
enum ieee802154_status_e status;
|
enum ieee802154_status_e status;
|
||||||
FAR struct mac802154_notif_s *privnotif =
|
|
||||||
(FAR struct mac802154_notif_s *)txdesc->conf;
|
|
||||||
FAR struct ieee802154_notif_s *notif = &privnotif->pub;
|
|
||||||
FAR struct ieee802154_txdesc_s *respdesc;
|
FAR struct ieee802154_txdesc_s *respdesc;
|
||||||
|
FAR struct ieee802154_notif_s *notif =
|
||||||
|
(FAR struct ieee802154_notif_s *)txdesc->conf;
|
||||||
|
|
||||||
if(txdesc->conf->status != IEEE802154_STATUS_SUCCESS)
|
if(txdesc->conf->status != IEEE802154_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -433,6 +481,7 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
IEEE802154_SADDRCOPY(notif->u.assocconf.saddr, &IEEE802154_SADDR_UNSPEC);
|
IEEE802154_SADDRCOPY(notif->u.assocconf.saddr, &IEEE802154_SADDR_UNSPEC);
|
||||||
|
|
||||||
|
|
||||||
/* We are now done the operation, unlock the semaphore */
|
/* We are now done the operation, unlock the semaphore */
|
||||||
|
|
||||||
priv->curr_op = MAC802154_OP_NONE;
|
priv->curr_op = MAC802154_OP_NONE;
|
||||||
@ -441,9 +490,9 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Release the MAC, call the callback, get exclusive access again */
|
/* Release the MAC, call the callback, get exclusive access again */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
mac802154_notify(priv, notif);
|
mac802154_notify(priv, notif);
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -467,17 +516,33 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
* to respond. Setup a timeout for macResponseWaitTime so that we
|
* to respond. Setup a timeout for macResponseWaitTime so that we
|
||||||
* can inform the next highest layer if the association attempt fails
|
* can inform the next highest layer if the association attempt fails
|
||||||
* due to NO_DATA.
|
* due to NO_DATA.
|
||||||
|
*
|
||||||
|
* TODO: The standard defines macResponseWaitTime as:
|
||||||
|
* The maximum time, in multiples of aBaseSuperframeDuration, a device
|
||||||
|
* shall wait for a response command frame to be available following a
|
||||||
|
* request command frame.
|
||||||
|
*
|
||||||
|
* However, on beacon-enabled networks, it seems the maximum value
|
||||||
|
* isn't really that large of a value, AKA: assoc always fails from
|
||||||
|
* timeout even though everything is working as expected. The definition
|
||||||
|
* does say after we've sent a data request, which we, haven't sent
|
||||||
|
* yet, but we do need a timeout for association in general. Not sure
|
||||||
|
* what the correct answer is. For now, I am going to change the
|
||||||
|
* way macResponseWaitTime is used with beacon-enabled networks and
|
||||||
|
* make the timeout (BI * macResponseWaitTime) where BI is Beacon
|
||||||
|
* Interval = aBaseSuperframeDuration * 2^macBeaconOrder
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
wlinfo("Starting timeout timer\n");
|
||||||
mac802154_timerstart(priv, (priv->resp_waittime *
|
mac802154_timerstart(priv, (priv->resp_waittime *
|
||||||
IEEE802154_BASE_SUPERFRAME_DURATION),
|
(IEEE802154_BASE_SUPERFRAME_DURATION * (1 << priv->sfspec.beaconorder))),
|
||||||
mac802154_assoctimeout);
|
mac802154_assoctimeout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Make sure the coordinator address mode is not set to none. This shouldn't
|
/* Make sure the coordinator address mode is not set to none. This
|
||||||
* happen since the association request should have set the mode to short or
|
* shouldn't happen since the association request should have set
|
||||||
* extended
|
* the mode to short or extended
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUGASSERT(priv->pandesc.coordaddr.mode != IEEE802154_ADDRMODE_NONE);
|
DEBUGASSERT(priv->pandesc.coordaddr.mode != IEEE802154_ADDRMODE_NONE);
|
||||||
@ -497,13 +562,9 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
(priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION));
|
(priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can deallocate the data conf notification as it is no longer
|
/* Deallocate the data conf notification as it is no longer needed. */
|
||||||
* needed. We can't use the public function here since we already
|
|
||||||
* have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
mac802154_notif_free_locked(priv, notif);
|
||||||
priv->notif_free = privnotif;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,9 +585,8 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
FAR struct ieee802154_txdesc_s *txdesc)
|
FAR struct ieee802154_txdesc_s *txdesc)
|
||||||
{
|
{
|
||||||
enum ieee802154_status_e status;
|
enum ieee802154_status_e status;
|
||||||
FAR struct mac802154_notif_s *privnotif =
|
FAR struct ieee802154_notif_s *notif =
|
||||||
(FAR struct mac802154_notif_s *)txdesc->conf;
|
(FAR struct ieee802154_notif_s *)txdesc->conf;
|
||||||
FAR struct ieee802154_notif_s *notif = &privnotif->pub;
|
|
||||||
|
|
||||||
/* If the data request failed to be sent, notify the next layer
|
/* If the data request failed to be sent, notify the next layer
|
||||||
* that the association has failed.
|
* that the association has failed.
|
||||||
@ -573,9 +633,9 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Release the MAC, call the callback, get exclusive access again */
|
/* Release the MAC, call the callback, get exclusive access again */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
mac802154_notify(priv, notif);
|
mac802154_notify(priv, notif);
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -587,22 +647,33 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
mac802154_rxenable(priv);
|
mac802154_rxenable(priv);
|
||||||
|
|
||||||
/* Start a timer, if we receive the data frame, we will cancel
|
/* If we are on a beacon-enabled network, we already have the association
|
||||||
* the timer, otherwise it will expire and we will notify the
|
* timeout timer scheduled. So we only need to start the timeout timer
|
||||||
* next highest layer of the failure.
|
* if we are operating on a non-beacon enabled network.
|
||||||
|
*
|
||||||
|
* NOTE: This may create a bad side-effect where the receiver is on
|
||||||
|
* for longer than it needs to be during association. Revisit if power
|
||||||
|
* is ever an issue.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_timerstart(priv, priv->max_frame_waittime,
|
if (priv->sfspec.beaconorder == 15)
|
||||||
mac802154_assoctimeout);
|
{
|
||||||
|
|
||||||
/* We can deallocate the data conf notification as it is no longer
|
/* Start a timer, if we receive the data frame, we will cancel
|
||||||
* needed. We can't use the public function here since we already
|
* the timer, otherwise it will expire and we will notify the
|
||||||
* have the MAC locked.
|
* next highest layer of the failure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
wlinfo("Starting timeout timer\n");
|
||||||
|
mac802154_timerstart(priv, priv->max_frame_waittime,
|
||||||
|
mac802154_assoctimeout);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deallocate the data conf notification as it is no longer needed. */
|
||||||
|
|
||||||
|
mac802154_notif_free_locked(priv, notif);
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
|
||||||
priv->notif_free = privnotif;
|
|
||||||
mac802154_givesem(&priv->notif_sem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,7 +695,7 @@ void mac802154_rx_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
/* Allocate a notification to pass to the next highest layer */
|
/* Allocate a notification to pass to the next highest layer */
|
||||||
|
|
||||||
@ -665,7 +736,7 @@ void mac802154_rx_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Unlock the MAC */
|
/* Unlock the MAC */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Notify the next highest layer of the association status */
|
/* Notify the next highest layer of the association status */
|
||||||
|
|
||||||
@ -673,7 +744,7 @@ void mac802154_rx_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
errout_with_sem:
|
errout_with_sem:
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,6 +769,19 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
if (priv->curr_op != MAC802154_OP_ASSOC)
|
if (priv->curr_op != MAC802154_OP_ASSOC)
|
||||||
{
|
{
|
||||||
|
/* This situation can occur in a beacon-enabled network if the association
|
||||||
|
* request has timed out, but the Coordinator has already queued the
|
||||||
|
* response. Which means the beacon would contain our address, causing us
|
||||||
|
* to extract the response.
|
||||||
|
*
|
||||||
|
* TODO: What is supposed to happen in this situation. Are we supposed to
|
||||||
|
* accept the request? Are we supposed to Disassociate with the network
|
||||||
|
* as a convienience to the PAN Coordinator. So that it does not need
|
||||||
|
* to waste space holding our information?
|
||||||
|
*/
|
||||||
|
|
||||||
|
wlinfo("Ignoring association response frame\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,7 +791,7 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
/* Allocate a notification to pass to the next highest layer */
|
/* Allocate a notification to pass to the next highest layer */
|
||||||
|
|
||||||
@ -720,7 +804,7 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Inform the radio of the address change */
|
/* Inform the radio of the address change */
|
||||||
|
|
||||||
priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_SADDR,
|
priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_SADDR,
|
||||||
(FAR union ieee802154_attr_u *)priv->addr.saddr);
|
(FAR union ieee802154_attr_u *)priv->addr.saddr);
|
||||||
|
|
||||||
/* A Short Address field value equal to 0xfffe shall indicate that the device
|
/* A Short Address field value equal to 0xfffe shall indicate that the device
|
||||||
@ -751,15 +835,16 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
IEEE802154_SADDRCOPY(notif->u.assocconf.saddr, priv->addr.saddr);
|
IEEE802154_SADDRCOPY(notif->u.assocconf.saddr, priv->addr.saddr);
|
||||||
|
|
||||||
/* Unlock the MAC */
|
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
|
||||||
|
|
||||||
/* We are no longer performing the association operation */
|
/* We are no longer performing the association operation */
|
||||||
|
|
||||||
priv->curr_op = MAC802154_OP_NONE;
|
priv->curr_op = MAC802154_OP_NONE;
|
||||||
priv->cmd_desc = NULL;
|
priv->cmd_desc = NULL;
|
||||||
mac802154_givesem(&priv->opsem);
|
mac802154_givesem(&priv->opsem);
|
||||||
|
mac802154_rxdisable(priv);
|
||||||
|
|
||||||
|
/* Unlock the MAC */
|
||||||
|
|
||||||
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Notify the next highest layer of the association status */
|
/* Notify the next highest layer of the association status */
|
||||||
|
|
||||||
@ -779,10 +864,22 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void mac802154_assoctimeout(FAR struct ieee802154_privmac_s *priv)
|
static void mac802154_assoctimeout(FAR void *arg)
|
||||||
{
|
{
|
||||||
|
FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)arg;
|
||||||
FAR struct ieee802154_notif_s *notif;
|
FAR struct ieee802154_notif_s *notif;
|
||||||
|
|
||||||
|
/* If there is work scheduled for the rxframe_worker, we want to reschedule
|
||||||
|
* this work, so that we make sure if the frame we were waiting for was just
|
||||||
|
* received, we don't timeout
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!work_available(&priv->rx_work))
|
||||||
|
{
|
||||||
|
work_queue(MAC802154_WORK, &priv->timer_work, mac802154_assoctimeout, priv, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUGASSERT(priv->curr_op == MAC802154_OP_ASSOC);
|
DEBUGASSERT(priv->curr_op == MAC802154_OP_ASSOC);
|
||||||
|
|
||||||
/* If the device does not extract an association response command
|
/* If the device does not extract an association response command
|
||||||
@ -796,17 +893,19 @@ static void mac802154_assoctimeout(FAR struct ieee802154_privmac_s *priv)
|
|||||||
* Don't allow EINTR to interrupt.
|
* Don't allow EINTR to interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
mac802154_notif_alloc(priv, ¬if, false);
|
mac802154_notif_alloc(priv, ¬if, false);
|
||||||
|
|
||||||
/* We are no longer performing the association operation */
|
/* We are no longer performing the association operation */
|
||||||
|
|
||||||
priv->curr_op = MAC802154_OP_NONE;
|
priv->curr_op = MAC802154_OP_NONE;
|
||||||
priv->cmd_desc = NULL;
|
priv->cmd_desc = NULL;
|
||||||
mac802154_givesem(&priv->opsem);
|
mac802154_givesem(&priv->opsem);
|
||||||
|
mac802154_rxdisable(priv);
|
||||||
|
|
||||||
/* Release the MAC */
|
/* Release the MAC */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
notif->notiftype = IEEE802154_NOTIFY_CONF_ASSOC;
|
notif->notiftype = IEEE802154_NOTIFY_CONF_ASSOC;
|
||||||
notif->u.assocconf.status = IEEE802154_STATUS_NO_DATA;
|
notif->u.assocconf.status = IEEE802154_STATUS_NO_DATA;
|
||||||
|
@ -118,7 +118,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
* 5.1.6.4 [1] pg. 118.
|
* 5.1.6.4 [1] pg. 118.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
*frame_ctrl |= (meta->msdu_flags.ack_tx << IEEE802154_FRAMECTRL_SHIFT_ACKREQ);
|
*frame_ctrl |= (meta->flags.ackreq << IEEE802154_FRAMECTRL_SHIFT_ACKREQ);
|
||||||
|
|
||||||
/* If the destination address is present, copy the PAN ID and one of the
|
/* If the destination address is present, copy the PAN ID and one of the
|
||||||
* addresses, depending on mode, into the MHR.
|
* addresses, depending on mode, into the MHR.
|
||||||
@ -147,7 +147,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
|
|
||||||
/* From this point on, we need exclusive access to the privmac struct */
|
/* From this point on, we need exclusive access to the privmac struct */
|
||||||
|
|
||||||
ret = mac802154_takesem(&priv->exclsem, true);
|
ret = mac802154_lock(priv, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* Should only fail if interrupted by a signal */
|
/* Should only fail if interrupted by a signal */
|
||||||
@ -161,7 +161,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
* [1] pg. 41.
|
* [1] pg. 41.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (meta->srcaddr_mode != IEEE802154_ADDRMODE_NONE &&
|
if (meta->srcmode != IEEE802154_ADDRMODE_NONE &&
|
||||||
meta->destaddr.mode != IEEE802154_ADDRMODE_NONE)
|
meta->destaddr.mode != IEEE802154_ADDRMODE_NONE)
|
||||||
{
|
{
|
||||||
/* If the PAN identifiers are identical, the PAN ID Compression field
|
/* If the PAN identifiers are identical, the PAN ID Compression field
|
||||||
@ -175,7 +175,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta->srcaddr_mode != IEEE802154_ADDRMODE_NONE)
|
if (meta->srcmode != IEEE802154_ADDRMODE_NONE)
|
||||||
{
|
{
|
||||||
/* If the destination address is not included, or if PAN ID Compression
|
/* If the destination address is not included, or if PAN ID Compression
|
||||||
* is off, we need to include the Source PAN ID.
|
* is off, we need to include the Source PAN ID.
|
||||||
@ -188,12 +188,12 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
mhr_len += 2;
|
mhr_len += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta->srcaddr_mode == IEEE802154_ADDRMODE_SHORT)
|
if (meta->srcmode == IEEE802154_ADDRMODE_SHORT)
|
||||||
{
|
{
|
||||||
IEEE802154_SADDRCOPY(&frame->io_data[mhr_len], priv->addr.saddr);
|
IEEE802154_SADDRCOPY(&frame->io_data[mhr_len], priv->addr.saddr);
|
||||||
mhr_len += 2;
|
mhr_len += 2;
|
||||||
}
|
}
|
||||||
else if (meta->srcaddr_mode == IEEE802154_ADDRMODE_EXTENDED)
|
else if (meta->srcmode == IEEE802154_ADDRMODE_EXTENDED)
|
||||||
{
|
{
|
||||||
IEEE802154_EADDRCOPY(&frame->io_data[mhr_len], priv->addr.eaddr);
|
IEEE802154_EADDRCOPY(&frame->io_data[mhr_len], priv->addr.eaddr);
|
||||||
mhr_len += IEEE802154_EADDRSIZE;
|
mhr_len += IEEE802154_EADDRSIZE;
|
||||||
@ -214,7 +214,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
|
|
||||||
/* Set the source addr mode inside the frame control field */
|
/* Set the source addr mode inside the frame control field */
|
||||||
|
|
||||||
*frame_ctrl |= (meta->srcaddr_mode << IEEE802154_FRAMECTRL_SHIFT_SADDR);
|
*frame_ctrl |= (meta->srcmode << IEEE802154_FRAMECTRL_SHIFT_SADDR);
|
||||||
|
|
||||||
/* Each time a data or a MAC command frame is generated, the MAC sublayer
|
/* Each time a data or a MAC command frame is generated, the MAC sublayer
|
||||||
* shall copy the value of macDSN into the Sequence Number field of the MHR
|
* shall copy the value of macDSN into the Sequence Number field of the MHR
|
||||||
@ -255,7 +255,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
|
|
||||||
/* Then initialize the TX descriptor */
|
/* Then initialize the TX descriptor */
|
||||||
|
|
||||||
txdesc->conf->handle = meta->msdu_handle;
|
txdesc->conf->handle = meta->handle;
|
||||||
txdesc->frame = frame;
|
txdesc->frame = frame;
|
||||||
txdesc->frametype = IEEE802154_FRAME_DATA;
|
txdesc->frametype = IEEE802154_FRAME_DATA;
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
* [1] pg. 118.
|
* [1] pg. 118.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (meta->msdu_flags.gts_tx)
|
if (meta->flags.usegts)
|
||||||
{
|
{
|
||||||
/* TODO: Support GTS transmission. This should just change where we link
|
/* TODO: Support GTS transmission. This should just change where we link
|
||||||
* the transaction. Instead of going in the CSMA transaction list, it
|
* the transaction. Instead of going in the CSMA transaction list, it
|
||||||
@ -291,7 +291,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
* described in 5.1.5 and 5.1.6.3. [1]
|
* described in 5.1.5 and 5.1.6.3. [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (meta->msdu_flags.indirect_tx)
|
if (meta->flags.indirect)
|
||||||
{
|
{
|
||||||
/* If the TxOptions parameter specifies that an indirect transmission
|
/* If the TxOptions parameter specifies that an indirect transmission
|
||||||
* is required and if the device receiving this primitive is not a
|
* is required and if the device receiving this primitive is not a
|
||||||
@ -313,7 +313,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
memcpy(&txdesc->destaddr, &meta->destaddr,
|
memcpy(&txdesc->destaddr, &meta->destaddr,
|
||||||
sizeof(struct ieee802154_addr_s));
|
sizeof(struct ieee802154_addr_s));
|
||||||
mac802154_setupindirect(priv, txdesc);
|
mac802154_setupindirect(priv, txdesc);
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -329,7 +329,7 @@ int mac802154_req_data(MACHANDLE mac,
|
|||||||
|
|
||||||
/* We no longer need to have the MAC layer locked. */
|
/* We no longer need to have the MAC layer locked. */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Notify the radio driver that there is data available */
|
/* Notify the radio driver that there is data available */
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ errout_with_txdesc:
|
|||||||
mac802154_txdesc_free(priv, txdesc);
|
mac802154_txdesc_free(priv, txdesc);
|
||||||
|
|
||||||
errout_with_sem:
|
errout_with_sem:
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,9 @@
|
|||||||
int mac802154_req_disassociate(MACHANDLE mac,
|
int mac802154_req_disassociate(MACHANDLE mac,
|
||||||
FAR struct ieee802154_disassoc_req_s *req)
|
FAR struct ieee802154_disassoc_req_s *req)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
FAR struct ieee802154_privmac_s *priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
|
#endif
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
@ -76,14 +76,14 @@ int mac802154_get_mhrlen(MACHANDLE mac,
|
|||||||
* to NONE */
|
* to NONE */
|
||||||
|
|
||||||
if (meta->destaddr.mode == IEEE802154_ADDRMODE_NONE &&
|
if (meta->destaddr.mode == IEEE802154_ADDRMODE_NONE &&
|
||||||
meta->srcaddr_mode == IEEE802154_ADDRMODE_NONE)
|
meta->srcmode == IEEE802154_ADDRMODE_NONE)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The source address can only be set to NONE if the device is the PAN coord */
|
/* The source address can only be set to NONE if the device is the PAN coord */
|
||||||
|
|
||||||
if (meta->srcaddr_mode == IEEE802154_ADDRMODE_NONE &&
|
if (meta->srcmode == IEEE802154_ADDRMODE_NONE &&
|
||||||
priv->devmode != IEEE802154_DEVMODE_PANCOORD)
|
priv->devmode != IEEE802154_DEVMODE_PANCOORD)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -95,14 +95,14 @@ int mac802154_get_mhrlen(MACHANDLE mac,
|
|||||||
|
|
||||||
/* Add the source address length */
|
/* Add the source address length */
|
||||||
|
|
||||||
ret += mac802154_addr_length[ meta->srcaddr_mode];
|
ret += mac802154_addr_length[ meta->srcmode];
|
||||||
|
|
||||||
/* If both destination and source addressing information is present, the MAC
|
/* If both destination and source addressing information is present, the MAC
|
||||||
* sublayer shall compare the destination and source PAN identifiers.
|
* sublayer shall compare the destination and source PAN identifiers.
|
||||||
* [1] pg. 41.
|
* [1] pg. 41.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (meta->srcaddr_mode != IEEE802154_ADDRMODE_NONE &&
|
if (meta->srcmode != IEEE802154_ADDRMODE_NONE &&
|
||||||
meta->destaddr.mode != IEEE802154_ADDRMODE_NONE)
|
meta->destaddr.mode != IEEE802154_ADDRMODE_NONE)
|
||||||
{
|
{
|
||||||
/* If the PAN identifiers are identical, the PAN ID Compression field
|
/* If the PAN identifiers are identical, the PAN ID Compression field
|
||||||
@ -121,7 +121,7 @@ int mac802154_get_mhrlen(MACHANDLE mac,
|
|||||||
* PAN ID if the respective address is included
|
* PAN ID if the respective address is included
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (meta->srcaddr_mode != IEEE802154_ADDRMODE_NONE)
|
if (meta->srcmode != IEEE802154_ADDRMODE_NONE)
|
||||||
{
|
{
|
||||||
ret += 2; /* 2 bytes for source PAN ID */
|
ret += 2; /* 2 bytes for source PAN ID */
|
||||||
}
|
}
|
||||||
|
@ -84,29 +84,55 @@ int mac802154_req_get(MACHANDLE mac, enum ieee802154_attr_e attr,
|
|||||||
switch (attr)
|
switch (attr)
|
||||||
{
|
{
|
||||||
case IEEE802154_ATTR_MAC_PANID:
|
case IEEE802154_ATTR_MAC_PANID:
|
||||||
IEEE802154_PANIDCOPY(attrval->mac.panid, priv->addr.panid);
|
{
|
||||||
|
IEEE802154_PANIDCOPY(attrval->mac.panid, priv->addr.panid);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE802154_ATTR_MAC_SADDR:
|
|
||||||
IEEE802154_SADDRCOPY(attrval->mac.saddr, priv->addr.saddr);
|
|
||||||
break;
|
|
||||||
case IEEE802154_ATTR_MAC_EADDR:
|
|
||||||
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;
|
|
||||||
default:
|
|
||||||
/* The attribute may be handled soley in the radio driver, so pass
|
|
||||||
* it along.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = priv->radio->get_attr(priv->radio, attr, attrval);
|
case IEEE802154_ATTR_MAC_SADDR:
|
||||||
|
{
|
||||||
|
IEEE802154_SADDRCOPY(attrval->mac.saddr, priv->addr.saddr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_ATTR_MAC_EADDR:
|
||||||
|
{
|
||||||
|
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_MAC_RESPONSE_WAIT_TIME:
|
||||||
|
{
|
||||||
|
attrval->mac.resp_waittime = priv->resp_waittime;
|
||||||
|
}
|
||||||
|
break;;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
/* The attribute may be handled soley in the radio driver, so pass
|
||||||
|
* it along.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = priv->radio->getattr(priv->radio, attr, attrval);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,54 +159,56 @@ int mac802154_req_set(MACHANDLE mac, enum ieee802154_attr_e attr,
|
|||||||
{
|
{
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
FAR struct ieee802154_privmac_s *priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
int ret;
|
int ret = IEEE802154_STATUS_SUCCESS;
|
||||||
|
|
||||||
switch (attr)
|
switch (attr)
|
||||||
{
|
{
|
||||||
case IEEE802154_ATTR_MAC_PANID:
|
case IEEE802154_ATTR_MAC_PANID:
|
||||||
{
|
{
|
||||||
mac802154_setpanid(priv, attrval->mac.panid);
|
mac802154_setpanid(priv, attrval->mac.panid);
|
||||||
ret = IEEE802154_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE802154_ATTR_MAC_SADDR:
|
case IEEE802154_ATTR_MAC_SADDR:
|
||||||
{
|
{
|
||||||
mac802154_setsaddr(priv, attrval->mac.saddr);
|
mac802154_setsaddr(priv, attrval->mac.saddr);
|
||||||
ret = IEEE802154_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE802154_ATTR_MAC_EADDR:
|
case IEEE802154_ATTR_MAC_EADDR:
|
||||||
{
|
{
|
||||||
mac802154_seteaddr(priv, attrval->mac.eaddr);
|
mac802154_seteaddr(priv, attrval->mac.eaddr);
|
||||||
ret = IEEE802154_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE802154_ATTR_MAC_COORD_SADDR:
|
case IEEE802154_ATTR_MAC_COORD_SADDR:
|
||||||
{
|
{
|
||||||
mac802154_setcoordsaddr(priv, attrval->mac.coordsaddr);
|
mac802154_setcoordsaddr(priv, attrval->mac.coordsaddr);
|
||||||
ret = IEEE802154_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE802154_ATTR_MAC_COORD_EADDR:
|
case IEEE802154_ATTR_MAC_COORD_EADDR:
|
||||||
{
|
{
|
||||||
mac802154_setcoordeaddr(priv, attrval->mac.coordeaddr);
|
mac802154_setcoordeaddr(priv, attrval->mac.coordeaddr);
|
||||||
ret = IEEE802154_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE802154_ATTR_MAC_ASSOCIATION_PERMIT:
|
case IEEE802154_ATTR_MAC_ASSOCIATION_PERMIT:
|
||||||
{
|
{
|
||||||
priv->sfspec.assocpermit = attrval->mac.assocpermit;
|
priv->sfspec.assocpermit = attrval->mac.assocpermit;
|
||||||
priv->beaconupdate = true;
|
priv->beaconupdate = true;
|
||||||
ret = IEEE802154_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IEEE802154_ATTR_MAC_RESPONSE_WAIT_TIME:
|
||||||
|
{
|
||||||
|
priv->resp_waittime = attrval->mac.resp_waittime;
|
||||||
|
}
|
||||||
|
case IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE:
|
||||||
|
{
|
||||||
|
mac802154_setrxonidle(priv, attrval->mac.rxonidle);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/* The attribute may be handled soley in the radio driver, so pass
|
/* The attribute may be handled soley in the radio driver, so pass
|
||||||
* it along.
|
* it along.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = priv->radio->set_attr(priv->radio, attr, attrval);
|
ret = priv->radio->setattr(priv->radio, attr, attrval);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,9 @@
|
|||||||
|
|
||||||
int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req)
|
int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
FAR struct ieee802154_privmac_s *priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
|
#endif
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -74,14 +74,12 @@
|
|||||||
|
|
||||||
int mac802154_ioctl(MACHANDLE mac, int cmd, unsigned long arg)
|
int mac802154_ioctl(MACHANDLE mac, int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
FAR union ieee802154_macarg_u *macarg =
|
FAR union ieee802154_macarg_u *macarg =
|
||||||
(FAR union ieee802154_macarg_u *)((uintptr_t)arg);
|
(FAR union ieee802154_macarg_u *)((uintptr_t)arg);
|
||||||
|
|
||||||
DEBUGASSERT(priv != NULL);
|
DEBUGASSERT(mac != NULL);
|
||||||
|
|
||||||
/* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */
|
/* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */
|
||||||
|
|
||||||
@ -124,7 +122,7 @@ int mac802154_ioctl(MACHANDLE mac, int cmd, unsigned long arg)
|
|||||||
break;
|
break;
|
||||||
case MAC802154IOC_MLME_RESET_REQUEST:
|
case MAC802154IOC_MLME_RESET_REQUEST:
|
||||||
{
|
{
|
||||||
ret = mac802154_req_reset(mac, macarg->resetreq.rst_pibattr);
|
ret = mac802154_req_reset(mac, macarg->resetreq.resetattr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MAC802154IOC_MLME_RXENABLE_REQUEST:
|
case MAC802154IOC_MLME_RXENABLE_REQUEST:
|
||||||
|
@ -173,8 +173,8 @@ static void macnet_ind_associate(FAR struct macnet_driver_s *priv,
|
|||||||
FAR struct ieee802154_assoc_ind_s *conf);
|
FAR struct ieee802154_assoc_ind_s *conf);
|
||||||
static void macnet_ind_disassociate(FAR struct macnet_driver_s *priv,
|
static void macnet_ind_disassociate(FAR struct macnet_driver_s *priv,
|
||||||
FAR struct ieee802154_disassoc_ind_s *conf);
|
FAR struct ieee802154_disassoc_ind_s *conf);
|
||||||
static void macnet_ind_beaconnotify(FAR struct macnet_driver_s *priv,
|
static void macnet_ind_beacon(FAR struct macnet_driver_s *priv,
|
||||||
FAR struct ieee802154_beaconnotify_ind_s *conf);
|
FAR struct ieee802154_beacon_ind_s *conf);
|
||||||
static void macnet_ind_gts(FAR struct macnet_driver_s *priv,
|
static void macnet_ind_gts(FAR struct macnet_driver_s *priv,
|
||||||
FAR struct ieee802154_gts_ind_s *conf);
|
FAR struct ieee802154_gts_ind_s *conf);
|
||||||
static void macnet_ind_orphan(FAR struct macnet_driver_s *priv,
|
static void macnet_ind_orphan(FAR struct macnet_driver_s *priv,
|
||||||
@ -589,15 +589,15 @@ static void macnet_ind_disassociate(FAR struct macnet_driver_s *priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: macnet_ind_beaconnotify
|
* Name: macnet_ind_beacon
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Beacon notification
|
* Beacon notification
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void macnet_ind_beaconnotify(FAR struct macnet_driver_s *priv,
|
static void macnet_ind_beacon(FAR struct macnet_driver_s *priv,
|
||||||
FAR struct ieee802154_beaconnotify_ind_s *ind)
|
FAR struct ieee802154_beacon_ind_s *ind)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -69,44 +69,22 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mac802154_notif_free(MACHANDLE mac,
|
void mac802154_notif_free(MACHANDLE mac, FAR struct ieee802154_notif_s *notif)
|
||||||
FAR struct ieee802154_notif_s *notif)
|
|
||||||
{
|
{
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
FAR struct ieee802154_privmac_s *priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
FAR struct mac802154_notif_s *privnotif =
|
|
||||||
(FAR struct mac802154_notif_s *)notif;
|
|
||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Lock the MAC */
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
|
|
||||||
/* We know how many clients have registered for notifications. Each must
|
/* Call the internal helper function to free the notification */
|
||||||
* call mac802154_notif_free() before we can release the notification
|
|
||||||
* resource.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (priv->nnotif < 2)
|
mac802154_notif_free_locked(priv, notif);
|
||||||
{
|
|
||||||
/* This is the free from the last notification */
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
/* Unlock the MAC */
|
||||||
priv->notif_free = privnotif;
|
|
||||||
priv->nnotif = 0;
|
|
||||||
|
|
||||||
mac802154_givesem(&priv->notif_sem);
|
mac802154_unlock(priv)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* More calls are expected. Decrement the count of expected calls
|
|
||||||
* and preserve the notification resources.
|
|
||||||
*/
|
|
||||||
|
|
||||||
priv->nnotif--;
|
|
||||||
}
|
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
|
||||||
return -ENOTTY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -184,15 +162,15 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
privnotif = priv->notif_free;
|
privnotif = priv->notif_free;
|
||||||
priv->notif_free = privnotif->flink;
|
priv->notif_free = privnotif->flink;
|
||||||
priv->nnotif = 0;
|
privnotif->nclients = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Unlock MAC so that other work can be done to free a notification */
|
/* Unlock MAC so that other work can be done to free a notification */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Take a count from the notification semaphore, waiting if necessary. We
|
/* Take a count from the notification semaphore, waiting if necessary. We
|
||||||
* only return from here with an error if we are allowing interruptions
|
* only return from here with an error if we are allowing interruptions
|
||||||
@ -211,7 +189,7 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
* MAC in order to ensure this happens correctly.
|
* MAC in order to ensure this happens correctly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = mac802154_takesem(&priv->exclsem, allow_interrupt);
|
ret = mac802154_lock(priv, allow_interrupt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
mac802154_givesem(&priv->notif_sem);
|
mac802154_givesem(&priv->notif_sem);
|
||||||
@ -220,9 +198,9 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* We can now safely unlink the next free structure from the free list */
|
/* We can now safely unlink the next free structure from the free list */
|
||||||
|
|
||||||
privnotif = priv->notif_free;
|
privnotif = priv->notif_free;
|
||||||
priv->notif_free = privnotif->flink;
|
priv->notif_free = privnotif->flink;
|
||||||
priv->nnotif = 0;
|
privnotif->nclients = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*notif = (FAR struct ieee802154_notif_s *)privnotif;
|
*notif = (FAR struct ieee802154_notif_s *)privnotif;
|
||||||
@ -230,6 +208,49 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mac802154_notif_free_locked
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* When the MAC calls the registered callback, it passes a reference
|
||||||
|
* to a mac802154_notify_s structure. This structure needs to be freed
|
||||||
|
* after the callback handler is done using it.
|
||||||
|
*
|
||||||
|
* Internal version that already has MAC locked
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mac802154_notif_free_locked(FAR struct ieee802154_privmac_s * priv,
|
||||||
|
FAR struct ieee802154_notif_s *notif)
|
||||||
|
{
|
||||||
|
FAR struct mac802154_notif_s *privnotif =
|
||||||
|
(FAR struct mac802154_notif_s *)notif;
|
||||||
|
|
||||||
|
/* We know how many clients have registered for notifications. Each must
|
||||||
|
* call mac802154_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;
|
||||||
|
|
||||||
|
mac802154_givesem(&priv->notif_sem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* More calls are expected. Decrement the count of expected calls
|
||||||
|
* and preserve the notification resources.
|
||||||
|
*/
|
||||||
|
|
||||||
|
privnotif->nclients--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mac802154_notify
|
* Name: mac802154_notify
|
||||||
*
|
*
|
||||||
@ -242,12 +263,13 @@ void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
|
|||||||
FAR struct ieee802154_notif_s *notif)
|
FAR struct ieee802154_notif_s *notif)
|
||||||
{
|
{
|
||||||
FAR struct mac802154_maccb_s *cb;
|
FAR struct mac802154_maccb_s *cb;
|
||||||
|
FAR struct mac802154_notif_s *privnotif = (FAR struct mac802154_notif_s *)notif;
|
||||||
|
|
||||||
/* Set the notification count so that the notification resources will be
|
/* Set the notification count so that the notification resources will be
|
||||||
* preserved until the final notification.
|
* preserved until the final notification.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
priv->nnotif = priv->nclients;
|
privnotif->nclients = priv->nclients;
|
||||||
|
|
||||||
/* Try to notify every registered MAC client */
|
/* Try to notify every registered MAC client */
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ struct mac802154_notif_s
|
|||||||
{
|
{
|
||||||
struct ieee802154_notif_s pub; /* Publically visible structure */
|
struct ieee802154_notif_s pub; /* Publically visible structure */
|
||||||
FAR struct mac802154_notif_s *flink; /* Supports a singly linked list */
|
FAR struct mac802154_notif_s *flink; /* Supports a singly linked list */
|
||||||
|
uint8_t nclients;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -82,4 +83,7 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
|
void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
|
||||||
FAR struct ieee802154_notif_s *notif);
|
FAR struct ieee802154_notif_s *notif);
|
||||||
|
|
||||||
|
void mac802154_notif_free_locked(FAR struct ieee802154_privmac_s * priv,
|
||||||
|
FAR struct ieee802154_notif_s *notif);
|
||||||
|
|
||||||
#endif /* __WIRELESS_IEEE802154__MAC802154_NOTIF_H */
|
#endif /* __WIRELESS_IEEE802154__MAC802154_NOTIF_H */
|
@ -65,7 +65,9 @@
|
|||||||
int mac802154_resp_orphan(MACHANDLE mac,
|
int mac802154_resp_orphan(MACHANDLE mac,
|
||||||
FAR struct ieee802154_orphan_resp_s *resp)
|
FAR struct ieee802154_orphan_resp_s *resp)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
FAR struct ieee802154_privmac_s *priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
|
#endif
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void mac802154_polltimeout(FAR struct ieee802154_privmac_s *priv);
|
static void mac802154_polltimeout(FAR void *arg);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public MAC Functions
|
* Public MAC Functions
|
||||||
@ -106,7 +106,7 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
ret = mac802154_takesem(&priv->exclsem, true);
|
ret = mac802154_lock(priv, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
mac802154_givesem(&priv->opsem);
|
mac802154_givesem(&priv->opsem);
|
||||||
@ -121,7 +121,7 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
|
|||||||
ret = mac802154_txdesc_alloc(priv, &txdesc, true);
|
ret = mac802154_txdesc_alloc(priv, &txdesc, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
mac802154_givesem(&priv->opsem);
|
mac802154_givesem(&priv->opsem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -152,13 +152,15 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
|
|||||||
|
|
||||||
priv->cmd_desc = txdesc;
|
priv->cmd_desc = txdesc;
|
||||||
|
|
||||||
|
wlinfo("Queuing POLL.request in CSMA queue\n");
|
||||||
|
|
||||||
/* Link the transaction into the CSMA transaction list */
|
/* Link the transaction into the CSMA transaction list */
|
||||||
|
|
||||||
sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue);
|
sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue);
|
||||||
|
|
||||||
/* We no longer need to have the MAC layer locked. */
|
/* We no longer need to have the MAC layer locked. */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
/* Notify the radio driver that there is data available */
|
/* Notify the radio driver that there is data available */
|
||||||
|
|
||||||
@ -188,9 +190,8 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv,
|
|||||||
FAR struct ieee802154_txdesc_s *txdesc)
|
FAR struct ieee802154_txdesc_s *txdesc)
|
||||||
{
|
{
|
||||||
enum ieee802154_status_e status;
|
enum ieee802154_status_e status;
|
||||||
FAR struct mac802154_notif_s *privnotif =
|
FAR struct ieee802154_notif_s *notif =
|
||||||
(FAR struct mac802154_notif_s *)txdesc->conf;
|
(FAR struct ieee802154_notif_s *)txdesc->conf;
|
||||||
FAR struct ieee802154_notif_s *notif = &privnotif->pub;
|
|
||||||
|
|
||||||
/* If the data request failed to be sent, notify the next layer
|
/* If the data request failed to be sent, notify the next layer
|
||||||
* that the poll has failed.
|
* that the poll has failed.
|
||||||
@ -223,9 +224,9 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* Release the MAC, call the callback, get exclusive access again */
|
/* Release the MAC, call the callback, get exclusive access again */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
mac802154_notify(priv, notif);
|
mac802154_notify(priv, notif);
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -245,13 +246,9 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv,
|
|||||||
mac802154_timerstart(priv, priv->max_frame_waittime,
|
mac802154_timerstart(priv, priv->max_frame_waittime,
|
||||||
mac802154_polltimeout);
|
mac802154_polltimeout);
|
||||||
|
|
||||||
/* We can deallocate the data conf notification as it is no longer
|
/* Deallocate the data conf notification as it is no longer needed. */
|
||||||
* needed. We can't use the public function here since we already
|
|
||||||
* have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
mac802154_notif_free_locked(priv, notif);
|
||||||
priv->notif_free = privnotif;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,17 +261,29 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void mac802154_polltimeout(FAR struct ieee802154_privmac_s *priv)
|
void mac802154_polltimeout(FAR void *arg)
|
||||||
{
|
{
|
||||||
|
FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)arg;
|
||||||
FAR struct ieee802154_notif_s *notif;
|
FAR struct ieee802154_notif_s *notif;
|
||||||
|
|
||||||
|
/* If there is work scheduled for the rxframe_worker, we want to reschedule
|
||||||
|
* this work, so that we make sure if the frame we were waiting for was just
|
||||||
|
* received, we don't timeout
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!work_available(&priv->rx_work))
|
||||||
|
{
|
||||||
|
work_queue(MAC802154_WORK, &priv->timer_work, mac802154_polltimeout, priv, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUGASSERT(priv->curr_op == MAC802154_OP_POLL);
|
DEBUGASSERT(priv->curr_op == MAC802154_OP_POLL);
|
||||||
|
|
||||||
/* Allocate a notification struct to pass to the next highest layer.
|
/* Allocate a notification struct to pass to the next highest layer.
|
||||||
* Don't allow EINTR to interrupt.
|
* Don't allow EINTR to interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
mac802154_notif_alloc(priv, ¬if, false);
|
mac802154_notif_alloc(priv, ¬if, false);
|
||||||
|
|
||||||
/* We are no longer performing the association operation */
|
/* We are no longer performing the association operation */
|
||||||
@ -284,7 +293,7 @@ void mac802154_polltimeout(FAR struct ieee802154_privmac_s *priv)
|
|||||||
|
|
||||||
/* Release the MAC */
|
/* Release the MAC */
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
notif->notiftype = IEEE802154_NOTIFY_CONF_POLL;
|
notif->notiftype = IEEE802154_NOTIFY_CONF_POLL;
|
||||||
notif->u.pollconf.status = IEEE802154_STATUS_NO_DATA;
|
notif->u.pollconf.status = IEEE802154_STATUS_NO_DATA;
|
||||||
|
@ -76,8 +76,10 @@
|
|||||||
|
|
||||||
int mac802154_req_purge(MACHANDLE mac, uint8_t msdu_handle)
|
int mac802154_req_purge(MACHANDLE mac, uint8_t msdu_handle)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
FAR struct ieee802154_privmac_s *priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
|
#endif
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,40 +74,38 @@
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* mac - Handle to the MAC layer instance
|
* mac - Handle to the MAC layer instance
|
||||||
* rst_pibattr - Whether or not to reset the MAC PIB attributes to defaults
|
* resetattr - Whether or not to reset the MAC PIB attributes to defaults
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr)
|
int mac802154_req_reset(MACHANDLE mac, bool resetattr)
|
||||||
{
|
{
|
||||||
FAR struct ieee802154_privmac_s * priv =
|
FAR struct ieee802154_privmac_s * priv =
|
||||||
(FAR struct ieee802154_privmac_s *) mac;
|
(FAR struct ieee802154_privmac_s *) mac;
|
||||||
union ieee802154_attr_u attr;
|
union ieee802154_attr_u attr;
|
||||||
|
|
||||||
if (rst_pibattr)
|
if (resetattr)
|
||||||
{
|
{
|
||||||
priv->isassoc = false; /* Not associated with a PAN */
|
priv->isassoc = false; /* Not associated with a PAN */
|
||||||
priv->trackingbeacon = false; /* Not tracking beacon by default */
|
priv->trackingbeacon = false; /* Not tracking beacon by default */
|
||||||
priv->sfspec.assocpermit = false; /* Device (if coord) not accepting ssociation */
|
priv->sfspec.assocpermit = false; /* Dev (if coord) not accepting assoc */
|
||||||
priv->autoreq = true; /* Auto send data req if addr. in beacon */
|
priv->autoreq = true; /* Auto send data req if addr in beacon */
|
||||||
priv->sfspec.ble = false; /* BLE disabled */
|
priv->sfspec.ble = false; /* BLE disabled */
|
||||||
priv->beaconpayloadlength = 0; /* Beacon payload NULL */
|
priv->beaconpayloadlength = 0; /* Beacon payload NULL */
|
||||||
priv->sfspec.beaconorder = 15; /* Non-beacon enabled network */
|
priv->sfspec.beaconorder = 15; /* Non-beacon enabled network */
|
||||||
priv->sfspec.sforder = 15; /* Length of active portion of outgoing SF */
|
priv->sfspec.sforder = 15; /* Length of active portion of outgoing SF */
|
||||||
priv->beacon_txtime = 0; /* Device never sent a beacon */
|
priv->beacon_txtime = 0; /* Device never sent a beacon */
|
||||||
#warning Set BSN and DSN to random values!
|
priv->dsn = 0; /* Data sequence number */
|
||||||
priv->bsn = 0;
|
priv->gtspermit = true; /* PAN Coord accepting GTS requests */
|
||||||
priv->dsn = 0;
|
priv->minbe = 3; /* Min value of backoff exponent (BE) */
|
||||||
priv->gtspermit = true; /* PAN Coord accepting GTS requests */
|
priv->maxbe = 5; /* Max value of backoff exponent (BE) */
|
||||||
priv->minbe = 3; /* Min value of backoff exponent (BE) */
|
priv->max_csmabackoffs = 4; /* Max # of backoffs before failure */
|
||||||
priv->maxbe = 5; /* Max value of backoff exponent (BE) */
|
priv->maxretries = 3; /* Max # of retries allowed after failure */
|
||||||
priv->max_csmabackoffs = 4; /* Max # of backoffs before failure */
|
priv->promisc = false; /* Device not in promiscuous mode */
|
||||||
priv->maxretries = 3; /* Max # of retries allowed after failure */
|
priv->rngsupport = false; /* Ranging not yet supported */
|
||||||
priv->promisc = false; /* Device not in promiscuous mode */
|
priv->resp_waittime = 32; /* 32 SF durations */
|
||||||
priv->rngsupport = false; /* Ranging not yet supported */
|
priv->sec_enabled = false; /* Security disabled by default */
|
||||||
priv->resp_waittime = 32; /* 32 SF durations */
|
priv->tx_totaldur = 0; /* 0 transmit duration */
|
||||||
priv->sec_enabled = false; /* Security disabled by default */
|
|
||||||
priv->tx_totaldur = 0; /* 0 transmit duration */
|
|
||||||
|
|
||||||
priv->trans_persisttime = 0x01F4;
|
priv->trans_persisttime = 0x01F4;
|
||||||
|
|
||||||
@ -125,35 +123,19 @@ int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr)
|
|||||||
IEEE802154_SADDRCOPY(priv->addr.saddr, &IEEE802154_SADDR_UNSPEC);
|
IEEE802154_SADDRCOPY(priv->addr.saddr, &IEEE802154_SADDR_UNSPEC);
|
||||||
IEEE802154_EADDRCOPY(priv->addr.eaddr, &IEEE802154_EADDR_UNSPEC);
|
IEEE802154_EADDRCOPY(priv->addr.eaddr, &IEEE802154_EADDR_UNSPEC);
|
||||||
|
|
||||||
priv->radio->reset_attrs(priv->radio);
|
priv->radio->reset(priv->radio);
|
||||||
|
|
||||||
/* The radio is in control of certain attributes, but we keep a mirror
|
/* The radio is in control of certain attributes, but we keep a mirror
|
||||||
* for easy access. Copy in the radio's values now that they've been
|
* for easy access. Copy in the radio's values now that they've been
|
||||||
* reset.
|
* reset.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
priv->radio->get_attr(priv->radio, IEEE802154_ATTR_MAC_MAX_FRAME_WAITTIME,
|
priv->radio->getattr(priv->radio, IEEE802154_ATTR_MAC_MAX_FRAME_WAITTIME,
|
||||||
&attr);
|
&attr);
|
||||||
priv->max_frame_waittime = attr.mac.max_frame_waittime;
|
priv->max_frame_waittime = attr.mac.max_frame_waittime;
|
||||||
|
|
||||||
/* These attributes are effected and determined based on the PHY. Need to
|
mac802154_setdevmode(priv, IEEE802154_DEVMODE_ENDPOINT);
|
||||||
* figure out how to "share" attributes between the radio driver and this
|
|
||||||
* MAC layer
|
|
||||||
*
|
|
||||||
* macAckWaitDuration
|
|
||||||
* macBattLifeExtPeriods
|
|
||||||
* macMaxFrameTotalWaitTime
|
|
||||||
* macLIFSPeriod
|
|
||||||
* macSIFSPeriod
|
|
||||||
* macSyncSymbolOffset
|
|
||||||
* macTimestampSupported
|
|
||||||
* macTxControlActiveDuration
|
|
||||||
* macTxControlPauseDuration
|
|
||||||
* macRxOnWhenIdle
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,7 +72,9 @@
|
|||||||
int mac802154_req_rxenable(MACHANDLE mac,
|
int mac802154_req_rxenable(MACHANDLE mac,
|
||||||
FAR struct ieee802154_rxenable_req_s *req)
|
FAR struct ieee802154_rxenable_req_s *req)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
FAR struct ieee802154_privmac_s * priv =
|
FAR struct ieee802154_privmac_s * priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
|
#endif
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
@ -60,7 +60,7 @@
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void mac802154_scantimeout(FAR struct ieee802154_privmac_s *priv);
|
static void mac802154_scantimeout(FAR void *arg);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public MAC Functions
|
* Public MAC Functions
|
||||||
@ -93,6 +93,8 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlinfo("MLME: SCAN.request received\n");
|
||||||
|
|
||||||
/* Need to get access to the ops semaphore since operations are serial. This
|
/* Need to get access to the ops semaphore since operations are serial. This
|
||||||
* must be done before locking the MAC so that we don't hold the MAC
|
* must be done before locking the MAC so that we don't hold the MAC
|
||||||
*/
|
*/
|
||||||
@ -108,7 +110,7 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req)
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
ret = mac802154_takesem(&priv->exclsem, true);
|
ret = mac802154_lock(priv, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
mac802154_givesem(&priv->opsem);
|
mac802154_givesem(&priv->opsem);
|
||||||
@ -126,6 +128,8 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req)
|
|||||||
{
|
{
|
||||||
case IEEE802154_SCANTYPE_PASSIVE:
|
case IEEE802154_SCANTYPE_PASSIVE:
|
||||||
{
|
{
|
||||||
|
wlinfo("MLME: Starting Passive scan\n");
|
||||||
|
|
||||||
/* Set the channel to the first channel in the list */
|
/* Set the channel to the first channel in the list */
|
||||||
|
|
||||||
mac802154_setchannel(priv, req->channels[priv->scanindex]);
|
mac802154_setchannel(priv, req->channels[priv->scanindex]);
|
||||||
@ -182,11 +186,11 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout_with_sem:
|
errout_with_sem:
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
mac802154_givesem(&priv->opsem);
|
mac802154_givesem(&priv->opsem);
|
||||||
errout:
|
errout:
|
||||||
return ret;
|
return ret;
|
||||||
@ -201,7 +205,7 @@ void mac802154_scanfinish(FAR struct ieee802154_privmac_s *priv,
|
|||||||
{
|
{
|
||||||
FAR struct ieee802154_notif_s * notif;
|
FAR struct ieee802154_notif_s * notif;
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_lock(priv, false);
|
||||||
mac802154_notif_alloc(priv, ¬if, false);
|
mac802154_notif_alloc(priv, ¬if, false);
|
||||||
|
|
||||||
priv->curr_op = MAC802154_OP_NONE;
|
priv->curr_op = MAC802154_OP_NONE;
|
||||||
@ -229,7 +233,7 @@ void mac802154_scanfinish(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
mac802154_setpanid(priv, priv->panidbeforescan);
|
mac802154_setpanid(priv, priv->panidbeforescan);
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
mac802154_notify(priv, notif);
|
mac802154_notify(priv, notif);
|
||||||
}
|
}
|
||||||
@ -247,8 +251,9 @@ void mac802154_scanfinish(FAR struct ieee802154_privmac_s *priv,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void mac802154_scantimeout(FAR struct ieee802154_privmac_s *priv)
|
static void mac802154_scantimeout(FAR void *arg)
|
||||||
{
|
{
|
||||||
|
FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)arg;
|
||||||
DEBUGASSERT(priv->curr_op == MAC802154_OP_SCAN);
|
DEBUGASSERT(priv->curr_op == MAC802154_OP_SCAN);
|
||||||
|
|
||||||
/* If we got here it means we are done scanning that channel */
|
/* If we got here it means we are done scanning that channel */
|
||||||
|
@ -72,7 +72,7 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req)
|
|||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Get exclusive access to the MAC */
|
||||||
|
|
||||||
ret = mac802154_takesem(&priv->exclsem, true);
|
ret = mac802154_lock(priv, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
@ -101,9 +101,9 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req)
|
|||||||
|
|
||||||
/* Tell the radio layer to set the channel number and channel page */
|
/* Tell the radio layer to set the channel number and channel page */
|
||||||
|
|
||||||
priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CHAN,
|
priv->radio->setattr(priv->radio, IEEE802154_ATTR_PHY_CHAN,
|
||||||
(FAR const union ieee802154_attr_u *)&req->chan);
|
(FAR const union ieee802154_attr_u *)&req->chan);
|
||||||
priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE,
|
priv->radio->setattr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE,
|
||||||
(FAR const union ieee802154_attr_u *)&req->chpage);
|
(FAR const union ieee802154_attr_u *)&req->chpage);
|
||||||
|
|
||||||
/* The address used in the Source Address field of the beacon frame shall
|
/* The address used in the Source Address field of the beacon frame shall
|
||||||
@ -147,11 +147,11 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req)
|
|||||||
|
|
||||||
if (req->pancoord)
|
if (req->pancoord)
|
||||||
{
|
{
|
||||||
priv->devmode = IEEE802154_DEVMODE_PANCOORD;
|
mac802154_setdevmode(priv, IEEE802154_DEVMODE_PANCOORD);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
priv->devmode = IEEE802154_DEVMODE_COORD;
|
mac802154_setdevmode(priv, IEEE802154_DEVMODE_COORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->sfspec.pancoord = req->pancoord;
|
priv->sfspec.pancoord = req->pancoord;
|
||||||
@ -194,11 +194,11 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_unlock(priv)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -71,8 +71,10 @@
|
|||||||
|
|
||||||
int mac802154_req_sync(MACHANDLE mac, FAR struct ieee802154_sync_req_s *req)
|
int mac802154_req_sync(MACHANDLE mac, FAR struct ieee802154_sync_req_s *req)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
FAR struct ieee802154_privmac_s *priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
|
#endif
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user