[nRF52840] front end module support (#2175)

This commit is contained in:
Hubert Miś
2017-09-06 09:55:47 -07:00
committed by Jonathan Hui
parent 5390449351
commit 75c5fbd1c9
18 changed files with 1704 additions and 88 deletions
+9
View File
@@ -37,6 +37,7 @@ lib_LIBRARIES
COMMONCPPFLAGS = \
-DCONFIG_GPIO_AS_PINRESET \
-DNRF52840_XXAA \
-DENABLE_FEM=1 \
-I$(top_srcdir)/include \
-I$(top_srcdir)/examples/platforms \
-I$(top_srcdir)/src/core \
@@ -53,12 +54,14 @@ COMMONCPPFLAGS
PLATFORM_COMMON_SOURCES = \
alarm.c \
fem.c \
flash.c \
logging.c \
misc.c \
platform.c \
uart.c \
platform-config.h \
platform-fem.h \
platform-nrf5.h \
radio.c \
random.c \
@@ -70,6 +73,7 @@ SINGLEPHY_SOURCES
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_notification_direct.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_priority_drop_direct.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_request_direct.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_direct.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c \
$(NULL)
@@ -85,6 +89,7 @@ SOFTDEVICE_SOURCES
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_priority_drop_swi.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_request_swi.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_swi.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_softdevice.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c \
$(NULL)
@@ -120,6 +125,7 @@ NORDICSEMI_SOURCES
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_fsm.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_pib.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_rx_buffer.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_common.c \
@top_builddir@/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT.c \
@top_builddir@/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT_Conf.h \
@top_builddir@/third_party/NordicSemiconductor/device/gcc_startup_nrf52840.S \
@@ -190,6 +196,9 @@ noinst_HEADERS
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_procedures_duration.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_request.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_rx_buffer.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_api.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.h \
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder 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 HOLDER 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.
*/
/**
* @file
* This file implements the OpenThread FEM helper functions.
*
*/
#include <openthread/config.h>
#include <openthread-core-config.h>
#include <stdint.h>
#include <string.h>
#include "platform-fem.h"
#define ENABLE_FEM 1
#include <nrf_drv_radio802154.h>
void PlatformFemSetConfigParams(const PlatformFemConfigParams *aConfig)
{
nrf_drv_radio802154_fem_control_cfg_t cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.pa_cfg.enable = aConfig->mPaCfg.mEnable;
cfg.pa_cfg.active_high = aConfig->mPaCfg.mActiveHigh;
cfg.pa_cfg.gpio_pin = aConfig->mPaCfg.mGpioPin;
cfg.lna_cfg.enable = aConfig->mLnaCfg.mEnable;
cfg.lna_cfg.active_high = aConfig->mLnaCfg.mActiveHigh;
cfg.lna_cfg.gpio_pin = aConfig->mLnaCfg.mGpioPin;
cfg.ppi_ch_id_clr = aConfig->mPpiChIdClr;
cfg.ppi_ch_id_set = aConfig->mPpiChIdSet;
cfg.radio_ppi_grp = aConfig->mRadioPpiGrp;
cfg.timer_ppi_grp = aConfig->mTimerPpiGrp;
cfg.gpiote_ch_id = aConfig->mGpioteChId;
nrf_drv_radio802154_fem_control_cfg_set(&cfg);
}
+108
View File
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder 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 HOLDER 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.
*/
/**
* @file
* This file includes front end module platform-specific functions.
*
*/
#ifndef PLATFORM_FEM_H_
#define PLATFORM_FEM_H_
#include <stdint.h>
#define PLATFORM_FEM_DEFAULT_PA_PIN 26 /**< Default Power Amplifier pin. */
#define PLATFORM_FEM_DEFAULT_LNA_PIN 27 /**< Default Low Noise Amplifier pin. */
#define PLATFORM_FEM_DEFAULT_SET_PPI_CHANNEL 18 /**< Default PPI channel for pin setting. */
#define PLATFORM_FEM_DEFAULT_CLR_PPI_CHANNEL 19 /**< Default PPI channel for pin clearing. */
#define PLATFORM_FEM_DEFAULT_TIMER_MATCH_PPI_GROUP 4 /**< Default PPI channel group used to disable timer match PPI. */
#define PLATFORM_FEM_DEFAULT_RADIO_DISABLED_PPI_GROUP 5 /**< Default PPI channel group used to disable radio disabled PPI. */
#define PLATFORM_FEM_DEFAULT_GPIOTE_CHANNEL 7 /**< Default GPIOTE channel for FEM control. */
#define PLATFORM_FEM_DEFAULT_CONFIG \
((PlatformFemConfigParams) { \
.mPaCfg = { \
.mEnable = 1, \
.mActiveHigh = 1, \
.mGpioPin = PLATFORM_FEM_DEFAULT_PA_PIN, \
}, \
.mLnaCfg = { \
.mEnable = 1, \
.mActiveHigh = 1, \
.mGpioPin = PLATFORM_FEM_DEFAULT_LNA_PIN, \
}, \
.mPpiChIdClr = PLATFORM_FEM_DEFAULT_CLR_PPI_CHANNEL, \
.mPpiChIdSet = PLATFORM_FEM_DEFAULT_SET_PPI_CHANNEL, \
.mTimerPpiGrp = PLATFORM_FEM_DEFAULT_TIMER_MATCH_PPI_GROUP, \
.mRadioPpiGrp = PLATFORM_FEM_DEFAULT_RADIO_DISABLED_PPI_GROUP, \
.mGpioteChId = PLATFORM_FEM_DEFAULT_GPIOTE_CHANNEL, \
})
/**
* @brief Configuration parameters for the PA and LNA.
*/
typedef struct
{
uint8_t mEnable : 1; /**< Enable toggling for this amplifier */
uint8_t mActiveHigh : 1; /**< Set the pin to be active high */
uint8_t mGpioPin : 6; /**< The GPIO pin to toggle for this amplifier */
} PlatformFemConfigPaLna;
/**
* @brief PA & LNA GPIO toggle configuration
*
* This option configures the nRF 802.15.4 radio driver to toggle pins when the radio
* is active for use with a power amplifier and/or a low noise amplifier.
*
* Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
* by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
*
* @note Changing this configuration while the radio is in use may have undefined
* consequences and must be avoided by the application.
*/
typedef struct
{
PlatformFemConfigPaLna mPaCfg; /**< Power Amplifier configuration */
PlatformFemConfigPaLna mLnaCfg; /**< Low Noise Amplifier configuration */
uint8_t mPpiChIdSet; /**< PPI channel used for radio pin setting */
uint8_t mPpiChIdClr; /**< PPI channel used for radio pin clearing */
uint8_t mTimerPpiGrp; /**< PPI group used for disabling timer match PPI. */
uint8_t mRadioPpiGrp; /**< PPI group used for disabling radio disabled PPI. */
uint8_t mGpioteChId; /**< GPIOTE channel used for radio pin toggling */
} PlatformFemConfigParams;
/**
* Function used to set parameters of FEM.
*
*/
void PlatformFemSetConfigParams(const PlatformFemConfigParams *aConfig);
#endif // PLATFORM_FEM_H_
@@ -0,0 +1,182 @@
/* Copyright (c) 2017, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @brief Front End Module control for the nRF 802.15.4 radio driver.
*
*/
#ifndef NRF_FEM_CONTROL_API_H_
#define NRF_FEM_CONTROL_API_H_
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @section Resource configuration.
*/
/** Default Power Amplifier pin. */
#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 26
/** Default Low Noise Amplifier pin. */
#define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 27
/** Default PPI channel for pin setting. */
#define NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL 18
/** Default PPI channel for pin clearing. */
#define NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL 19
/** Default PPI channel group used to disable timer match PPI. */
#define NRF_FEM_CONTROL_DEFAULT_TIMER_MATCH_PPI_GROUP 4
/** Default PPI channel group used to disable radio disabled PPI. */
#define NRF_FEM_CONTROL_DEFAULT_RADIO_DISABLED_PPI_GROUP 5
/** Default GPIOTE channel for FEM control. */
#define NRF_FEM_CONTROL_DEFAULT_GPIOTE_CHANNEL 7
#if ENABLE_FEM
/**
* @brief Configuration parameters for the PA and LNA.
*/
typedef struct
{
uint8_t enable :1; /**< Enable toggling for this amplifier */
uint8_t active_high :1; /**< Set the pin to be active high */
uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */
} nrf_fem_control_pa_lna_cfg_t;
/**
* @brief PA & LNA GPIO toggle configuration
*
* This option configures the nRF 802.15.4 radio driver to toggle pins when the radio
* is active for use with a power amplifier and/or a low noise amplifier.
*
* Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
* by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
*
* @note Changing this configuration while the radio is in use may have undefined
* consequences and must be avoided by the application.
*/
typedef struct
{
nrf_fem_control_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */
nrf_fem_control_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */
uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */
uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */
uint8_t timer_ppi_grp; /**< PPI group used for disabling timer match PPI. */
uint8_t radio_ppi_grp; /**< PPI group used for disabling radio disabled PPI. */
uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */
} nrf_fem_control_cfg_t;
/**@brief Set PA & LNA GPIO toggle configuration.
*
* @note This function shall not be called when radio is in use.
*
* @param[in] p_cfg A pointer to the PA & LNA GPIO toggle configuration.
*
*/
void nrf_fem_control_cfg_set(const nrf_fem_control_cfg_t * p_cfg);
/**@brief Get PA & LNA GPIO toggle configuration.
*
* @param[out] p_cfg A pointer to the structure for the PA & LNA GPIO toggle configuration.
*
*/
void nrf_fem_control_cfg_get(nrf_fem_control_cfg_t * p_cfg);
/**@brief Activate FEM controller.
*
* This function should be called when radio wakes up.
*/
void nrf_fem_control_activate(void);
/**@brief De-activate FEM controller.
*
* This function should be called when radio goes to sleep.
*/
void nrf_fem_control_deactivate(void);
/**@brief Latch current time in FEM controller.
*
* This function stores current time to enable precise time measurement and mitigate impact of code
* execution time. It should be called before triggering RXEN or TXEN task, and calling
* @ref nrf_fem_control_pa_set or @ref nrf_fem_control_lna_set funcitons.
*/
void nrf_fem_control_time_latch(void);
/**@brief Activate Power Amplifier (TX) pin of the Front End Module.
*
* @param[in] shorts_used Information if this operation is related to a task triggered by a short.
*
* This function will set up a timer to activate the pin 5 +/- 2.5 us before radio READY event is generated.
* It will also set up a PPI to deactivate the pin on radio DISABLED event.
*
* @note This function shall always be called after @ref nrf_fem_control_time_latch function was called,
* to enable precise time measurement.
* */
void nrf_fem_control_pa_set(bool shorts_used);
/**@brief Activate Low Noise Amplifier (RX) pin of the Front End Module.
*
* @param[in] shorts_used Information if this operation is related to a task triggered by a short.
*
* This function will set up a timer to activate the pin 5 +/- 2.5 us before radio READY event is generated.
* It will also set up a PPI to deactivate the pin on radio DISABLED event.
*
* @note This function shall always be called after @ref nrf_fem_control_time_latch function was called,
* to enable precise time measurement.
* */
void nrf_fem_control_lna_set(bool shorts_used);
#else // ENABLE_FEM
#define nrf_fem_control_cfg_set(...)
#define nrf_fem_control_cfg_get(...)
#define nrf_fem_control_activate(...)
#define nrf_fem_control_deactivate(...)
#define nrf_fem_control_time_latch(...)
#define nrf_fem_control_pa_set(...)
#define nrf_fem_control_lna_set(...)
#endif // ENABLE_FEM
#ifdef __cplusplus
}
#endif
#endif /* NRF_FEM_CONTROL_API_H_ */
@@ -0,0 +1,220 @@
/* Copyright (c) 2017, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER 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.
*
*/
/**
* @file
* This file implements common function for Front End Module control of the nRF 802.15.4 radio driver.
*
*/
#include "nrf_fem_control_api.h"
#include "compiler_abstraction.h"
#include "nrf_fem_control_config.h"
#include "nrf_fem_control_internal.h"
#include "nrf.h"
#include "hal/nrf_gpio.h"
#include "hal/nrf_gpiote.h"
#include "hal/nrf_ppi.h"
#include "hal/nrf_radio.h"
static nrf_fem_control_cfg_t m_nrf_fem_control_cfg; /**< FEM controller configuration. */
static volatile uint32_t m_time_latch; /**< Recently latched timer value. */
/**
* @section GPIO control.
*/
/** Initialize GPIO according to configuration provided. */
static void gpio_init(void)
{
if (m_nrf_fem_control_cfg.pa_cfg.enable)
{
nrf_gpio_cfg_output(m_nrf_fem_control_cfg.pa_cfg.gpio_pin);
nrf_gpio_pin_write(m_nrf_fem_control_cfg.pa_cfg.gpio_pin,
!m_nrf_fem_control_cfg.pa_cfg.active_high);
}
if (m_nrf_fem_control_cfg.lna_cfg.enable)
{
nrf_gpio_cfg_output(m_nrf_fem_control_cfg.lna_cfg.gpio_pin);
nrf_gpio_pin_write(m_nrf_fem_control_cfg.lna_cfg.gpio_pin,
!m_nrf_fem_control_cfg.lna_cfg.active_high);
}
}
/** Configure GPIOTE task. */
__STATIC_INLINE void gpiote_configure(uint8_t pin, nrf_gpiote_outinit_t init_val)
{
nrf_gpiote_task_configure(m_nrf_fem_control_cfg.gpiote_ch_id,
pin,
NRF_GPIOTE_POLARITY_TOGGLE,
init_val);
nrf_gpiote_task_enable(m_nrf_fem_control_cfg.gpiote_ch_id);
}
/**
* @section PPI control.
*/
/** Initialize PPI according to configuration provided. */
static void ppi_init(void)
{
nrf_ppi_channel_include_in_group(m_nrf_fem_control_cfg.ppi_ch_id_set,
m_nrf_fem_control_cfg.timer_ppi_grp);
nrf_ppi_channel_include_in_group(m_nrf_fem_control_cfg.ppi_ch_id_clr,
m_nrf_fem_control_cfg.radio_ppi_grp);
nrf_ppi_channel_and_fork_endpoint_setup(
m_nrf_fem_control_cfg.ppi_ch_id_set,
(uint32_t)(&NRF_TIMER0->EVENTS_COMPARE[TIMER_CC_FEM]),
(uint32_t)(&NRF_GPIOTE->TASKS_OUT[m_nrf_fem_control_cfg.gpiote_ch_id]),
(uint32_t)(&NRF_PPI->TASKS_CHG[m_nrf_fem_control_cfg.timer_ppi_grp].DIS));
// Workaround for FTPAN-114, disable PPI to prevent second radio DISABLED event trigger.
nrf_ppi_channel_and_fork_endpoint_setup(
m_nrf_fem_control_cfg.ppi_ch_id_clr,
(uint32_t)(&NRF_RADIO->EVENTS_DISABLED),
(uint32_t)(&NRF_GPIOTE->TASKS_OUT[m_nrf_fem_control_cfg.gpiote_ch_id]),
(uint32_t)(&NRF_PPI->TASKS_CHG[m_nrf_fem_control_cfg.radio_ppi_grp].DIS));
}
/** Enable PPI. */
__STATIC_INLINE void ppi_enable(void)
{
NRF_PPI->CHENSET = (1 << m_nrf_fem_control_cfg.ppi_ch_id_set) |
(1 << m_nrf_fem_control_cfg.ppi_ch_id_clr);
}
/** Disable PPI. */
__STATIC_INLINE void ppi_disable(void)
{
NRF_PPI->CHENCLR = (1 << m_nrf_fem_control_cfg.ppi_ch_id_set) |
(1 << m_nrf_fem_control_cfg.ppi_ch_id_clr);
}
/**
* @section FEM API functions.
*/
void nrf_fem_control_cfg_set(const nrf_fem_control_cfg_t * p_cfg)
{
m_nrf_fem_control_cfg = *p_cfg;
if (m_nrf_fem_control_cfg.pa_cfg.enable || m_nrf_fem_control_cfg.lna_cfg.enable)
{
gpio_init();
ppi_init();
nrf_fem_control_timer_init();
}
else
{
nrf_fem_control_timer_deinit();
}
}
void nrf_fem_control_cfg_get(nrf_fem_control_cfg_t * p_cfg)
{
*p_cfg = m_nrf_fem_control_cfg;
}
void nrf_fem_control_activate(void)
{
if (m_nrf_fem_control_cfg.pa_cfg.enable || m_nrf_fem_control_cfg.lna_cfg.enable)
{
nrf_fem_control_timer_start();
}
}
void nrf_fem_control_deactivate(void)
{
if (m_nrf_fem_control_cfg.pa_cfg.enable || m_nrf_fem_control_cfg.lna_cfg.enable)
{
nrf_fem_control_timer_stop();
nrf_gpiote_task_disable(m_nrf_fem_control_cfg.gpiote_ch_id);
ppi_disable();
}
}
void nrf_fem_control_time_latch(void)
{
if (m_nrf_fem_control_cfg.pa_cfg.enable || m_nrf_fem_control_cfg.lna_cfg.enable)
{
m_time_latch = nrf_fem_control_timer_time_get();
}
}
void nrf_fem_control_pa_set(bool shorts_used)
{
uint32_t target_time;
if (m_nrf_fem_control_cfg.pa_cfg.enable)
{
gpiote_configure(m_nrf_fem_control_cfg.pa_cfg.gpio_pin,
!m_nrf_fem_control_cfg.pa_cfg.active_high);
ppi_enable();
uint32_t tifs = nrf_radio_ifs_get();
target_time = tifs <= NRF_FEM_RADIO_TX_STARTUP_LATENCY_US ?
m_time_latch + NRF_FEM_RADIO_TX_STARTUP_LATENCY_US - NRF_FEM_PA_TIME_IN_ADVANCE :
m_time_latch + tifs - NRF_FEM_RADIO_TIFS_DRIFT_US - NRF_FEM_PA_TIME_IN_ADVANCE;
if (shorts_used)
{
target_time -= nrf_fem_control_irq_delay_get();
}
nrf_fem_control_timer_set(target_time);
}
}
void nrf_fem_control_lna_set(bool shorts_used)
{
uint32_t target_time;
if (m_nrf_fem_control_cfg.lna_cfg.enable)
{
gpiote_configure(m_nrf_fem_control_cfg.lna_cfg.gpio_pin,
!m_nrf_fem_control_cfg.lna_cfg.active_high);
ppi_enable();
target_time = m_time_latch + NRF_FEM_RADIO_RX_STARTUP_LATENCY_US -
NRF_FEM_LNA_TIME_IN_ADVANCE;
if (shorts_used)
{
target_time -= nrf_fem_control_irq_delay_get();
}
nrf_fem_control_timer_set(target_time);
}
}
@@ -0,0 +1,69 @@
/* Copyright (c) 2017, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER 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 NRF_FEM_CONTROL_CONFIG_H_
#define NRF_FEM_CONTROL_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @section Timings.
*/
/** Time in us when PA GPIO is activated before radio is ready for transmission. */
#define NRF_FEM_PA_TIME_IN_ADVANCE 5
/** Time in us when LNA GPIO is activated before radio is ready for reception. */
#define NRF_FEM_LNA_TIME_IN_ADVANCE 5
#ifdef NRF52840_XXAA
/** Radio ramp-up time in TX mode, in us. */
#define NRF_FEM_RADIO_TX_STARTUP_LATENCY_US 129
/** Radio ramp-up time in RX mode, in us. */
#define NRF_FEM_RADIO_RX_STARTUP_LATENCY_US 129
/** Tifs drift measured, in us. */
#define NRF_FEM_RADIO_TIFS_DRIFT_US 20
#else
#error "Device not supported."
#endif
#ifdef __cplusplus
}
#endif
#endif /* NRF_FEM_CONTROL_CONFIG_H_ */
@@ -0,0 +1,91 @@
/* Copyright (c) 2017, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER 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.
*
*/
/**
* @file
* This file implements internal functions of Front End Module control for standalone version of
* the nRF 802.15.4 radio driver.
*
*/
#include "nrf_fem_control_internal.h"
#include "hal/nrf_timer.h"
static bool m_timer_started = false; /**< Information if timer is running. */
void nrf_fem_control_timer_start(void)
{
if (!m_timer_started)
{
nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_START);
m_timer_started = true;
}
}
void nrf_fem_control_timer_stop(void)
{
nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP);
m_timer_started = false;
}
void nrf_fem_control_timer_set(uint32_t target)
{
nrf_timer_cc_write(NRF_TIMER0, TIMER_CC_FEM, target);
}
uint32_t nrf_fem_control_timer_time_get(void)
{
NRF_TIMER0->TASKS_CAPTURE[TIMER_CC_CAPTURE] = 1;
return NRF_TIMER0->CC[TIMER_CC_CAPTURE];
}
void nrf_fem_control_timer_init(void)
{
nrf_fem_control_timer_stop();
nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR);
nrf_timer_mode_set(NRF_TIMER0, NRF_TIMER_MODE_TIMER);
nrf_timer_bit_width_set(NRF_TIMER0, NRF_TIMER_BIT_WIDTH_32);
nrf_timer_frequency_set(NRF_TIMER0, NRF_TIMER_FREQ_1MHz);
}
void nrf_fem_control_timer_deinit(void)
{
nrf_fem_control_timer_stop();
nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR);
}
uint32_t nrf_fem_control_irq_delay_get(void)
{
return 0;
}
@@ -0,0 +1,82 @@
/* Copyright (c) 2017, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @brief Front End Module control internal functions.
*
*/
#ifndef NRF_FEM_CONTROL_INTERNAL_H_
#define NRF_FEM_CONTROL_INTERNAL_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "nrf_fem_control_api.h"
#define TIMER_CC_FEM 3 /**< Compare channel used by the module. */
#define TIMER_CC_CAPTURE 2 /**< Compare channel used for time capture. */
/**@brief Start timer used by the module. */
void nrf_fem_control_timer_start(void);
/**@brief Stop timer used by the module. */
void nrf_fem_control_timer_stop(void);
/**@brief Set timer CC target value.
*
* @param[in] target Traget time.
*/
void nrf_fem_control_timer_set(uint32_t target);
/**@brief Get current time from the timer.
*
* @retval Current timer time.
*/
uint32_t nrf_fem_control_timer_time_get(void);
/**@brief Initialize timer. */
void nrf_fem_control_timer_init(void);
/**@brief De-initialize timer. */
void nrf_fem_control_timer_deinit(void);
/**@brief Get configuration specific irq entry delay.
*
* @retval Delay value.
*/
uint32_t nrf_fem_control_irq_delay_get(void);
#ifdef __cplusplus
}
#endif
#endif /* NRF_FEM_CONTROL_INTERNAL_H_ */
@@ -0,0 +1,78 @@
/* Copyright (c) 2017, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER 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.
*
*/
/**
* @file
* This file implements internal functions of Front End Module control for
* nRF 802.15.4 radio driver working with SoftDevice RAAL.
*
*/
#include "nrf_fem_control_internal.h"
#include "hal/nrf_timer.h"
#define SOFTDEVICE_IRQ_ENTRY_DELAY 4UL /**< An IRQ entry delay when using SoftDevice. */
void nrf_fem_control_timer_start(void)
{
// Intentionally empty. In this configuration timer is controlled by RAAL.
}
void nrf_fem_control_timer_stop(void)
{
// Intentionally empty. In this configuration timer is controlled by RAAL.
}
void nrf_fem_control_timer_set(uint32_t target)
{
nrf_timer_cc_write(NRF_TIMER0, TIMER_CC_FEM, target);
}
uint32_t nrf_fem_control_timer_time_get(void)
{
NRF_TIMER0->TASKS_CAPTURE[TIMER_CC_CAPTURE] = 1;
return NRF_TIMER0->CC[TIMER_CC_CAPTURE];
}
void nrf_fem_control_timer_init(void)
{
// Intentionally empty. In this configuration timer is controlled by RAAL.
}
void nrf_fem_control_timer_deinit(void)
{
// Intentionally empty. In this configuration timer is controlled by RAAL.
}
uint32_t nrf_fem_control_irq_delay_get(void)
{
return SOFTDEVICE_IRQ_ENTRY_DELAY;
}
@@ -57,6 +57,10 @@
#include <cmsis/core_cmFunc.h>
#if ENABLE_FEM
#include "fem/nrf_fem_control_api.h"
#endif
#define RAW_LENGTH_OFFSET 0
#define RAW_PAYLOAD_OFFSET 1
@@ -134,6 +138,18 @@ void nrf_drv_radio802154_irq_handler(void)
}
#endif // !RADIO_INTERNAL_IRQ_HANDLING
#if ENABLE_FEM
void nrf_drv_radio802154_fem_control_cfg_set(const nrf_drv_radio802154_fem_control_cfg_t * p_cfg)
{
nrf_fem_control_cfg_set(p_cfg);
}
void nrf_drv_radio802154_fem_control_cfg_get(nrf_drv_radio802154_fem_control_cfg_t * p_cfg)
{
nrf_fem_control_cfg_get(p_cfg);
}
#endif
nrf_drv_radio802154_state_t nrf_drv_radio802154_state_get(void)
{
switch (nrf_drv_radio802154_fsm_state_get())
@@ -299,6 +315,41 @@ int8_t nrf_drv_radio802154_rssi_last_get(void)
return - (int8_t)minus_dbm;
}
int8_t nrf_drv_radio802154_rssi_corrected_get(int8_t rssi, int8_t temp)
{
if (temp <= -30)
{
return rssi + 3;
}
if (temp <= -10)
{
return rssi + 2;
}
if (temp <= 10)
{
return rssi + 1;
}
if (temp <= 30)
{
return rssi;
}
if (temp <= 50)
{
return rssi - 1;
}
if (temp <= 70)
{
return rssi - 2;
}
return rssi - 3;
}
bool nrf_drv_radio802154_promiscuous_get(void)
{
return nrf_drv_radio802154_pib_promiscuous_get();
@@ -42,6 +42,10 @@
#include "nrf_drv_radio802154_config.h"
#include "hal/nrf_radio.h"
#if ENABLE_FEM
#include "fem/nrf_fem_control_api.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -132,6 +136,54 @@ void nrf_drv_radio802154_tx_power_set(int8_t power);
*/
int8_t nrf_drv_radio802154_tx_power_get(void);
/**
* @section Front-end module management.
*/
#if ENABLE_FEM
typedef nrf_fem_control_cfg_t nrf_drv_radio802154_fem_control_cfg_t;
#define NRF_DRV_RADIO802154_FEM_DEFAULT_SETTINGS \
((nrf_drv_radio802154_fem_control_cfg_t) { \
.pa_cfg = { \
.enable = 1, \
.active_high = 1, \
.gpio_pin = NRF_FEM_CONTROL_DEFAULT_PA_PIN, \
}, \
.lna_cfg = { \
.enable = 1, \
.active_high = 1, \
.gpio_pin = NRF_FEM_CONTROL_DEFAULT_LNA_PIN, \
}, \
.ppi_ch_id_clr = NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL, \
.ppi_ch_id_set = NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL, \
.radio_ppi_grp = NRF_FEM_CONTROL_DEFAULT_TIMER_MATCH_PPI_GROUP, \
.timer_ppi_grp = NRF_FEM_CONTROL_DEFAULT_RADIO_DISABLED_PPI_GROUP, \
.gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_GPIOTE_CHANNEL, \
})
/**
* @brief Set PA & LNA GPIO toggle configuration.
*
* @note This function shall not be called when radio is in use.
*
* @param[in] p_cfg A pointer to the PA & LNA GPIO toggle configuration.
*
*/
void nrf_drv_radio802154_fem_control_cfg_set(const nrf_drv_radio802154_fem_control_cfg_t * p_cfg);
/**
* @brief Get PA & LNA GPIO toggle configuration.
*
* @param[out] p_cfg A pointer to the structure for the PA & LNA GPIO toggle configuration.
*
*/
void nrf_drv_radio802154_fem_control_cfg_get(nrf_drv_radio802154_fem_control_cfg_t * p_cfg);
#endif // ENABLE_FEM
/**
* @section Setting addresses and Pan Id of this device.
*/
@@ -526,6 +578,16 @@ void nrf_drv_radio802154_rssi_measure(void);
*/
int8_t nrf_drv_radio802154_rssi_last_get(void);
/**
* @brief Adjust given RSSI measurement using a temperature correction factor.
*
* @param[in] rssi Measured RSSI value [dBm].
* @param[in] temp Temperature value when RSSI sample took place [C].
*
* @returns RSSI [dBm] corrected by a temperature factor (Errata 153).
*/
int8_t nrf_drv_radio802154_rssi_corrected_get(int8_t rssi, int8_t temp);
/**
* @section Promiscuous mode.
@@ -142,7 +142,7 @@ extern "C" {
* Priority of software interrupt used to call notification from 802.15.4 driver.
*
*/
#define RADIO_NOTIFICATION_SWI_PRIORITY 6
#define RADIO_NOTIFICATION_SWI_PRIORITY 5
/**
*@}
@@ -51,6 +51,7 @@
#include "nrf_drv_radio802154_priority_drop.h"
#include "nrf_drv_radio802154_procedures_duration.h"
#include "nrf_drv_radio802154_rx_buffer.h"
#include "fem/nrf_fem_control_api.h"
#include "hal/nrf_radio.h"
#include "raal/nrf_raal_api.h"
@@ -190,6 +191,15 @@ static inline void state_set(radio_state_t state)
{
m_state = state;
if (m_state == RADIO_STATE_SLEEP)
{
nrf_fem_control_deactivate();
}
else
{
nrf_fem_control_activate();
}
nrf_drv_radio802154_log(EVENT_SET_STATE, (uint32_t)state);
}
@@ -260,6 +270,22 @@ static void cca_configuration_update(void)
nrf_radio_cca_corr_counter_set(cca_cfg.corr_limit);
}
/** Trigger RX task. */
static void rx_enable(void)
{
nrf_fem_control_time_latch();
nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
nrf_fem_control_lna_set(false);
}
/** Trigger TX task. */
static void tx_enable(void)
{
nrf_fem_control_time_latch();
nrf_radio_task_trigger(NRF_RADIO_TASK_TXEN);
nrf_fem_control_pa_set(false);
}
/***************************************************************************************************
* @section Radio parameters calculators
**************************************************************************************************/
@@ -600,6 +626,7 @@ void nrf_raal_timeslot_ended(void)
irq_deinit();
nrf_radio_reset();
nrf_fem_control_deactivate();
switch (m_state)
{
@@ -1029,7 +1056,7 @@ static inline void irq_disabled_state_waiting_rx_frame(void)
assert(nrf_radio_state_get() == NRF_RADIO_STATE_DISABLED);
nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
rx_enable();
mutex_unlock();
rx_buffer_in_use_set(nrf_drv_radio802154_rx_buffer_free_find());
@@ -1074,6 +1101,12 @@ static inline void irq_disabled_state_tx_ack(void)
auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
}
else
{
// nrf_fem_control_time_latch was called at the beginning of the irq handler,
// to capture the time as close to short occurence as possible
nrf_fem_control_pa_set(true);
}
}
/** This event is generated before CCA procedure starts.
@@ -1084,7 +1117,8 @@ static inline void irq_disabled_state_cca_before_tx(void)
{
assert(nrf_radio_shorts_get() == SHORTS_IDLE);
assert(nrf_radio_state_get() == NRF_RADIO_STATE_DISABLED);
nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
rx_enable();
}
/** This event is generated before transmission of a frame starts.
@@ -1096,7 +1130,8 @@ static inline void irq_disabled_state_tx_frame(void)
if (nrf_radio_state_get() == NRF_RADIO_STATE_DISABLED)
{
shorts_tx_frame_set();
nrf_radio_task_trigger(NRF_RADIO_TASK_TXEN);
tx_enable();
}
assert(nrf_radio_shorts_get() == SHORTS_TX_FRAME);
@@ -1110,7 +1145,8 @@ static inline void irq_disabled_state_rx_ack(void)
{
assert(nrf_radio_shorts_get() == SHORTS_IDLE);
assert(nrf_radio_state_get() == NRF_RADIO_STATE_DISABLED);
nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
rx_enable();
if (mp_current_rx_buffer == NULL || (!mp_current_rx_buffer->free))
{
@@ -1127,7 +1163,8 @@ static inline void irq_disabled_state_ed(void)
{
assert(nrf_radio_shorts_get() == SHORTS_IDLE);
assert(nrf_radio_state_get() == NRF_RADIO_STATE_DISABLED);
nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
rx_enable();
}
/** This event is generated before stand-alone CCA procedure.
@@ -1138,7 +1175,8 @@ static inline void irq_disabled_state_cca(void)
{
assert(nrf_radio_shorts_get() == SHORTS_IDLE);
assert(nrf_radio_state_get() == NRF_RADIO_STATE_DISABLED);
nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
rx_enable();
}
/** This event is generated before continuous-carrier procedure is started.
@@ -1150,7 +1188,8 @@ static inline void irq_disabled_state_continuous_carrier(void)
{
assert(nrf_radio_shorts_get() == SHORTS_IDLE);
assert(nrf_radio_state_get() == NRF_RADIO_STATE_DISABLED);
nrf_radio_task_trigger(NRF_RADIO_TASK_TXEN);
tx_enable();
}
/** This event is generated when receiver is ready to start receiving a frame.
@@ -1328,6 +1367,8 @@ static inline void irq_edend(void)
/// Handler of radio interrupts.
static inline void irq_handler(void)
{
nrf_fem_control_time_latch();
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_IRQ_HANDLER);
if (nrf_radio_event_get(NRF_RADIO_EVENT_FRAMESTART))
@@ -1551,6 +1592,10 @@ static inline void irq_handler(void)
case RADIO_STATE_TX_FRAME:
#if !RADIO_SHORT_CCAIDLE_TXEN
irq_ccaidle_state_tx_frame();
#else
// nrf_fem_control_time_latch was called at the beginning of the irq handler,
// to capture the time as close to short occurence as possible
nrf_fem_control_pa_set(true);
#endif
break;
@@ -1558,6 +1603,13 @@ static inline void irq_handler(void)
irq_ccaidle_state_cca();
break;
#if RADIO_SHORT_CCAIDLE_TXEN
case RADIO_STATE_WAITING_RX_FRAME:
case RADIO_STATE_RX_ACK:
// If CCAIDLE->TXEN short is enabled, this event may be handled after event END.
break;
#endif
case RADIO_STATE_WAITING_TIMESLOT:
// Exit as soon as possible when waiting for timeslot.
break;
@@ -1626,6 +1678,11 @@ static inline void tx_procedure_abort(radio_state_t state)
state_set(state);
// Stop CCA and clear result. CCA may be performed regardless disabled receiver.
nrf_radio_task_trigger(NRF_RADIO_TASK_CCASTOP);
nrf_radio_event_clear(NRF_RADIO_EVENT_CCAIDLE);
nrf_radio_event_clear(NRF_RADIO_EVENT_CCABUSY);
switch (nrf_radio_state_get())
{
case NRF_RADIO_STATE_TX_DISABLE:
+9 -29
View File
@@ -1,39 +1,19 @@
/* Copyright (c) 2016, Nordic Semiconductor ASA
* All rights reserved.
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER 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.
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#ifndef NRF_GPIO_H__
#define NRF_GPIO_H__
#include "nrf.h"
#include "nrf_peripherals.h"
#include "nrf_assert.h"
#include <stdbool.h>
#include <stdlib.h>
@@ -452,7 +432,7 @@ __STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number);
*/
__STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin)
{
ASSERT(*p_pin < NUMBER_OF_PINS);
//ASSERT(*p_pin < NUMBER_OF_PINS);
#if (GPIO_COUNT == 1)
// The oldest definition case
return NRF_GPIO;
@@ -732,7 +712,7 @@ __STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, u
{
NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST;
ASSERT(start_port + length <= GPIO_COUNT);
//ASSERT(start_port + length <= GPIO_COUNT);
uint32_t i;
for (i = start_port; i < (start_port + length); i++)
+7 -26
View File
@@ -1,33 +1,14 @@
/* Copyright (c) 2016, Nordic Semiconductor ASA
* All rights reserved.
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER 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.
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#ifndef NRF_GPIOTE_H__
#define NRF_GPIOTE_H__
+7 -25
View File
@@ -1,30 +1,12 @@
/* Copyright (c) 2016, Nordic Semiconductor ASA
* All rights reserved.
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA 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 HOLDER 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.
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
+10
View File
@@ -593,6 +593,16 @@ __STATIC_INLINE void nrf_radio_ifs_set(uint32_t radio_ifs)
NRF_RADIO->TIFS = radio_ifs;
}
/**
* @brief Function for getting Inter Frame Spacing
*
* @return Current Inter Frame Spacing
*/
__STATIC_INLINE uint32_t nrf_radio_ifs_get(void)
{
return NRF_RADIO->TIFS & RADIO_TIFS_TIFS_Msk;
}
/**
* @brief Function for setting Bit counter compare.
*
+589
View File
@@ -0,0 +1,589 @@
/*$$$LICENCE_NORDIC_STANDARD<2014>$$$*/
/**
* @defgroup nrf_timer_hal Timer HAL
* @{
* @ingroup nrf_timer
*
* @brief Hardware access layer for accessing the timer peripheral.
*/
#ifndef NRF_TIMER_H__
#define NRF_TIMER_H__
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf_peripherals.h"
#include "nrf.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Macro for validating the correctness of the BIT_WIDTH setting.
*/
#define TIMER_MAX_SIZE(id) CONCAT_3(TIMER, id, _MAX_SIZE)
#define TIMER_BIT_WIDTH_MAX(id, bit_width) \
(TIMER_MAX_SIZE(id) == 8 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) : \
(TIMER_MAX_SIZE(id) == 16 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
(bit_width == NRF_TIMER_BIT_WIDTH_16) : \
(TIMER_MAX_SIZE(id) == 24 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
(bit_width == NRF_TIMER_BIT_WIDTH_16) || \
(bit_width == NRF_TIMER_BIT_WIDTH_24) : \
(TIMER_MAX_SIZE(id) == 32 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
(bit_width == NRF_TIMER_BIT_WIDTH_16) || \
(bit_width == NRF_TIMER_BIT_WIDTH_24) || \
(bit_width == NRF_TIMER_BIT_WIDTH_32) : \
false))))
#if TIMER_COUNT > 3
#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \
((p_reg == NRF_TIMER0) && (TIMER_BIT_WIDTH_MAX(0, bit_width))) \
|| ((p_reg == NRF_TIMER1) && (TIMER_BIT_WIDTH_MAX(1, bit_width))) \
|| ((p_reg == NRF_TIMER2) && (TIMER_BIT_WIDTH_MAX(2, bit_width))) \
|| ((p_reg == NRF_TIMER3) && (TIMER_BIT_WIDTH_MAX(3, bit_width))) \
|| ((p_reg == NRF_TIMER4) && (TIMER_BIT_WIDTH_MAX(4, bit_width))) )
#else
#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \
((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \
|| ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \
|| ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)) )
#endif
/**
* @brief Macro for getting the number of capture/compare channels available
* in a given timer instance.
*/
#define NRF_TIMER_CC_CHANNEL_COUNT(id) CONCAT_3(TIMER, id, _CC_NUM)
/**
* @brief Timer tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), ///< Task for starting the timer.
NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), ///< Task for stopping the timer.
NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), ///< Task for incrementing the timer (in counter mode).
NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), ///< Task for resetting the timer value.
NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer.
NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), ///< Task for capturing the timer value on channel 0.
NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), ///< Task for capturing the timer value on channel 1.
NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), ///< Task for capturing the timer value on channel 2.
NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), ///< Task for capturing the timer value on channel 3.
#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4.
NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5.
#endif
/*lint -restore*/
} nrf_timer_task_t;
/**
* @brief Timer events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), ///< Event from compare channel 0.
NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), ///< Event from compare channel 1.
NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), ///< Event from compare channel 2.
NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]), ///< Event from compare channel 3.
#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4.
NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5.
#endif
/*lint -restore*/
} nrf_timer_event_t;
/**
* @brief Types of timer shortcuts.
*/
typedef enum
{
NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, ///< Shortcut for stopping the timer based on compare 0.
NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, ///< Shortcut for stopping the timer based on compare 1.
NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, ///< Shortcut for stopping the timer based on compare 2.
NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, ///< Shortcut for stopping the timer based on compare 3.
#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4.
NRF_TIMER_SHORT_COMPARE5_STOP_MASK = TIMER_SHORTS_COMPARE5_STOP_Msk, ///< Shortcut for stopping the timer based on compare 5.
#endif
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 0.
NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 1.
NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 2.
NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 3.
#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4.
NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK = TIMER_SHORTS_COMPARE5_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 5.
#endif
} nrf_timer_short_mask_t;
/**
* @brief Timer modes.
*/
typedef enum
{
NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, ///< Timer mode: timer.
NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter, ///< Timer mode: counter.
#if defined(TIMER_MODE_MODE_LowPowerCounter) || defined(__SDK_DOXYGEN__)
NRF_TIMER_MODE_LOW_POWER_COUNTER = TIMER_MODE_MODE_LowPowerCounter, ///< Timer mode: low-power counter.
#endif
} nrf_timer_mode_t;
/**
* @brief Timer bit width.
*/
typedef enum
{
NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, ///< Timer bit width 8 bit.
NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, ///< Timer bit width 16 bit.
NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, ///< Timer bit width 24 bit.
NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit ///< Timer bit width 32 bit.
} nrf_timer_bit_width_t;
/**
* @brief Timer prescalers.
*/
typedef enum
{
NRF_TIMER_FREQ_16MHz = 0, ///< Timer frequency 16 MHz.
NRF_TIMER_FREQ_8MHz, ///< Timer frequency 8 MHz.
NRF_TIMER_FREQ_4MHz, ///< Timer frequency 4 MHz.
NRF_TIMER_FREQ_2MHz, ///< Timer frequency 2 MHz.
NRF_TIMER_FREQ_1MHz, ///< Timer frequency 1 MHz.
NRF_TIMER_FREQ_500kHz, ///< Timer frequency 500 kHz.
NRF_TIMER_FREQ_250kHz, ///< Timer frequency 250 kHz.
NRF_TIMER_FREQ_125kHz, ///< Timer frequency 125 kHz.
NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz.
NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz.
} nrf_timer_frequency_t;
/**
* @brief Timer capture/compare channels.
*/
typedef enum
{
NRF_TIMER_CC_CHANNEL0 = 0, ///< Timer capture/compare channel 0.
NRF_TIMER_CC_CHANNEL1, ///< Timer capture/compare channel 1.
NRF_TIMER_CC_CHANNEL2, ///< Timer capture/compare channel 2.
NRF_TIMER_CC_CHANNEL3, ///< Timer capture/compare channel 3.
#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4.
NRF_TIMER_CC_CHANNEL5, ///< Timer capture/compare channel 5.
#endif
} nrf_timer_cc_channel_t;
/**
* @brief Timer interrupts.
*/
typedef enum
{
NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, ///< Timer interrupt from compare event on channel 0.
NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, ///< Timer interrupt from compare event on channel 1.
NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, ///< Timer interrupt from compare event on channel 2.
NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk, ///< Timer interrupt from compare event on channel 3.
#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4.
NRF_TIMER_INT_COMPARE5_MASK = TIMER_INTENSET_COMPARE5_Msk, ///< Timer interrupt from compare event on channel 5.
#endif
} nrf_timer_int_mask_t;
/**
* @brief Function for activating a specific timer task.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] task Task to activate.
*/
__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task);
/**
* @brief Function for getting the address of a specific timer task register.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task);
/**
* @brief Function for clearing a specific timer event.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event);
/**
* @brief Function for checking the state of a specific timer event.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] event Event to check.
*
* @retval true If the event is set.
* @retval false If the event is not set.
*/
__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event);
/**
* @brief Function for getting the address of a specific timer event register.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event);
/**
* @brief Function for enabling specified shortcuts.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] timer_shorts_mask Shortcuts to enable.
*/
__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg,
uint32_t timer_shorts_mask);
/**
* @brief Function for disabling specified shortcuts.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] timer_shorts_mask Shortcuts to disable.
*/
__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg,
uint32_t timer_shorts_mask);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] timer_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg,
uint32_t timer_int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] timer_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg,
uint32_t timer_int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] timer_int Interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg,
uint32_t timer_int);
/**
* @brief Function for setting the timer mode.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] mode Timer mode.
*/
__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg,
nrf_timer_mode_t mode);
/**
* @brief Function for retrieving the timer mode.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
*
* @return Timer mode.
*/
__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg);
/**
* @brief Function for setting the timer bit width.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] bit_width Timer bit width.
*/
__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg,
nrf_timer_bit_width_t bit_width);
/**
* @brief Function for retrieving the timer bit width.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
*
* @return Timer bit width.
*/
__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg);
/**
* @brief Function for setting the timer frequency.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] frequency Timer frequency.
*/
__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg,
nrf_timer_frequency_t frequency);
/**
* @brief Function for retrieving the timer frequency.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
*
* @return Timer frequency.
*/
__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg);
/**
* @brief Function for writing the capture/compare register for a specified channel.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] cc_channel Requested capture/compare channel.
* @param[in] cc_value Value to write to the capture/compare register.
*/
__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg,
nrf_timer_cc_channel_t cc_channel,
uint32_t cc_value);
/**
* @brief Function for retrieving the capture/compare value for a specified channel.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] cc_channel Requested capture/compare channel.
*
* @return Value from the requested capture/compare register.
*/
__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg,
nrf_timer_cc_channel_t cc_channel);
/**
* @brief Function for getting a specific timer capture task.
*
* @param[in] channel Capture channel.
*
* @return Capture task.
*/
__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel);
/**
* @brief Function for getting a specific timer compare event.
*
* @param[in] channel Compare channel.
*
* @return Compare event.
*/
__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel);
/**
* @brief Function for getting a specific timer compare interrupt.
*
* @param[in] channel Compare channel.
*
* @return Compare interrupt.
*/
__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel);
/**
* @brief Function for calculating the number of timer ticks for a given time
* (in microseconds) and timer frequency.
*
* @param[in] time_us Time in microseconds.
* @param[in] frequency Timer frequency.
*
* @return Number of timer ticks.
*/
__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us,
nrf_timer_frequency_t frequency);
/**
* @brief Function for calculating the number of timer ticks for a given time
* (in milliseconds) and timer frequency.
*
* @param[in] time_ms Time in milliseconds.
* @param[in] frequency Timer frequency.
*
* @return Number of timer ticks.
*/
__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
nrf_timer_frequency_t frequency);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg,
uint32_t timer_shorts_mask)
{
p_reg->SHORTS |= timer_shorts_mask;
}
__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg,
uint32_t timer_shorts_mask)
{
p_reg->SHORTS &= ~(timer_shorts_mask);
}
__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg,
uint32_t timer_int_mask)
{
p_reg->INTENSET = timer_int_mask;
}
__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg,
uint32_t timer_int_mask)
{
p_reg->INTENCLR = timer_int_mask;
}
__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg,
uint32_t timer_int)
{
return (bool)(p_reg->INTENSET & timer_int);
}
__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg,
nrf_timer_mode_t mode)
{
p_reg->MODE = (p_reg->MODE & ~TIMER_MODE_MODE_Msk) |
((mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk);
}
__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg)
{
return (nrf_timer_mode_t)(p_reg->MODE);
}
__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg,
nrf_timer_bit_width_t bit_width)
{
p_reg->BITMODE = (p_reg->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) |
((bit_width << TIMER_BITMODE_BITMODE_Pos) &
TIMER_BITMODE_BITMODE_Msk);
}
__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg)
{
return (nrf_timer_bit_width_t)(p_reg->BITMODE);
}
__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg,
nrf_timer_frequency_t frequency)
{
p_reg->PRESCALER = (p_reg->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) |
((frequency << TIMER_PRESCALER_PRESCALER_Pos) &
TIMER_PRESCALER_PRESCALER_Msk);
}
__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg)
{
return (nrf_timer_frequency_t)(p_reg->PRESCALER);
}
__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg,
nrf_timer_cc_channel_t cc_channel,
uint32_t cc_value)
{
p_reg->CC[cc_channel] = cc_value;
}
__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg,
nrf_timer_cc_channel_t cc_channel)
{
return (uint32_t)p_reg->CC[cc_channel];
}
__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel)
{
return (nrf_timer_task_t)
((uint32_t)NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t)));
}
__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel)
{
return (nrf_timer_event_t)
((uint32_t)NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t)));
}
__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel)
{
return (nrf_timer_int_mask_t)
((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << channel);
}
__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us,
nrf_timer_frequency_t frequency)
{
// The "frequency" parameter here is actually the prescaler value, and the
// timer runs at the following frequency: f = 16 MHz / 2^prescaler.
uint32_t prescaler = (uint32_t)frequency;
return ((time_us * 16UL) >> prescaler);
}
__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
nrf_timer_frequency_t frequency)
{
// The "frequency" parameter here is actually the prescaler value, and the
// timer runs at the following frequency: f = 16000 kHz / 2^prescaler.
uint32_t prescaler = (uint32_t)frequency;
return ((time_ms * 16000UL) >> prescaler);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#ifdef __cplusplus
}
#endif
#endif // NRF_TIMER_H__
/** @} */