drivers/wireless/ieee802154/mrf24j40: Splits up driver into multiple files to make it easier to navigate

This commit is contained in:
Anthony Merlino 2017-07-10 03:10:20 -04:00
parent 4b7d743f32
commit 28d1db02b8
11 changed files with 2226 additions and 1823 deletions

View File

@ -37,7 +37,8 @@ ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
# Include MRF24J40 files into the build
CSRCS += mrf24j40.c
CSRCS += mrf24j40_getset.c mrf24j40_interrupt.c mrf24j40_radif.c
CSRCS += mrf24j40_regops.c mrf24j40.c
# Include MRF24J40 build support

File diff suppressed because it is too large Load Diff

View File

@ -33,258 +33,192 @@
*
****************************************************************************/
#ifndef __DRIVERS_WIRELESS_IEEE802154_MRF24J40_MRF24J40_H
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_MRF24J40_H
#ifndef __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H
/* MRF24J40 Registers *******************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#define MRF24J40_RXMCR 0x00
#define MRF24J40_PANIDL 0x01
#define MRF24J40_PANIDH 0x02
#define MRF24J40_SADRL 0x03
#define MRF24J40_SADRH 0x04
#define MRF24J40_EADR0 0x05
#define MRF24J40_EADR1 0x06
#define MRF24J40_EADR2 0x07
#define MRF24J40_EADR3 0x08
#define MRF24J40_EADR4 0x09
#define MRF24J40_EADR5 0x0A
#define MRF24J40_EADR6 0x0B
#define MRF24J40_EADR7 0x0C
#define MRF24J40_RXFLUSH 0x0D
#define MRF24J40_ORDER 0x10
#define MRF24J40_TXMCR 0x11
#define MRF24J40_ACKTMOUT 0x12
#define MRF24J40_ESLOTG1 0x13
#define MRF24J40_SYMTICKL 0x14
#define MRF24J40_SYMTICKH 0x15
#define MRF24J40_PACON0 0x16
#define MRF24J40_PACON1 0x17
#define MRF24J40_PACON2 0x18
#define MRF24J40_TXBCON0 0x1A
#define MRF24J40_TXNCON 0x1B
#define MRF24J40_TXG1CON 0x1C
#define MRF24J40_TXG2CON 0x1D
#define MRF24J40_ESLOTG23 0x1E
#define MRF24J40_ESLOTG45 0x1F
#define MRF24J40_ESLOTG67 0x20
#define MRF24J40_TXPEND 0x21
#define MRF24J40_WAKECON 0x22
#define MRF24J40_FRMOFFSET 0x23
#define MRF24J40_TXSTAT 0x24
#define MRF24J40_TXBCON1 0x25
#define MRF24J40_GATECLK 0x26
#define MRF24J40_TXTIME 0x27
#define MRF24J40_HSYMTMRL 0x28
#define MRF24J40_HSYMTMRH 0x29
#define MRF24J40_SOFTRST 0x2A
#define MRF24J40_SECCON0 0x2C
#define MRF24J40_SECCON1 0x2C
#define MRF24J40_TXSTBL 0x2E
#define MRF24J40_RXSR 0x30
#define MRF24J40_INTSTAT 0x31
#define MRF24J40_INTCON 0x32
#define MRF24J40_GPIO 0x33
#define MRF24J40_TRISGPIO 0x34
#define MRF24J40_SLPACK 0x35
#define MRF24J40_RFCTL 0x36
#define MRF24J40_SECCR2 0x37
#define MRF24J40_BBREG0 0x38
#define MRF24J40_BBREG1 0x39
#define MRF24J40_BBREG2 0x3A
#define MRF24J40_BBREG3 0x3B
#define MRF24J40_BBREG4 0x3C
#define MRF24J40_BBREG6 0x3E
#define MRF24J40_CCAEDTH 0x3F
#include <nuttx/config.h>
#define MRF24J40_FIFO_BASE 0x80000000
#define MRF24J40_LONGREG_BASE 0x80000200
#define MRF24J40_RXBUF_BASE 0x80000300
#include <stdint.h>
#include <stdbool.h>
#include <semaphore.h>
#define MRF24J40_TXNORM_FIFO (MRF24J40_FIFO_BASE + 0x000)
#define MRF24J40_BEACON_FIFO (MRF24J40_FIFO_BASE + 0x080)
#define MRF24J40_GTS1_FIFO (MRF24J40_FIFO_BASE + 0x100)
#define MRF24J40_GTS2_FIFO (MRF24J40_FIFO_BASE + 0x180)
#include <nuttx/wqueue.h>
#include <nuttx/spi/spi.h>
#define MRF24J40_RFCON0 (MRF24J40_LONGREG_BASE + 0x00)
#define MRF24J40_RFCON1 (MRF24J40_LONGREG_BASE + 0x01)
#define MRF24J40_RFCON2 (MRF24J40_LONGREG_BASE + 0x02)
#define MRF24J40_RFCON3 (MRF24J40_LONGREG_BASE + 0x03)
#define MRF24J40_RFCON5 (MRF24J40_LONGREG_BASE + 0x05)
#define MRF24J40_RFCON6 (MRF24J40_LONGREG_BASE + 0x06)
#define MRF24J40_RFCON7 (MRF24J40_LONGREG_BASE + 0x07)
#define MRF24J40_RFCON8 (MRF24J40_LONGREG_BASE + 0x08)
#define MRF24J40_SLPCAL0 (MRF24J40_LONGREG_BASE + 0x09)
#define MRF24J40_SLPCAL1 (MRF24J40_LONGREG_BASE + 0x0A)
#define MRF24J40_SLPCAL2 (MRF24J40_LONGREG_BASE + 0x0B)
#define MRF24J40_RFSTATE (MRF24J40_LONGREG_BASE + 0x0F)
#define MRF24J40_RSSI (MRF24J40_LONGREG_BASE + 0x10)
#define MRF24J40_SLPCON0 (MRF24J40_LONGREG_BASE + 0x11)
#define MRF24J40_SLPCON1 (MRF24J40_LONGREG_BASE + 0x20)
#define MRF24J40_WAKETIMEL (MRF24J40_LONGREG_BASE + 0x22)
#define MRF24J40_WAKETIMEH (MRF24J40_LONGREG_BASE + 0x23)
#define MRF24J40_REMCNTL (MRF24J40_LONGREG_BASE + 0x24)
#define MRF24J40_REMCNTH (MRF24J40_LONGREG_BASE + 0x25)
#define MRF24J40_MAINCNT0 (MRF24J40_LONGREG_BASE + 0x26)
#define MRF24J40_MAINCNT1 (MRF24J40_LONGREG_BASE + 0x27)
#define MRF24J40_MAINCNT2 (MRF24J40_LONGREG_BASE + 0x28)
#define MRF24J40_MAINCNT3 (MRF24J40_LONGREG_BASE + 0x29)
#define MRF24J40_TESTMODE (MRF24J40_LONGREG_BASE + 0x2F)
#define MRF24J40_ASSOEADR0 (MRF24J40_LONGREG_BASE + 0x30)
#define MRF24J40_ASSOEADR1 (MRF24J40_LONGREG_BASE + 0x31)
#define MRF24J40_ASSOEADR2 (MRF24J40_LONGREG_BASE + 0x32)
#define MRF24J40_ASSOEADR3 (MRF24J40_LONGREG_BASE + 0x33)
#define MRF24J40_ASSOEADR4 (MRF24J40_LONGREG_BASE + 0x34)
#define MRF24J40_ASSOEADR5 (MRF24J40_LONGREG_BASE + 0x35)
#define MRF24J40_ASSOEADR6 (MRF24J40_LONGREG_BASE + 0x36)
#define MRF24J40_ASSOEADR7 (MRF24J40_LONGREG_BASE + 0x37)
#define MRF24J40_ASSOSADR0 (MRF24J40_LONGREG_BASE + 0x38)
#define MRF24J40_ASSOSADR1 (MRF24J40_LONGREG_BASE + 0x39)
#define MRF24J40_UPNONCE0 (MRF24J40_LONGREG_BASE + 0x40)
#define MRF24J40_UPNONCE1 (MRF24J40_LONGREG_BASE + 0x41)
#define MRF24J40_UPNONCE2 (MRF24J40_LONGREG_BASE + 0x42)
#define MRF24J40_UPNONCE3 (MRF24J40_LONGREG_BASE + 0x43)
#define MRF24J40_UPNONCE4 (MRF24J40_LONGREG_BASE + 0x44)
#define MRF24J40_UPNONCE5 (MRF24J40_LONGREG_BASE + 0x45)
#define MRF24J40_UPNONCE6 (MRF24J40_LONGREG_BASE + 0x46)
#define MRF24J40_UPNONCE7 (MRF24J40_LONGREG_BASE + 0x47)
#define MRF24J40_UPNONCE8 (MRF24J40_LONGREG_BASE + 0x48)
#define MRF24J40_UPNONCE9 (MRF24J40_LONGREG_BASE + 0x49)
#define MRF24J40_UPNONCE10 (MRF24J40_LONGREG_BASE + 0x4A)
#define MRF24J40_UPNONCE11 (MRF24J40_LONGREG_BASE + 0x4B)
#define MRF24J40_UPNONCE12 (MRF24J40_LONGREG_BASE + 0x4C)
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/ieee802154_radio.h>
/* INTSTAT bits */
/* NuttX implementation defines **********************************************/
#define MRF24J40_INTSTAT_TXNIF (1 << 0)
#define MRF24J40_INTSTAT_TXG1IF (1 << 1)
#define MRF24J40_INTSTAT_TXG2IF (1 << 2)
#define MRF24J40_INTSTAT_RXIF (1 << 3)
#define MRF24J40_INTSTAT_SECIF (1 << 4)
#define MRF24J40_INTSTAT_HSYMTMRIF (1 << 5)
#define MRF24J40_INTSTAT_WAKEIF (1 << 6)
#define MRF24J40_INTSTAT_SLPIF (1 << 7)
#define MRF24J40_GTS_SLOTS 2
/* RXMCR bits */
/* Definitions for the device structure */
#define MRF24J40_RXMCR_PROMI (1 << 0) /* Enable promisc mode (rx all valid packets) */
#define MRF24J40_RXMCR_ERRPKT 0x02 /* Do not check CRC */
#define MRF24J40_RXMCR_COORD 0x04 /* Enable coordinator mode ??? DIFFERENCE ??? - not used in datasheet! */
#define MRF24J40_RXMCR_PANCOORD 0x08 /* Enable PAN coordinator mode ??? DIFFERENCE ??? */
#define MRF24J40_RXMCR_NOACKRSP 0x20 /* Enable auto ACK when a packet is rxed */
#define MRF24J40_RXMODE_NORMAL 0
#define MRF24J40_RXMODE_PROMISC 1
#define MRF24J40_RXMODE_NOCRC 2
/* TXMCR bits */
#define MRF24J40_MODE_DEVICE 0
#define MRF24J40_MODE_COORD 1
#define MRF24J40_MODE_PANCOORD 2
#define MRF24J40_TXMCR_CSMABF0 (1 << 0)
#define MRF24J40_TXMCR_CSMABF1 0x02
#define MRF24J40_TXMCR_CSMABF2 0x04
#define MRF24J40_TXMCR_MACMINBE0 0x08
#define MRF24J40_TXMCR_MACMINBE1 0x10
#define MRF24J40_TXMCR_SLOTTED 0x20
#define MRF24J40_TXMCR_BATLIFEXT 0x40
#define MRF24J40_TXMCR_NOCSMA 0x80
/* Definitions for PA control on high power modules */
/* ACKTMOUT bits */
#define MRF24J40_PA_AUTO 1
#define MRF24J40_PA_ED 2
#define MRF24J40_PA_SLEEP 3
#define MRF24J40_ACKTMOUT_MAWD 0xEF
#define MRF24J40_ACKTMOUT_DRPACK 0x80
/* 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
*/
/* INTCON bits */
#define MRF24J40_DEFAULT_MAX_FRAME_WAITTIME 1824
#define MRF24J40_INTCON_SLPIE 0x80
#define MRF24J40_INTCON_WAKEIE 0x40
#define MRF24J40_INTCON_HSYMTMRIE 0x20
#define MRF24J40_INTCON_SECIE 0x10
#define MRF24J40_INTCON_RXIE 0x08
#define MRF24J40_INTCON_TXG2IE 0x04
#define MRF24J40_INTCON_TXG1IE 0x02
#define MRF24J40_INTCON_TXNIE (1 << 0)
#define MRF24J40_SYMBOL_DURATION_PS 16000000
/* BBREG1 bits */
/* Configuration *************************************************************/
#define MRF24J40_BBREG1_RXDECINV 0x04 /* Enable/Disable packet reception */
#ifndef CONFIG_SCHED_HPWORK
# error High priority work queue required in this driver
#endif
/* BBREG2 bits */
#ifndef CONFIG_IEEE802154_MRF24J40_SPIMODE
# define CONFIG_IEEE802154_MRF24J40_SPIMODE SPIDEV_MODE0
#endif
#define MRF24J40_BBREG2_CCAMODE_ED 0x80
#define MRF24J40_BBREG2_CCAMODE_CS 0x40
#ifndef CONFIG_IEEE802154_MRF24J40_FREQUENCY
# define CONFIG_IEEE802154_MRF24J40_FREQUENCY 8000000
#endif
/* TXNCON bits */
#ifndef CONFIG_SPI_EXCHANGE
# error CONFIG_SPI_EXCHANGE required for this driver
#endif
#define MRF24J40_TXNCON_TXNTRIG (1 << 0) /* Trigger packet tx, automatically cleared */
#define MRF24J40_TXNCON_TXNSECEN 0x02 /* Enable security */
#define MRF24J40_TXNCON_TXNACKREQ 0x04 /* An ACK is requested for this pkt */
#define MRF24J40_TXNCON_INDIRECT 0x08 /* Activate indirect tx bit (for coordinators) */
#define MRF24J40_TXNCON_FPSTAT 0x10 /* Status of the frame pending big in txed acks */
/****************************************************************************
* Private Types
****************************************************************************/
/* TXSTAT bits */
/* A MRF24J40 device instance */
#define MRF24J40_TXSTAT_TXNSTAT (1 << 0)
#define MRF24J40_TXSTAT_TXG1STAT (1 << 1)
#define MRF24J40_TXSTAT_TXG2STAT (1 << 2)
#define MRF24J40_TXSTAT_CCAFAIL (1 << 5)
#define MRF24J40_TXSTAT_X_SHIFT 6
#define MRF24J40_TXSTAT_X_MASK (3 << MRF24J40_TXSTAT_X_SHIFT)
struct mrf24j40_radio_s
{
struct ieee802154_radio_s radio; /* The public device instance */
FAR struct ieee802154_radiocb_s *radiocb; /* Registered callbacks */
/* TXBCON0 bits */
/* Low-level MCU-specific support */
#define MRF24J40_TXBCON0_TXBTRIG 0x01
#define MRF24J40_TXBCON0_TXBSECEN 0x02
FAR const struct mrf24j40_lower_s *lower;
FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
/* TXBCON1 bits */
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 */
#define MRF24J40_TXBCON1_RSSINUM 0x30
#define MRF24J40_TXBCON1_NWU_BCN 0x40
#define MRF24J40_TXBCON1_TXBMSK 0x80
sem_t exclsem; /* Exclusive access to this struct */
/* WAKECON bits */
/* MAC Attributes */
#define MRF24J40_WAKECON_INTL 0x3F
#define MRF24J40_WAKECON_REGWAKE 0x40
#define MRF24J40_WAKECON_IMMWAKE 0x80
struct ieee802154_addr_s addr;
/* WAKECON bits */
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 */
#define MRF24J40_WAKECON_INTL 0x3F
#define MRF24J40_WAKECON_REGWAKE 0x40
#define MRF24J40_WAKECON_IMMWAKE 0x80
/* MAC PIB attributes */
/* ESLOTG1 bits */
uint32_t max_frame_waittime;
#define MRF24J40_ESLOTG1_CAP 0x0F
#define MRF24J40_ESLOTG1_GTS1 0xF0
struct ieee802154_txdesc_s *txdelayed_desc;
struct ieee802154_txdesc_s *csma_desc;
bool txdelayed_busy : 1;
bool csma_busy : 1;
bool reschedule_csma : 1;
/* SLPCAL2 bits */
bool rxenabled : 1;
#define MRF24J40_SLPCAL2_SLPCAL 0x0F
#define MRF24J40_SLPCAL2_SLPCALEN 0x10
#define MRF24J40_SLPCAL2_SLPCALRDY 0x80
uint8_t bsn;
/* RFCON7 bits */
struct ieee802154_txdesc_s *gts_desc[MRF24J40_GTS_SLOTS];
bool gts_busy[MRF24J40_GTS_SLOTS];
};
#define MRF24J40_RFCON7_SEL_32KHZ 0x40
#define MRF24J40_RFCON7_SEL_100KHZ 0x80
/****************************************************************************
* Internal Function Prototypes
****************************************************************************/
/* SLPACK bits */
int mrf24j40_interrupt(int irq, FAR void *context, FAR void *arg);
void mrf24j40_irqworker(FAR void *arg);
#define MRF24J40_SLPACK_WAKECNT0_6 0x7F
#define MRF24J40_SLPACK_SLPACK 0x80
void mrf24j40_dopoll_csma(FAR void *arg);
void mrf24j40_dopoll_gts(FAR void *arg);
/* RXFLUSH bits */
void mrf24j40_resetrfsm(FAR struct mrf24j40_radio_s *dev);
#define MRF24J40_RXFLUSH_RXFLUSH 0x01
#define MRF24J40_RXFLUSH_BCNONLY 0x02
#define MRF24J40_RXFLUSH_DATAONLY 0x04
#define MRF24J40_RXFLUSH_CMDONLY 0x08
#define MRF24J40_RXFLUSH_WAKEPAD 0x20
#define MRF24J40_RXFLUSH_WAKEPOL 0x40
void mrf24j40_setorder(FAR struct mrf24j40_radio_s *dev, uint8_t bo, uint8_t so);
#define MRF24J40_RXFLUSH_SHIFT_RXFLUSH 0
#define MRF24J40_RXFLUSH_SHIFT_BCNONLY 1
#define MRF24J40_RXFLUSH_SHIFT_DATAONLY 2
#define MRF24J40_RXFLUSH_SHIFT_CMDONLY 3
#define MRF24J40_RXFLUSH_SHIFT_WAKEPAD 5
#define MRF24J40_RXFLUSH_SHIFT_WAKEPOL 6
int mrf24j40_pacontrol(FAR struct mrf24j40_radio_s *dev, int mode);
int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev, FAR uint8_t *energy);
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_MRF24J40_H */
int mrf24j40_rxenable(FAR struct ieee802154_radio_s *dev, bool enable);
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);
void mrf24j40_mactimer(FAR struct mrf24j40_radio_s *dev, int numsymbols);
/****************************************************************************
* Internal Helpers
****************************************************************************/
/****************************************************************************
* 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);
}
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H */

