nrf52/nrf52_radio: various changes to support IEEE802154

- remove read-write logic - this should be handled by radio protocol implementation
- remove EVENTS and TASKS bit definitions - we can just use a signle definition
- add more radio ops
- fix frequency configuration
- fix printf warnings
- fix radio reset
This commit is contained in:
raiden00pl 2024-01-20 15:07:43 +01:00 committed by Xiang Xiao
parent a99275ec1a
commit 3f763f5d69
5 changed files with 332 additions and 542 deletions

View File

@ -42,6 +42,8 @@ config ARCH_CHIP_NRF52840
select NRF52_HAVE_USBDEV
select NRF52_HAVE_PWM3
select NRF52_HAVE_CRYPTOCELL
select NRF52_HAVE_IEEE802154
select NRF52_HAVE_BLELR
endchoice # NRF52 Chip Selection
@ -134,6 +136,14 @@ config NRF52_HAVE_CRYPTOCELL
bool
default n
config NRF52_HAVE_BLELE
bool
default n
config NRF52_HAVE_IEEE802154
bool
default n
# Peripheral Selection
config NRF52_I2C_MASTER
@ -611,6 +621,18 @@ endif # NRF52_PWM
endmenu # PWM configuration
menu "RADIO Configuration"
if NRF52_RADIO
config NRF52_RADIO_CUSTOM
bool "RADIO uses custom IRQ handlers"
default n
endif #NRF52_RADIO
endmenu # "RADIO Configuration"
menu "SAADC Configuration"
if NRF52_SAADC

View File

@ -206,146 +206,6 @@
/* Register Bitfield Definitions ********************************************/
/* TASKS_TXEN Register */
#define RADIO_TASKS_TXEN (1 << 0) /* Bit 0: Enable RADIO in TX mode */
/* TASKS_RXEN Register */
#define RADIO_TASKS_RXEN (1 << 0) /* Bit 0: Enable RADIO in RX mode */
/* TASKS_START Register */
#define RADIO_TASKS_START (1 << 0) /* Bit 0: Start RADIO */
/* TASKS_STOP Register */
#define RADIO_TASKS_STOP (1 << 0) /* Bit 0: Stop RADIO */
/* TASKS_DISABLE Register */
#define RADIO_TASKS_DISABLE (1 << 0) /* Bit 0: Disable RADIO */
/* TASKS_RSSISTART Register */
#define RADIO_TASKS_RSSISTART (1 << 0) /* Bit 0: Start the RSSI */
/* TASKS_RSSISTOP Register */
#define RADIO_TASKS_RSSISTOP (1 << 0) /* Bit 0: Stop the RSSI */
/* TASKS_BCSTART Register */
#define RADIO_TASKS_BCSTART (1 << 0) /* Bit 0: Start the bit counter */
/* TASKS_BCSTOP Register */
#define RADIO_TASKS_BCSTOP (1 << 0) /* Bit 0: Stop the bit counter */
/* TASKS_EDSTART Register */
#define RADIO_TASKS_EDSTART (1 << 0) /* Bit 0: Start the energy detect measurement (IEEE 802.15.4) */
/* TASKS_EDSTOP Register */
#define RADIO_TASKS_EDSTOP (1 << 0) /* Bit 0: Stop the energy detect measurement (IEEE 802.15.4) */
/* TASKS_CCASTART Register */
#define RADIO_TASKS_CCASTART (1 << 0) /* Bit 0: Start the channel assessment (IEEE 802.15.4) */
/* TASKS_CCASTOP Register */
#define RADIO_TASKS_CCASTOP (1 << 0) /* Bit 0: Stop the channel assessment (IEEE 802.15.4) */
/* EVENTS_READY Register */
#define RADIO_EVENTS_READY (1 << 0) /* Bit 0: RADIO has ramped up and is ready to be started */
/* EVENTS_ADDRESS Register */
#define RADIO_EVENTS_ADDRESS (1 << 0) /* Bit 0: Address sent or received */
/* EVENTS_PAYLOAD Register */
#define RADIO_EVENTS_PAYLOAD (1 << 0) /* Bit 0: Packet payload sent or received */
/* EVENTS_END Register */
#define RADIO_EVENTS_END (1 << 0) /* Bit 0: Packet sent or received */
/* EVENTS_DISABLED Register */
#define RADIO_EVENTS_DISABLED (1 << 0) /* Bit 0: RADIO has been disabled */
/* EVENTS_DEVMATCH Register */
#define RADIO_EVENTS_DEVMATCH (1 << 0) /* Bit 0: A device address match */
/* EVENTS_DEVMISS Register */
#define RADIO_EVENTS_DEVMISS (1 << 0) /* Bit 0: No device address match */
/* EVENTS_RSSIEND Register */
#define RADIO_EVENTS_RSSIEND (1 << 0) /* Bit 0: Sampling of receive signal strength complete */
/* EVENTS_BCMATCH Register */
#define RADIO_EVENTS_BCMATCH (1 << 0) /* Bit 0: Bit counter reached bit count value */
/* EVENTS_CRCOK Register */
#define RADIO_EVENTS_CRCOK (1 << 0) /* Bit 0: Packet received with CRC ok */
/* EVENTS_CRCERROR Register */
#define RADIO_EVENTS_CRCERROR (1 << 0) /* Bit 0: Packet received with CRC error */
/* EVENTS_FRAMESTART Register */
#define RADIO_EVENTS_FRAMESTART (1 << 0) /* Bit 0: IEEE 802.15.4 length field received*/
/* EVENTS_EDEND Register */
#define RADIO_EVENTS_EDEND (1 << 0) /* Bit 0: ampling of energy detection complete */
/* EVENTS_EDSTOPPED Register */
#define RADIO_EVENTS_EDSTOPPED (1 << 0) /* Bit 0: The sampling of energy detection has stopped */
/* EVENTS_CCAIDLE Register */
#define RADIO_EVENTS_CCAIDLE (1 << 0) /* Bit 0: Wireless medium in idle */
/* EVENTS_CCABUSY Register */
#define RADIO_EVENTS_CCABUSY (1 << 0) /* Bit 0: Wireless medium busy */
/* EVENTS_CCASTOPPED Register */
#define RADIO_EVENTS_CCASTOPPED (1 << 0) /* Bit 0: The CCA has stopped */
/* EVENTS_RATEBOOST Register */
#define RADIO_EVENTS_RATEBOOST (1 << 0) /* Bit 0: Ble_LR CI field received */
/* EVENTS_TXREADY Register */
#define RADIO_EVENTS_TXREADY (1 << 0) /* Bit 0: RADIO has ramped up and is ready to be started TX path */
/* EVENTS_RXREADY Register */
#define RADIO_EVENTS_RXREADY (1 << 0) /* Bit 0: RADIO has ramped up and is ready to be started RX path */
/* EVENTS_MHRMATCH Register */
#define RADIO_EVENTS_MHRMATCH (1 << 0) /* Bit 0: MAC header match found */
/* EVENTS_PHYEND Register */
#define RADIO_EVENTS_PHYEND (1 << 0) /* Bit 0: Last bit is sent on air */
/* SHORTS Register */
#define RADIO_SHORTS_READY_START (1 << 0) /* Bit 0: Shortcut between event READY and task START */
@ -622,6 +482,12 @@
# define RADIO_CCACTRL_CCAMODE_CANDED (2 << RADIO_CCACTRL_CCAMODE_SHIFT)
# define RADIO_CCACTRL_CCAMODE_CORED (3 << RADIO_CCACTRL_CCAMODE_SHIFT)
# define RADIO_CCACTRL_CCAMODE_EDTST1 (4 << RADIO_CCACTRL_CCAMODE_SHIFT)
#define RADIO_CCACTRL_CCAEDTHRES_SHIFT (8)
#define RADIO_CCACTRL_CCAEDTHRES_MASK (0xff << RADIO_CCACTRL_CCAEDTHRES_SHIFT)
#define RADIO_CCACTRL_CCACORRTHRES_SHIFT (16)
#define RADIO_CCACTRL_CCACORRTHRES_MASK (0xff << RADIO_CCACTRL_CCACORRTHRES_SHIFT)
#define RADIO_CCACTRL_CCACORRCNT_SHIFT (24)
#define RADIO_CCACTRL_CCACORRCNT_MASK (0xff << RADIO_CCACTRL_CCACORRCNT_SHIFT)
/* POWER Register */

View File

@ -27,6 +27,8 @@
#include <nuttx/config.h>
#include "arm_internal.h"
/****************************************************************************
* Public Function Prototypes / Inline Functions
****************************************************************************/

View File

@ -41,15 +41,6 @@
#include "hardware/nrf52_radio.h"
#include "hardware/nrf52_utils.h"
#warning NRF52 RADIO support is EXPERIMENTAL!
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define NRF52_RADIO_RXBUFFER (255)
#define NRF52_RADIO_TXBUFFER (255)
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -64,17 +55,20 @@ static uint32_t nrf52_radio_getreg(struct nrf52_radio_dev_s *dev,
/* Radio operations *********************************************************/
static void nrf52_radio_reset(struct nrf52_radio_dev_s *dev);
static void nrf52_radio_inten(struct nrf52_radio_dev_s *dev, uint32_t irq);
static void nrf52_radio_intclr(struct nrf52_radio_dev_s *dev, uint32_t irq);
static void nrf52_radio_shorts(struct nrf52_radio_dev_s *dev, uint32_t sh);
static int nrf52_radio_power(struct nrf52_radio_dev_s *dev, bool state);
static int nrf52_radio_mode_set(struct nrf52_radio_dev_s *dev,
uint8_t mode);
static int nrf52_radio_freq_set(struct nrf52_radio_dev_s *dev,
uint32_t freq);
static int nrf52_radio_rssi_get(struct nrf52_radio_dev_s *dev,
int *rssi);
int8_t *rssi);
static int nrf52_radio_txpower_set(struct nrf52_radio_dev_s *dev,
uint8_t txpower);
static int nrf52_radio_tifs_set(struct nrf52_radio_dev_s *dev,
uint16_t us);
static int nrf52_radio_tifs_set(struct nrf52_radio_dev_s *dev, uint16_t us);
static int nrf52_radio_pkt_cfg(struct nrf52_radio_dev_s *dev,
struct nrf52_radio_pktcfg_s *cfg);
static int nrf52_radio_crc_cfg(struct nrf52_radio_dev_s *dev,
@ -83,22 +77,15 @@ static int nrf52_radio_white_set(struct nrf52_radio_dev_s *dev,
uint8_t init);
static int nrf52_radio_addr_set(struct nrf52_radio_dev_s *dev, uint8_t i,
struct nrf52_radio_addr_s *addr);
static int nrf52_radio_write(struct nrf52_radio_dev_s *dev,
uint8_t *buf, int len);
static int nrf52_radio_read(struct nrf52_radio_dev_s *dev,
uint8_t *buf, int len);
static void nrf52_radio_dumpregs(struct nrf52_radio_dev_s *dev);
/* Radio interrupts *********************************************************/
static int nrf52_radio_isr(int irq, void *context, void *arg);
static int nrf52_radio_isr_rx(struct nrf52_radio_dev_s *dev);
static int nrf52_radio_isr_tx(struct nrf52_radio_dev_s *dev);
/* Radio configuration ******************************************************/
static int nrf52_radio_setup(struct nrf52_radio_dev_s *dev);
static int nrf52_radio_reset(struct nrf52_radio_dev_s *dev);
#ifdef CONFIG_NRF52_HAVE_IEEE802154
static void nrf52_radio_sfd_set(struct nrf52_radio_dev_s *dev, uint8_t sfd);
static void nrf52_radio_edcnt_set(struct nrf52_radio_dev_s *dev,
uint32_t edcnt);
static void nrf52_radio_cca_cfg(struct nrf52_radio_dev_s *dev,
struct nrf52_radio_cca_s *cca);
#endif
/****************************************************************************
* Private Data
@ -107,8 +94,14 @@ static int nrf52_radio_reset(struct nrf52_radio_dev_s *dev);
/* NRF52 radio operations */
struct nrf52_radio_dev_s;
struct nrf52_radio_ops_s g_nrf52_radio_ops =
static struct nrf52_radio_ops_s g_nrf52_radio_ops =
{
.reset = nrf52_radio_reset,
.putreg = nrf52_radio_putreg,
.getreg = nrf52_radio_getreg,
.inten = nrf52_radio_inten,
.intclr = nrf52_radio_intclr,
.shorts = nrf52_radio_shorts,
.power = nrf52_radio_power,
.mode_set = nrf52_radio_mode_set,
.freq_set = nrf52_radio_freq_set,
@ -119,33 +112,23 @@ struct nrf52_radio_ops_s g_nrf52_radio_ops =
.white_set = nrf52_radio_white_set,
.crc_cfg = nrf52_radio_crc_cfg,
.addr_set = nrf52_radio_addr_set,
.read = nrf52_radio_read,
.write = nrf52_radio_write,
.dumpregs = nrf52_radio_dumpregs
.dumpregs = nrf52_radio_dumpregs,
#ifdef CONFIG_NRF52_HAVE_IEEE802154
.sfd_set = nrf52_radio_sfd_set,
.edcnt_set = nrf52_radio_edcnt_set,
.cca_cfg = nrf52_radio_cca_cfg,
#endif
};
/* RX buffer 1 */
uint8_t g_nrf52_radio_dev_rx1[NRF52_RADIO_RXBUFFER];
/* TX buffer 1 */
uint8_t g_nrf52_radio_dev_tx1[NRF52_RADIO_TXBUFFER];
/* Radio device 1 */
struct nrf52_radio_dev_s g_nrf52_radio_dev_1 =
static struct nrf52_radio_dev_s g_nrf52_radio_dev_1 =
{
.ops = &g_nrf52_radio_ops,
.irq = NRF52_IRQ_RADIO,
.base = NRF52_RADIO_BASE,
.mode = 0,
.rxbuf_len = NRF52_RADIO_RXBUFFER,
.txbuf_len = NRF52_RADIO_TXBUFFER,
.rxbuf = g_nrf52_radio_dev_rx1,
.txbuf = g_nrf52_radio_dev_tx1,
.lock = NXMUTEX_INITIALIZER,
.sem_isr = SEM_INITIALIZER(0),
};
/****************************************************************************
@ -181,6 +164,45 @@ static uint32_t nrf52_radio_getreg(struct nrf52_radio_dev_s *dev,
return getreg32(dev->base + offset);
}
/****************************************************************************
* Name: nrf52_radio_inten
*
* Description:
* Enable interrupts.
*
****************************************************************************/
static void nrf52_radio_inten(struct nrf52_radio_dev_s *dev, uint32_t irq)
{
nrf52_radio_putreg(dev, NRF52_RADIO_INTENSET_OFFSET, irq);
}
/****************************************************************************
* Name: nrf52_radio_intclr
*
* Description:
* Disable interrupts.
*
****************************************************************************/
static void nrf52_radio_intclr(struct nrf52_radio_dev_s *dev, uint32_t irq)
{
nrf52_radio_putreg(dev, NRF52_RADIO_INTENCLR_OFFSET, irq);
}
/****************************************************************************
* Name: nrf52_radio_shorts
*
* Description:
* Configure RADIO shorts
*
****************************************************************************/
static void nrf52_radio_shorts(struct nrf52_radio_dev_s *dev, uint32_t sh)
{
nrf52_radio_putreg(dev, NRF52_RADIO_SHORTS_OFFSET, sh);
}
/****************************************************************************
* Name: nrf52_radio_power
*
@ -234,7 +256,12 @@ static int nrf52_radio_mode_set(struct nrf52_radio_dev_s *dev,
/* Check if mode is valid */
if (mode > NRF52_RADIO_MODE_IEEE802154)
#ifndef CONFIG_NRF52_HAVE_IEEE802154
if (mode >= NRF52_RADIO_MODE_LAST)
#else
if (mode >= NRF52_RADIO_MODE_LAST &&
mode != NRF52_RADIO_MODE_IEEE802154)
#endif
{
wlerr("ERROR: unsupported RADIO mode %d\n", mode);
ret = -EINVAL;
@ -272,7 +299,7 @@ static int nrf52_radio_freq_set(struct nrf52_radio_dev_s *dev,
if (freq < 2360 || freq > 2500)
{
wlerr("ERROR: unsupported radio frequency %d MHz\n", freq);
wlerr("ERROR: unsupported radio frequency %" PRId32" MHz\n", freq);
ret = -EINVAL;
goto errout;
}
@ -282,6 +309,11 @@ static int nrf52_radio_freq_set(struct nrf52_radio_dev_s *dev,
if (freq < 2400)
{
regval |= RADIO_FREQUENCY_MAP_2360MHZ;
freq -= 2360;
}
else
{
freq -= 2400;
}
regval |= freq;
@ -300,14 +332,13 @@ errout:
****************************************************************************/
static int nrf52_radio_rssi_get(struct nrf52_radio_dev_s *dev,
int *rssi)
int8_t *rssi)
{
uint32_t regval = 0;
/* Start the RSSI meassurement */
nrf52_radio_putreg(dev, NRF52_RADIO_TASKS_RSSISTART_OFFSET,
RADIO_TASKS_RSSISTART);
nrf52_radio_putreg(dev, NRF52_RADIO_TASKS_RSSISTART_OFFSET, 1);
/* Wait for the RSSI sample */
@ -316,7 +347,7 @@ static int nrf52_radio_rssi_get(struct nrf52_radio_dev_s *dev,
/* Get the RSSI sample */
regval = nrf52_radio_getreg(dev, NRF52_RADIO_RSSISAMPLE_OFFSET);
*rssi = -(int)regval;
*rssi = -(int8_t)regval;
return OK;
}
@ -382,13 +413,13 @@ static int nrf52_radio_addr_set(struct nrf52_radio_dev_s *dev, uint8_t i,
/* Get current BASE and PREFIX registers */
base_now = nrf52_radio_getreg(dev, basereg);
UNUSED(base_now);
prefix_now = nrf52_radio_getreg(dev, prefixreg);
/* TODO: check if new address match to old BASE1 */
if (basereg == NRF52_RADIO_BASE1_OFFSET)
{
#warning missing logic!
}
/* Get new BASE */
@ -457,8 +488,7 @@ errout:
*
****************************************************************************/
static int nrf52_radio_tifs_set(struct nrf52_radio_dev_s *dev,
uint16_t us)
static int nrf52_radio_tifs_set(struct nrf52_radio_dev_s *dev, uint16_t us)
{
int ret = OK;
@ -496,7 +526,7 @@ static int nrf52_radio_pkt_cfg(struct nrf52_radio_dev_s *dev,
{
uint32_t pcnf0 = 0;
uint32_t pcnf1 = 0;
int ret = OK;
int ret = OK;
/* LENGTH field length */
@ -532,6 +562,7 @@ static int nrf52_radio_pkt_cfg(struct nrf52_radio_dev_s *dev,
pcnf0 &= (~RADIO_PCNF0_S1INCL);
#ifdef HAVE_RADIO_BLELR
/* Configure code indicator length */
if (cfg->ci_len > RADIO_PCNF0_CILEN_MAX)
@ -565,6 +596,7 @@ static int nrf52_radio_pkt_cfg(struct nrf52_radio_dev_s *dev,
/* Include CRC in LENGTH or not */
pcnf0 |= (cfg->crcinc << RADIO_PCNF0_CRCINC_SHIFT);
#endif
/* Configure maximum payload length */
@ -588,14 +620,17 @@ static int nrf52_radio_pkt_cfg(struct nrf52_radio_dev_s *dev,
/* Configure base address length */
if (cfg->bal_len < RADIO_PCNF1_BALEN_MIN ||
cfg->bal_len > RADIO_PCNF1_BALEN_MAX)
if (cfg->bal_len)
{
ret = -EINVAL;
goto errout;
}
if (cfg->bal_len < RADIO_PCNF1_BALEN_MIN ||
cfg->bal_len > RADIO_PCNF1_BALEN_MAX)
{
ret = -EINVAL;
goto errout;
}
pcnf1 |= (cfg->bal_len << RADIO_PCNF1_BALEN_SHIFT);
pcnf1 |= (cfg->bal_len << RADIO_PCNF1_BALEN_SHIFT);
}
/* Configure on-air endianness of packet */
@ -714,126 +749,6 @@ errout:
return ret;
}
/****************************************************************************
* Name: nrf52_radio_write
*
* Description:
* Write radio packet
*
****************************************************************************/
static int nrf52_radio_write(struct nrf52_radio_dev_s *dev,
uint8_t *buf, int len)
{
int ret = OK;
/* Lock device */
ret = nxmutex_lock(&dev->lock);
if (ret < 0)
{
return ret;
}
/* */
if (len > dev->txbuf_len)
{
ret = -ENOMEM;
goto errout;
}
/* Copy packet */
memcpy(dev->txbuf, buf, len);
/* Set packet pointer */
DEBUGASSERT(nrf52_easydma_valid(&dev->txbuf));
nrf52_radio_putreg(dev, NRF52_RADIO_PACKETPTR_OFFSET, &dev->txbuf);
/* Set state to TX */
dev->state = NRF52_RADIO_STATE_TX;
/* Start TX.
* NOTE: shortcut between READ and START is enabled.
*/
nrf52_radio_putreg(dev, NRF52_RADIO_TASKS_TXEN_OFFSET, RADIO_TASKS_TXEN);
/* Wait for IRQ */
ret = nxsem_wait(&dev->sem_isr);
errout:
/* Unlock device */
nxmutex_unlock(&dev->lock);
return ret;
}
/****************************************************************************
* Name: nrf52_radio_read
*
* Description:
* Read radio packet
*
****************************************************************************/
static int nrf52_radio_read(struct nrf52_radio_dev_s *dev,
uint8_t *buf, int len)
{
int ret = OK;
/* Lock radio */
ret = nxmutex_lock(&dev->lock);
if (ret < 0)
{
return ret;
}
/* */
if (len > dev->rxbuf_len)
{
ret = -ENOMEM;
goto errout;
}
/* Set packet pointer */
DEBUGASSERT(nrf52_easydma_valid(&dev->rxbuf));
nrf52_radio_putreg(dev, NRF52_RADIO_PACKETPTR_OFFSET, &dev->rxbuf);
/* Set state to RX */
dev->state = NRF52_RADIO_STATE_RX;
/* Start RX.
* NOTE: shortcut between READ and START is enabled.
*/
nrf52_radio_putreg(dev, NRF52_RADIO_TASKS_RXEN_OFFSET, RADIO_TASKS_RXEN);
/* Wait for IRQ */
ret = nxsem_wait(&dev->sem_isr);
/* Copy packet */
memcpy(buf, dev->rxbuf, len);
errout:
/* Unlock radio */
nxmutex_unlock(&dev->lock);
return ret;
}
/****************************************************************************
* Name: nrf52_radio_dumpregs
*
@ -846,250 +761,176 @@ static void nrf52_radio_dumpregs(struct nrf52_radio_dev_s *dev)
{
printf("\nnrf52_radio_dumpregs:\n");
printf("SHORTS 0x%08x\n",
printf("SHORTS 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_SHORTS_OFFSET));
printf("INTENSET 0x%08x\n",
printf("INTENSET 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_INTENSET_OFFSET));
printf("CRCSTATUS 0x%08x\n",
printf("CRCSTATUS 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_CRCSTATUS_OFFSET));
printf("RXMATCH 0x%08x\n",
printf("RXMATCH 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_RXMATCH_OFFSET));
printf("RXCRC 0x%08x\n",
printf("RXCRC 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_RXCRC_OFFSET));
printf("DAI 0x%08x\n",
printf("DAI 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAI_OFFSET));
printf("PDUSTAT 0x%08x\n",
printf("PDUSTAT 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_PDUSTAT_OFFSET));
printf("PACKETPTR 0x%08x\n",
printf("PACKETPTR 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_PACKETPTR_OFFSET));
printf("FREQUENCY 0x%08x\n",
printf("FREQUENCY 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_FREQUENCY_OFFSET));
printf("TXPOWER 0x%08x\n",
printf("TXPOWER 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_TXPOWER_OFFSET));
printf("MODE 0x%08x\n",
printf("MODE 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_MODE_OFFSET));
printf("PCNF0 0x%08x\n",
printf("PCNF0 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_PCNF0_OFFSET));
printf("PCNF1 0x%08x\n",
printf("PCNF1 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_PCNF1_OFFSET));
printf("BASE0 0x%08x\n",
printf("BASE0 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_BASE0_OFFSET));
printf("BASE1 0x%08x\n",
printf("BASE1 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_BASE1_OFFSET));
printf("PREFIX0 0x%08x\n",
printf("PREFIX0 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_PREFIX0_OFFSET));
printf("PREFIX1 0x%08x\n",
printf("PREFIX1 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_PREFIX1_OFFSET));
printf("TXADDRESS 0x%08x\n",
printf("TXADDRESS 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_TXADDRESS_OFFSET));
printf("RXADDRESS 0x%08x\n",
nrf52_radio_getreg(dev, NRF52_RADIO_RXADDRESS_OFFSET));
printf("CRCCNF 0x%08x\n",
printf("RXADDRESSES 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_RXADDRESSES_OFFSET));
printf("CRCCNF 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_CRCCNF_OFFSET));
printf("CRCPOLY 0x%08x\n",
printf("CRCPOLY 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_CRCPOLY_OFFSET));
printf("CRCINIT 0x%08x\n",
printf("CRCINIT 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_CRCINIT_OFFSET));
printf("TIFS 0x%08x\n",
printf("TIFS 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_TIFS_OFFSET));
printf("RSSISAMPLE 0x%08x\n",
printf("RSSISAMPLE 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_RSSISAMPLE_OFFSET));
printf("STATE 0x%08x\n",
printf("STATE 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_STATE_OFFSET));
printf("DATAWHITEIV 0x%08x\n",
printf("DATAWHITEIV 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DATAWHITEIV_OFFSET));
printf("BCC 0x%08x\n",
printf("BCC 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_BCC_OFFSET));
printf("DAB0 0x%08x\n",
printf("DAB0 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAB_OFFSET(0)));
printf("DAB1 0x%08x\n",
printf("DAB1 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAB_OFFSET(1)));
printf("DAB2 0x%08x\n",
printf("DAB2 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAB_OFFSET(2)));
printf("DAB3 0x%08x\n",
printf("DAB3 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAB_OFFSET(3)));
printf("DAB4 0x%08x\n",
printf("DAB4 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAB_OFFSET(4)));
printf("DAB5 0x%08x\n",
printf("DAB5 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAB_OFFSET(5)));
printf("DAB6 0x%08x\n",
printf("DAB6 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAB_OFFSET(6)));
printf("DAB7 0x%08x\n",
printf("DAB7 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAB_OFFSET(6)));
printf("DAP0 0x%08x\n",
printf("DAP0 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAP_OFFSET(0)));
printf("DAP1 0x%08x\n",
printf("DAP1 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAP_OFFSET(1)));
printf("DAP2 0x%08x\n",
printf("DAP2 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAP_OFFSET(2)));
printf("DAP3 0x%08x\n",
printf("DAP3 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAP_OFFSET(3)));
printf("DAP4 0x%08x\n",
printf("DAP4 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAP_OFFSET(4)));
printf("DAP5 0x%08x\n",
printf("DAP5 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAP_OFFSET(5)));
printf("DAP6 0x%08x\n",
printf("DAP6 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAP_OFFSET(6)));
printf("DAP7 0x%08x\n",
printf("DAP7 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DAP_OFFSET(6)));
printf("DACNF 0x%08x\n",
printf("DACNF 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_DACNF_OFFSET));
printf("MHRMATCHCONF 0x%08x\n",
printf("MHRMATCHCONF 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_MHRMATCHCONF_OFFSET));
printf("MHRMATCHMAS 0x%08x\n",
printf("MHRMATCHMAS 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_MHRMATCHMAS_OFFSET));
printf("MODECNF0 0x%08x\n",
printf("MODECNF0 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_MODECNF0_OFFSET));
printf("SFD 0x%08x\n",
printf("SFD 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_SFD_OFFSET));
printf("EDCNT 0x%08x\n",
printf("EDCNT 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_EDCNT_OFFSET));
printf("EDSAMPLE 0x%08x\n",
printf("EDSAMPLE 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_EDSAMPLE_OFFSET));
printf("CCACTRL 0x%08x\n",
printf("CCACTRL 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_CCACTRL_OFFSET));
printf("POWER 0x%08x\n",
printf("POWER 0x%08" PRIx32 "\n",
nrf52_radio_getreg(dev, NRF52_RADIO_POWER_OFFSET));
}
#ifdef CONFIG_NRF52_HAVE_IEEE802154
/****************************************************************************
* Name: nrf52_radio_isr_rx
* Name: nrf52_radio_sfd_set
*
* Description:
* RX radio interrupt handler
* Set SFD.
*
****************************************************************************/
static int nrf52_radio_isr_rx(struct nrf52_radio_dev_s *dev)
static void nrf52_radio_sfd_set(struct nrf52_radio_dev_s *dev, uint8_t sfd)
{
/* RX done */
nxsem_post(&dev->sem_isr);
return OK;
nrf52_radio_putreg(dev, NRF52_RADIO_SFD_OFFSET, sfd);
}
/****************************************************************************
* Name: nrf52_radio_isr_tx
* Name: nrf52_radio_edcnt_set
*
* Description:
* TX radio interrupt handler
* Set EDCNT.
*
****************************************************************************/
static int nrf52_radio_isr_tx(struct nrf52_radio_dev_s *dev)
static void nrf52_radio_edcnt_set(struct nrf52_radio_dev_s *dev,
uint32_t edcnt)
{
/* TX done */
nxsem_post(&dev->sem_isr);
return OK;
nrf52_radio_putreg(dev, NRF52_RADIO_EDCNT_OFFSET, edcnt);
}
/****************************************************************************
* Name: nrf52_radio_isr
* Name: nrf52_radio_cca_cfg
*
* Description:
* Radio interrupt handler
* Set CCA configuration
*
****************************************************************************/
static int nrf52_radio_isr(int irq, void *context, void *arg)
{
struct nrf52_radio_dev_s *dev = (struct nrf52_radio_dev_s *)arg;
int ret = OK;
uint32_t state = 0;
DEBUGASSERT(dev);
/* Get radio state */
wlinfo("RADIO ISR STATE=%d\n", dev->state);
/* Handle radio state */
switch (dev->state)
{
case NRF52_RADIO_STATE_RX:
{
/* Transmit DONE */
ret = nrf52_radio_isr_rx(dev);
break;
}
case NRF52_RADIO_STATE_TX:
{
/* Receive DONE */
ret = nrf52_radio_isr_tx(dev);
break;
}
case NRF52_RADIO_STATE_DISABLED:
{
break;
}
default:
{
PANIC();
break;
}
}
/* Clear END event */
nrf52_radio_putreg(dev, NRF52_RADIO_EVENTS_END_OFFSET, 0);
/* Update radio state
* NOTE: shortcut between END and DISABLE is enabled.
*/
dev->state = NRF52_RADIO_STATE_DISABLED;
return ret;
}
/****************************************************************************
* Name: nrf52_radio_setup
*
* Description:
* Initial RADIO setup
*
****************************************************************************/
static int nrf52_radio_setup(struct nrf52_radio_dev_s *dev)
static void nrf52_radio_cca_cfg(struct nrf52_radio_dev_s *dev,
struct nrf52_radio_cca_s *cca)
{
uint32_t regval = 0;
int ret = OK;
DEBUGASSERT(dev);
/* CCA mode of operation */
/* Configure interrupts:
* 1. END - packet sent or received
*/
regval |= (cca->mode << 0);
regval = (RADIO_INT_END);
nrf52_radio_putreg(dev, NRF52_RADIO_INTENSET_OFFSET, regval);
/* CCA energy busy threshold */
/* Configure shortucts:
* 1. shortcut between READY and START
* 2. shortcut between END and DISABLE
*/
regval |= ((cca->edthres << RADIO_CCACTRL_CCAEDTHRES_SHIFT)
& RADIO_CCACTRL_CCAEDTHRES_MASK);
regval = RADIO_SHORTS_READY_START;
regval |= RADIO_SHORTS_END_DISABLE;
nrf52_radio_putreg(dev, NRF52_RADIO_SHORTS_OFFSET, regval);
/* CCA correlator busy threshold */
/* Power on radio */
regval |= ((cca->corrthres << RADIO_CCACTRL_CCACORRTHRES_SHIFT)
& RADIO_CCACTRL_CCACORRTHRES_MASK);
nrf52_radio_power(dev, true);
/* Limit for occurances above CCACORRTHRES */
return ret;
regval |= ((cca->corrcnt << RADIO_CCACTRL_CCACORRCNT_SHIFT)
& RADIO_CCACTRL_CCACORRCNT_MASK);
nrf52_radio_putreg(dev, NRF52_RADIO_CCACTRL_OFFSET, regval);
}
#endif
/****************************************************************************
* Name: nrf52_radio_reset
@ -1099,21 +940,22 @@ static int nrf52_radio_setup(struct nrf52_radio_dev_s *dev)
*
****************************************************************************/
static int nrf52_radio_reset(struct nrf52_radio_dev_s *dev)
static void nrf52_radio_reset(struct nrf52_radio_dev_s *dev)
{
/* Turn off radio power */
nrf52_radio_power(dev, false);
/* Wait some time */
nxsig_usleep(100000);
/* Turn on radio power */
up_udelay(100);
nrf52_radio_power(dev, true);
up_udelay(100);
return OK;
/* Reset radio state */
dev->mode = 0;
dev->tifs = 0;
dev->txpower = 0;
memset(&dev->pktcfg, 0, sizeof(dev->pktcfg));
memset(&dev->addr, 0, sizeof(dev->addr));
}
/****************************************************************************
@ -1132,7 +974,6 @@ struct nrf52_radio_dev_s *
nrf52_radio_initialize(int intf, struct nrf52_radio_board_s *board)
{
struct nrf52_radio_dev_s *dev = NULL;
int ret = OK;
/* Get radio interface */
@ -1157,13 +998,6 @@ nrf52_radio_initialize(int intf, struct nrf52_radio_board_s *board)
/* Reset some data */
memset(&dev->pktcfg, 0, sizeof(struct nrf52_radio_pktcfg_s));
memset(dev->rxbuf, 0, NRF52_RADIO_RXBUFFER);
memset(dev->txbuf, 0, NRF52_RADIO_TXBUFFER);
/* Attach radio interrupt */
irq_attach(dev->irq, nrf52_radio_isr, dev);
up_enable_irq(dev->irq);
/* Connect board-specific data */
@ -1171,21 +1005,7 @@ nrf52_radio_initialize(int intf, struct nrf52_radio_board_s *board)
/* Reset radio */
ret = nrf52_radio_reset(dev);
if (ret < 0)
{
wlerr("ERROR: failed to reset radio interface %d\n", ret);
goto errout;
}
/* Initial radio setup */
ret = nrf52_radio_setup(dev);
if (ret < 0)
{
wlerr("ERROR: failed to setup radio interface %d\n", ret);
goto errout;
}
nrf52_radio_reset(dev);
return dev;

View File

@ -40,6 +40,29 @@
#define NRF52_RADIO_LOGICAL_ADDRESS_MAX (8)
/* Ops */
#define NRF52_RADIO_RESET(lower) lower->ops->reset(lower)
#define NRF52_RADIO_PUTREG(lower, o, v) lower->ops->putreg(lower, o, v)
#define NRF52_RADIO_GETREG(lower, o) lower->ops->getreg(lower, o)
#define NRF52_RADIO_INTEN(lower, i) lower->ops->inten(lower, i)
#define NRF52_RADIO_INTCLR(lower, i) lower->ops->intclr(lower, i)
#define NRF52_RADIO_SHRTSET(lower, s) lower->ops->shorts(lower, s)
#define NRF52_RADIO_PWRSET(lower, pwr) lower->ops->power(lower, pwr)
#define NRF52_RADIO_MODESET(lower, m) lower->ops->mode_set(lower, m)
#define NRF52_RADIO_FREQSET(lower, f) lower->ops->freq_set(lower, f)
#define NRF52_RADIO_RSSIGET(lower, r) lower->ops->rssi_get(lower, r)
#define NRF52_RADIO_TXPWRSET(lower, p) lower->ops->txpower_set(lower, p)
#define NRF52_RADIO_TIFSSET(lower, p) lower->ops->tifs_set(lower, t)
#define NRF52_RADIO_PKTCFG(lower, cfg) lower->ops->pkt_cfg(lower, cfg)
#define NRF52_RADIO_CRCCFG(lower, cfg) lower->ops->crc_cfg(lower, cfg)
#define NRF52_RADIO_WHITESET(lower, cfg) lower->ops->white_set(lower, c)
#define NRF52_RADIO_ADDRSET(lower, i, a) lower->ops->addr_set(lower, i, a)
#define NRF52_RADIO_DUMPREGS(lower) lower->ops->dumpregs(lower)
#define NRF52_RADIO_SFDSET(lower, sfd) lower->ops->sfd_set(lower, sfd)
#define NRF52_RADIO_EDCNTSET(lower, ec) lower->ops->edcnt_set(lower, ec)
#define NRF52_RADIO_CCACFG(lower, cca) lower->ops->cca_cfg(lower, cca)
/****************************************************************************
* Public Types
****************************************************************************/
@ -50,20 +73,18 @@ enum nrf52_radio_mode_e
{
NRF52_RADIO_MODE_NRF1MBIT = 0,
NRF52_RADIO_MODE_NRF2MBIT = 1,
NRF52_RADIO_MODE_BLE1MBIT = 2,
NRF52_RADIO_MODE_BLE2MBIT = 3,
NRF52_RADIO_MODE_BLELR125KBIT = 4,
NRF52_RADIO_MODE_BLELR500KBIT = 5,
NRF52_RADIO_MODE_IEEE802154 = 6
};
NRF52_RADIO_MODE_NRF250KBIT = 2,
NRF52_RADIO_MODE_BLE1MBIT = 3,
NRF52_RADIO_MODE_BLE2MBIT = 4,
#ifdef CONFIG_NRF52_HAVE_BLELR
NRF52_RADIO_MODE_BLELR125KBIT = 5,
NRF52_RADIO_MODE_BLELR500KBIT = 6,
#endif
NRF52_RADIO_MODE_LAST,
/* Radio state */
enum nrf52_radio_state_e
{
NRF52_RADIO_STATE_DISABLED = 0,
NRF52_RADIO_STATE_TX = 1,
NRF52_RADIO_STATE_RX = 2,
#ifdef CONFIG_NRF52_HAVE_IEEE802154
NRF52_RADIO_MODE_IEEE802154 = 15
#endif
};
/* Preamble configuration */
@ -95,7 +116,18 @@ enum nrf52_radio_crc_skipaddr_e
NRF52_RADIO_CRC_SKIPADDR_IEEE802154 = 2,
};
/* On air packet layout:
/* CCA mode of operation */
enum nrf52_radio_cca_mode_e
{
NRF52_RADIO_CCA_ED = 0,
NRF52_RADIO_CCA_CARRIER = 1,
NRF52_RADIO_CCA_CARRIER_AND_ED = 2,
NRF52_RADIO_CCA_CARRIER_OR_ED = 2,
NRF52_RADIO_CCA_EDTEST1 = 4,
};
/* On air packet layout (no IEEE802154 mode):
*
* +---------------------------------------+
* | FIRST |
@ -105,7 +137,6 @@ enum nrf52_radio_crc_skipaddr_e
* | | ADDRESS | | |
* +----------+---------------+----+-------+
*
*
* +----------------------------+
* | Stored on RAM |
* |----+--------+----+---------|
@ -122,6 +153,20 @@ enum nrf52_radio_crc_skipaddr_e
* | | |
* +-------+-------+
*
* For IEEE802154 mode packet layout is different:
*
* +--------------------------------------------------------------------+
* | PHY protocol data unit (PPDU) |
* +--------------------+-----+---------+-------------------------------+
* | Preamble sequence | SFD | Lenght | PHY payload |
* |--------------------+-----+---------+-------------------------------+
* | 5 octets synchronization | 1 octet | Maximum 127 octets (PSDU) |
* | header (SHR) | (PHR) +-------------------------------+
* | | | MAC protocol data unit (MPDU) |
* +--------------------------+---------+-------------------------------+
* | Stored on RAM |
* +-----------------------------------------+
*
*/
/* Radio packet configuration */
@ -166,11 +211,49 @@ struct nrf52_radio_addr_s
uint8_t a4; /* BASE[3] */
};
#ifdef CONFIG_NRF52_HAVE_IEEE802154
/* IEEE 802.15.4 clear channel assessment control */
struct nrf52_radio_cca_s
{
uint8_t mode; /* CCA mode of operation */
uint8_t edthres; /* CCA energy busy threshold */
uint8_t corrthres; /* CCA correlator busy threshold */
uint8_t corrcnt; /* Limit for occurances above CCACORRTHRES */
};
#endif
/* NRF52 radio operations */
struct nrf52_radio_dev_s;
struct nrf52_radio_ops_s
{
/* Reset radio */
void (*reset)(struct nrf52_radio_dev_s *dev);
/* Put register value */
void (*putreg)(struct nrf52_radio_dev_s *dev, uint32_t offset,
uint32_t value);
/* Get register value */
uint32_t (*getreg)(struct nrf52_radio_dev_s *dev, uint32_t offset);
/* Enable interrupts */
void (*inten)(struct nrf52_radio_dev_s *dev, uint32_t irq);
/* Disable interrupts */
void (*intclr)(struct nrf52_radio_dev_s *dev, uint32_t irq);
/* Configure shorts */
void (*shorts)(struct nrf52_radio_dev_s *dev, uint32_t irq);
/* Turn-on/turn-off radio power */
int (*power)(struct nrf52_radio_dev_s *dev, bool state);
@ -185,7 +268,7 @@ struct nrf52_radio_ops_s
/* Get RSSI sample */
int (*rssi_get)(struct nrf52_radio_dev_s *dev, int *rssi);
int (*rssi_get)(struct nrf52_radio_dev_s *dev, int8_t *rssi);
/* Set TX power */
@ -214,19 +297,24 @@ struct nrf52_radio_ops_s
int (*addr_set)(struct nrf52_radio_dev_s *dev, uint8_t i,
struct nrf52_radio_addr_s *addr);
/* Read packet */
int (*read)(struct nrf52_radio_dev_s *dev,
uint8_t *buf, int len);
/* Write packet */
int (*write)(struct nrf52_radio_dev_s *dev,
uint8_t *buf, int len);
/* Dump radio registers */
void (*dumpregs)(struct nrf52_radio_dev_s *dev);
#ifdef CONFIG_NRF52_HAVE_IEEE802154
/* IEEE 802.15.4 start of frame delimiter */
void (*sfd_set)(struct nrf52_radio_dev_s *dev, uint8_t sfd);
/* IEEE 802.15.4 energy detect level */
void (*edcnt_set)(struct nrf52_radio_dev_s *dev, uint32_t edcnt);
/* IEEE 802.15.4 clear channel assessment control */
void (*cca_cfg)(struct nrf52_radio_dev_s *dev,
struct nrf52_radio_cca_s *cca);
#endif
};
/* NRF52 radio board specific data */
@ -247,18 +335,10 @@ struct nrf52_radio_dev_s
uint32_t base; /* Radio base */
uint32_t irq; /* Radio IRQ number */
uint8_t mode; /* Radio mode */
uint8_t state; /* Radio state */
struct nrf52_radio_pktcfg_s pktcfg; /* Current packet */
uint16_t rxbuf_len; /* RX buffer length */
uint16_t txbuf_len; /* TX buffer length */
uint8_t *rxbuf; /* RX buffer */
uint8_t *txbuf; /* TX buffer */
mutex_t lock; /* Mutual exclusion mutex */
sem_t sem_isr; /* Interrupt wait semaphore */
uint16_t tifs; /* Interframe spacing time */
uint8_t txpower; /* TX power */
uint8_t txaddr; /* TX address */
uint8_t rxaddr; /* RX addresses */
struct nrf52_radio_addr_s addr[NRF52_RADIO_LOGICAL_ADDRESS_MAX];
};