View File

@ -0,0 +1,425 @@
/****************************************************************************
* 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 "mrf24j40.h"
#include "mrf24j40_reg.h"
#include "mrf24j40_regops.h"
#include "mrf24j40_getset.h"
/****************************************************************************
* 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)
{
int ret = OK;
uint8_t reg;
/* Disable slotted mode until I decide to implement slotted mode */
reg = mrf24j40_getreg(dev->spi, MRF24J40_TXMCR);
reg &= ~MRF24J40_TXMCR_SLOTTED;
mrf24j40_setreg(dev->spi, MRF24J40_TXMCR, reg);
mrf24j40_setreg(dev->spi, MRF24J40_ORDER, 0xFF);
/* 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 ret;
}
/****************************************************************************
* 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;
}

View File

@ -0,0 +1,64 @@
/****************************************************************************
* 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);
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_GETSET_H */

View File

@ -0,0 +1,439 @@
/****************************************************************************
* 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
/* 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);
}
/* 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);
}

View File

@ -0,0 +1,530 @@
/****************************************************************************
* 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/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 Data
****************************************************************************/
static const uint8_t g_allones[8] =
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
/****************************************************************************
* 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;
}
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_SLPCON1, 0x01); /* 00000001 no CLKOUT, default divisor */
mrf24j40_setreg(dev->spi, MRF24J40_BBREG6 , 0x40); /* 01000000 Append RSSI to rx packets */
/* Set this in reset since it can exist for all device modes. See pg 101 */
mrf24j40_setreg(dev->spi, MRF24J40_FRMOFFSET, 0x15);
/* 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 WAKECNT (SLPACK 0x35<6:0>) value = 0xC8 to set the main oscillator
* (20 MHz) start-up timer value.
*/
mrf24j40_setreg(dev->spi, MRF24J40_SLPACK, 0xC8);
/* Set WAKETIME to recommended value for 100kHz SLPCLK Source */
mrf24j40_setreg(dev->spi, MRF24J40_WAKETIMEL, 0xD2);
mrf24j40_setreg(dev->spi, MRF24J40_WAKETIMEH, 0x00);
/* 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);
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_pacontrol(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;
switch (attr)
{
case IEEE802154_ATTR_MAC_PANID:
{
mrf24j40_setpanid(dev, attrval->mac.panid);
ret = IEEE802154_STATUS_SUCCESS;
}
break;
case IEEE802154_ATTR_MAC_SADDR:
{
mrf24j40_setsaddr(dev, attrval->mac.saddr);
ret = IEEE802154_STATUS_SUCCESS;
}
break;
case IEEE802154_ATTR_MAC_EADDR:
{
mrf24j40_seteaddr(dev, attrval->mac.eaddr);
ret = IEEE802154_STATUS_SUCCESS;
}
break;
case IEEE802154_ATTR_MAC_COORD_SADDR:
{
mrf24j40_setcoordsaddr(dev, attrval->mac.coordsaddr);
ret = IEEE802154_STATUS_SUCCESS;
}
break;
case IEEE802154_ATTR_MAC_COORD_EADDR:
{
mrf24j40_setcoordeaddr(dev, attrval->mac.coordeaddr);
ret = IEEE802154_STATUS_SUCCESS;
}
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);
}
ret = IEEE802154_STATUS_SUCCESS;
}
break;
case IEEE802154_ATTR_PHY_CHAN:
{
mrf24j40_setchannel(dev, attrval->phy.chan);
ret = IEEE802154_STATUS_SUCCESS;
}
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;
}
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;
}

View File

@ -0,0 +1,71 @@
/****************************************************************************
* 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_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 */

View File

@ -0,0 +1,286 @@
/****************************************************************************
* drivers/wireless/ieee802154/mrf24j40/mrf24j40_reg.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.
*
****************************************************************************/
/* MRF24J40 Registers *******************************************************/
#define MRF24J40_RXMCR 0x00
#define MRF24J40_PANIDL 0x01
#define MRF24J40_PANIDH 0x02
#define MRF24J40_SADRL 0x03
#define MRF24J40_SADRH 0x04
#define MRF24J40_EADR0 0x05
#define MRF24J40_EADR1 0x06
#define MRF24J40_EADR2 0x07
#define MRF24J40_EADR3 0x08
#define MRF24J40_EADR4 0x09
#define MRF24J40_EADR5 0x0A
#define MRF24J40_EADR6 0x0B
#define MRF24J40_EADR7 0x0C
#define MRF24J40_RXFLUSH 0x0D
#define MRF24J40_ORDER 0x10
#define MRF24J40_TXMCR 0x11
#define MRF24J40_ACKTMOUT 0x12
#define MRF24J40_ESLOTG1 0x13
#define MRF24J40_SYMTICKL 0x14
#define MRF24J40_SYMTICKH 0x15
#define MRF24J40_PACON0 0x16
#define MRF24J40_PACON1 0x17
#define MRF24J40_PACON2 0x18
#define MRF24J40_TXBCON0 0x1A
#define MRF24J40_TXNCON 0x1B
#define MRF24J40_TXG1CON 0x1C
#define MRF24J40_TXG2CON 0x1D
#define MRF24J40_ESLOTG23 0x1E
#define MRF24J40_ESLOTG45 0x1F
#define MRF24J40_ESLOTG67 0x20
#define MRF24J40_TXPEND 0x21
#define MRF24J40_WAKECON 0x22
#define MRF24J40_FRMOFFSET 0x23
#define MRF24J40_TXSTAT 0x24
#define MRF24J40_TXBCON1 0x25
#define MRF24J40_GATECLK 0x26
#define MRF24J40_TXTIME 0x27
#define MRF24J40_HSYMTMRL 0x28
#define MRF24J40_HSYMTMRH 0x29
#define MRF24J40_SOFTRST 0x2A
#define MRF24J40_SECCON0 0x2C
#define MRF24J40_SECCON1 0x2C
#define MRF24J40_TXSTBL 0x2E
#define MRF24J40_RXSR 0x30
#define MRF24J40_INTSTAT 0x31
#define MRF24J40_INTCON 0x32
#define MRF24J40_GPIO 0x33
#define MRF24J40_TRISGPIO 0x34
#define MRF24J40_SLPACK 0x35
#define MRF24J40_RFCTL 0x36
#define MRF24J40_SECCR2 0x37
#define MRF24J40_BBREG0 0x38
#define MRF24J40_BBREG1 0x39
#define MRF24J40_BBREG2 0x3A
#define MRF24J40_BBREG3 0x3B
#define MRF24J40_BBREG4 0x3C
#define MRF24J40_BBREG6 0x3E
#define MRF24J40_CCAEDTH 0x3F
#define MRF24J40_FIFO_BASE 0x80000000
#define MRF24J40_LONGREG_BASE 0x80000200
#define MRF24J40_RXBUF_BASE 0x80000300
#define MRF24J40_TXNORM_FIFO (MRF24J40_FIFO_BASE + 0x000)
#define MRF24J40_BEACON_FIFO (MRF24J40_FIFO_BASE + 0x080)
#define MRF24J40_GTS1_FIFO (MRF24J40_FIFO_BASE + 0x100)
#define MRF24J40_GTS2_FIFO (MRF24J40_FIFO_BASE + 0x180)
#define MRF24J40_RFCON0 (MRF24J40_LONGREG_BASE + 0x00)
#define MRF24J40_RFCON1 (MRF24J40_LONGREG_BASE + 0x01)
#define MRF24J40_RFCON2 (MRF24J40_LONGREG_BASE + 0x02)
#define MRF24J40_RFCON3 (MRF24J40_LONGREG_BASE + 0x03)
#define MRF24J40_RFCON5 (MRF24J40_LONGREG_BASE + 0x05)
#define MRF24J40_RFCON6 (MRF24J40_LONGREG_BASE + 0x06)
#define MRF24J40_RFCON7 (MRF24J40_LONGREG_BASE + 0x07)
#define MRF24J40_RFCON8 (MRF24J40_LONGREG_BASE + 0x08)
#define MRF24J40_SLPCAL0 (MRF24J40_LONGREG_BASE + 0x09)
#define MRF24J40_SLPCAL1 (MRF24J40_LONGREG_BASE + 0x0A)
#define MRF24J40_SLPCAL2 (MRF24J40_LONGREG_BASE + 0x0B)
#define MRF24J40_RFSTATE (MRF24J40_LONGREG_BASE + 0x0F)
#define MRF24J40_RSSI (MRF24J40_LONGREG_BASE + 0x10)
#define MRF24J40_SLPCON0 (MRF24J40_LONGREG_BASE + 0x11)
#define MRF24J40_SLPCON1 (MRF24J40_LONGREG_BASE + 0x20)
#define MRF24J40_WAKETIMEL (MRF24J40_LONGREG_BASE + 0x22)
#define MRF24J40_WAKETIMEH (MRF24J40_LONGREG_BASE + 0x23)
#define MRF24J40_REMCNTL (MRF24J40_LONGREG_BASE + 0x24)
#define MRF24J40_REMCNTH (MRF24J40_LONGREG_BASE + 0x25)
#define MRF24J40_MAINCNT0 (MRF24J40_LONGREG_BASE + 0x26)
#define MRF24J40_MAINCNT1 (MRF24J40_LONGREG_BASE + 0x27)
#define MRF24J40_MAINCNT2 (MRF24J40_LONGREG_BASE + 0x28)
#define MRF24J40_MAINCNT3 (MRF24J40_LONGREG_BASE + 0x29)
#define MRF24J40_TESTMODE (MRF24J40_LONGREG_BASE + 0x2F)
#define MRF24J40_ASSOEADR0 (MRF24J40_LONGREG_BASE + 0x30)
#define MRF24J40_ASSOEADR1 (MRF24J40_LONGREG_BASE + 0x31)
#define MRF24J40_ASSOEADR2 (MRF24J40_LONGREG_BASE + 0x32)
#define MRF24J40_ASSOEADR3 (MRF24J40_LONGREG_BASE + 0x33)
#define MRF24J40_ASSOEADR4 (MRF24J40_LONGREG_BASE + 0x34)
#define MRF24J40_ASSOEADR5 (MRF24J40_LONGREG_BASE + 0x35)
#define MRF24J40_ASSOEADR6 (MRF24J40_LONGREG_BASE + 0x36)
#define MRF24J40_ASSOEADR7 (MRF24J40_LONGREG_BASE + 0x37)
#define MRF24J40_ASSOSADR0 (MRF24J40_LONGREG_BASE + 0x38)
#define MRF24J40_ASSOSADR1 (MRF24J40_LONGREG_BASE + 0x39)
#define MRF24J40_UPNONCE0 (MRF24J40_LONGREG_BASE + 0x40)
#define MRF24J40_UPNONCE1 (MRF24J40_LONGREG_BASE + 0x41)
#define MRF24J40_UPNONCE2 (MRF24J40_LONGREG_BASE + 0x42)
#define MRF24J40_UPNONCE3 (MRF24J40_LONGREG_BASE + 0x43)
#define MRF24J40_UPNONCE4 (MRF24J40_LONGREG_BASE + 0x44)
#define MRF24J40_UPNONCE5 (MRF24J40_LONGREG_BASE + 0x45)
#define MRF24J40_UPNONCE6 (MRF24J40_LONGREG_BASE + 0x46)
#define MRF24J40_UPNONCE7 (MRF24J40_LONGREG_BASE + 0x47)
#define MRF24J40_UPNONCE8 (MRF24J40_LONGREG_BASE + 0x48)
#define MRF24J40_UPNONCE9 (MRF24J40_LONGREG_BASE + 0x49)
#define MRF24J40_UPNONCE10 (MRF24J40_LONGREG_BASE + 0x4A)
#define MRF24J40_UPNONCE11 (MRF24J40_LONGREG_BASE + 0x4B)
#define MRF24J40_UPNONCE12 (MRF24J40_LONGREG_BASE + 0x4C)
/* INTSTAT bits */
#define MRF24J40_INTSTAT_TXNIF (1 << 0)
#define MRF24J40_INTSTAT_TXG1IF (1 << 1)
#define MRF24J40_INTSTAT_TXG2IF (1 << 2)
#define MRF24J40_INTSTAT_RXIF (1 << 3)
#define MRF24J40_INTSTAT_SECIF (1 << 4)
#define MRF24J40_INTSTAT_HSYMTMRIF (1 << 5)
#define MRF24J40_INTSTAT_WAKEIF (1 << 6)
#define MRF24J40_INTSTAT_SLPIF (1 << 7)
/* RXMCR bits */
#define MRF24J40_RXMCR_PROMI (1 << 0) /* Enable promisc mode (rx all valid packets) */
#define MRF24J40_RXMCR_ERRPKT 0x02 /* Do not check CRC */
#define MRF24J40_RXMCR_COORD 0x04 /* Enable coordinator mode ??? DIFFERENCE ??? - not used in datasheet! */
#define MRF24J40_RXMCR_PANCOORD 0x08 /* Enable PAN coordinator mode ??? DIFFERENCE ??? */
#define MRF24J40_RXMCR_NOACKRSP 0x20 /* Enable auto ACK when a packet is rxed */
/* TXMCR bits */
#define MRF24J40_TXMCR_CSMABF0 (1 << 0)
#define MRF24J40_TXMCR_CSMABF1 0x02
#define MRF24J40_TXMCR_CSMABF2 0x04
#define MRF24J40_TXMCR_MACMINBE0 0x08
#define MRF24J40_TXMCR_MACMINBE1 0x10
#define MRF24J40_TXMCR_SLOTTED 0x20
#define MRF24J40_TXMCR_BATLIFEXT 0x40
#define MRF24J40_TXMCR_NOCSMA 0x80
/* ACKTMOUT bits */
#define MRF24J40_ACKTMOUT_MAWD 0xEF
#define MRF24J40_ACKTMOUT_DRPACK 0x80
/* INTCON bits */
#define MRF24J40_INTCON_SLPIE 0x80
#define MRF24J40_INTCON_WAKEIE 0x40
#define MRF24J40_INTCON_HSYMTMRIE 0x20
#define MRF24J40_INTCON_SECIE 0x10
#define MRF24J40_INTCON_RXIE 0x08
#define MRF24J40_INTCON_TXG2IE 0x04
#define MRF24J40_INTCON_TXG1IE 0x02
#define MRF24J40_INTCON_TXNIE (1 << 0)
/* BBREG1 bits */
#define MRF24J40_BBREG1_RXDECINV 0x04 /* Enable/Disable packet reception */
/* BBREG2 bits */
#define MRF24J40_BBREG2_CCAMODE_ED 0x80
#define MRF24J40_BBREG2_CCAMODE_CS 0x40
/* TXNCON bits */
#define MRF24J40_TXNCON_TXNTRIG (1 << 0) /* Trigger packet tx, automatically cleared */
#define MRF24J40_TXNCON_TXNSECEN 0x02 /* Enable security */
#define MRF24J40_TXNCON_TXNACKREQ 0x04 /* An ACK is requested for this pkt */
#define MRF24J40_TXNCON_INDIRECT 0x08 /* Activate indirect tx bit (for coordinators) */
#define MRF24J40_TXNCON_FPSTAT 0x10 /* Status of the frame pending big in txed acks */
/* TXSTAT bits */
#define MRF24J40_TXSTAT_TXNSTAT (1 << 0)
#define MRF24J40_TXSTAT_TXG1STAT (1 << 1)
#define MRF24J40_TXSTAT_TXG2STAT (1 << 2)
#define MRF24J40_TXSTAT_CCAFAIL (1 << 5)
#define MRF24J40_TXSTAT_X_SHIFT 6
#define MRF24J40_TXSTAT_X_MASK (3 << MRF24J40_TXSTAT_X_SHIFT)
/* TXBCON0 bits */
#define MRF24J40_TXBCON0_TXBTRIG 0x01
#define MRF24J40_TXBCON0_TXBSECEN 0x02
/* TXBCON1 bits */
#define MRF24J40_TXBCON1_RSSINUM 0x30
#define MRF24J40_TXBCON1_NWU_BCN 0x40
#define MRF24J40_TXBCON1_TXBMSK 0x80
/* WAKECON bits */
#define MRF24J40_WAKECON_INTL 0x3F
#define MRF24J40_WAKECON_REGWAKE 0x40
#define MRF24J40_WAKECON_IMMWAKE 0x80
/* WAKECON bits */
#define MRF24J40_WAKECON_INTL 0x3F
#define MRF24J40_WAKECON_REGWAKE 0x40
#define MRF24J40_WAKECON_IMMWAKE 0x80
/* ESLOTG1 bits */
#define MRF24J40_ESLOTG1_CAP 0x0F
#define MRF24J40_ESLOTG1_GTS1 0xF0
/* SLPCAL2 bits */
#define MRF24J40_SLPCAL2_SLPCAL 0x0F
#define MRF24J40_SLPCAL2_SLPCALEN 0x10
#define MRF24J40_SLPCAL2_SLPCALRDY 0x80
/* RFCON7 bits */
#define MRF24J40_RFCON7_SEL_32KHZ 0x40
#define MRF24J40_RFCON7_SEL_100KHZ 0x80
/* SLPACK bits */
#define MRF24J40_SLPACK_WAKECNT0_6 0x7F
#define MRF24J40_SLPACK_SLPACK 0x80
/* RXFLUSH bits */
#define MRF24J40_RXFLUSH_RXFLUSH 0x01
#define MRF24J40_RXFLUSH_BCNONLY 0x02
#define MRF24J40_RXFLUSH_DATAONLY 0x04
#define MRF24J40_RXFLUSH_CMDONLY 0x08
#define MRF24J40_RXFLUSH_WAKEPAD 0x20
#define MRF24J40_RXFLUSH_WAKEPOL 0x40
#define MRF24J40_RXFLUSH_SHIFT_RXFLUSH 0
#define MRF24J40_RXFLUSH_SHIFT_BCNONLY 1
#define MRF24J40_RXFLUSH_SHIFT_DATAONLY 2
#define MRF24J40_RXFLUSH_SHIFT_CMDONLY 3
#define MRF24J40_RXFLUSH_SHIFT_WAKEPAD 5
#define MRF24J40_RXFLUSH_SHIFT_WAKEPOL 6

View File

@ -0,0 +1,189 @@
/****************************************************************************
* 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 "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;
}

View 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 */