初始版本
This commit is contained in:
559
components/drivers_ext/nrf21540/nrf21540.c
Normal file
559
components/drivers_ext/nrf21540/nrf21540.c
Normal file
@@ -0,0 +1,559 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "nrf21540.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nrf21540_defs.h"
|
||||
#include "nrf21540_macro.h"
|
||||
#include "nrf_radio.h"
|
||||
#include "nrf_ppi.h"
|
||||
#include "nrf_gpiote.h"
|
||||
#include "nrf_timer.h"
|
||||
#include "boards.h"
|
||||
#if NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#include "nrf_egu.h"
|
||||
#endif
|
||||
|
||||
#define NRF21540_BUSY_CHECK(mode) \
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING) \
|
||||
{ \
|
||||
while(is_driver_busy()) \
|
||||
{ \
|
||||
\
|
||||
} \
|
||||
} \
|
||||
else if (is_driver_busy()) \
|
||||
{ \
|
||||
return NRF_ERROR_BUSY; \
|
||||
}
|
||||
|
||||
#define NRF21540_ERROR_CHECK(invalid_state_condition) \
|
||||
if (device_state_get() == NRF21540_STATE_ERROR) \
|
||||
{ \
|
||||
m_nrf21540_data.busy = false; \
|
||||
return NRF_ERROR_INTERNAL; \
|
||||
} \
|
||||
if (invalid_state_condition) \
|
||||
{ \
|
||||
m_nrf21540_data.busy = false; \
|
||||
return NRF_ERROR_INVALID_STATE; \
|
||||
}
|
||||
|
||||
/**@brief nRF21540 chip state.
|
||||
*
|
||||
* @details driver state variable possible values.
|
||||
*/
|
||||
typedef enum {
|
||||
NRF21540_STATE_OFF, ///< Chip inactive, line PDN is low, SPI communication impossible.
|
||||
NRF21540_STATE_READY, ///< SPI is active, but nether transmit nor receive can be performed.
|
||||
NRF21540_STATE_TX, ///< Transmit state - chip can perform transmiting data.
|
||||
NRF21540_STATE_RX, ///< Receive state - chip can receive data.
|
||||
NRF21540_STATE_ERROR, ///< Invalid state - requires reinit.
|
||||
} nrf21540_state_t;
|
||||
|
||||
/**@brief nRF21540 static data. */
|
||||
static struct
|
||||
{
|
||||
volatile nrf21540_state_t cur_state; ///< driver state variable.
|
||||
volatile nrf21540_trx_t cur_direction; ///< currently serviced radio communication direction.
|
||||
volatile bool busy; ///< driver is busy at the moment (during changing state phase).
|
||||
#if NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
volatile uint32_t shorts;
|
||||
#endif
|
||||
} m_nrf21540_data;
|
||||
|
||||
/**@brief Function checks if nRF21540 driver is busy now.
|
||||
*
|
||||
* @details Based on driver busy variable.
|
||||
*
|
||||
* @return true if nRF21540 driver is busy.
|
||||
*/
|
||||
static inline bool is_driver_busy(void)
|
||||
{
|
||||
return m_nrf21540_data.busy;
|
||||
}
|
||||
|
||||
/**@brief Function checks if nRF21540 is powered down.
|
||||
*
|
||||
* @details Based on driver state variable.
|
||||
*
|
||||
* @return true if nRF21540 is in power down state.
|
||||
*/
|
||||
static inline bool is_device_off(void)
|
||||
{
|
||||
return m_nrf21540_data.cur_state == NRF21540_STATE_OFF;
|
||||
}
|
||||
|
||||
/**@brief Function checks if nRF21540 is powered up state.
|
||||
*
|
||||
* @details Based on driver state variable.
|
||||
*
|
||||
* @return true if nRF21540 is in power up state.
|
||||
*/
|
||||
static inline bool is_device_on(void)
|
||||
{
|
||||
return m_nrf21540_data.cur_state != NRF21540_STATE_OFF;
|
||||
}
|
||||
|
||||
/**@brief Function checks if nRF21540 can transmit or receive data.
|
||||
*
|
||||
* @details Based on driver state variable.
|
||||
*
|
||||
* @return true if nRF21540 is in TX or RX mode.
|
||||
*/
|
||||
static inline bool is_device_ready_for_transmission(void)
|
||||
{
|
||||
return (m_nrf21540_data.cur_state == NRF21540_STATE_TX ||
|
||||
m_nrf21540_data.cur_state == NRF21540_STATE_RX);
|
||||
}
|
||||
|
||||
/**@brief Function changes driver state.
|
||||
*
|
||||
* @details Changes driver state variable value.
|
||||
*
|
||||
* @param[in] new_state state that will be store.
|
||||
*/
|
||||
static inline void device_state_set(nrf21540_state_t new_state)
|
||||
{
|
||||
m_nrf21540_data.cur_state = new_state;
|
||||
}
|
||||
|
||||
/**@brief Function returns driver state variable value.
|
||||
*
|
||||
* @details Based on driver state variable.
|
||||
*
|
||||
* @return @ref nrf21540_state_t based state variable value.
|
||||
*/
|
||||
static inline nrf21540_state_t device_state_get(void)
|
||||
{
|
||||
return m_nrf21540_data.cur_state;
|
||||
}
|
||||
|
||||
/**@brief Function returns task related to transmission direction.
|
||||
*
|
||||
* @param[in] dir direction of radio transfer. See @nrf21540_trx_t.
|
||||
*
|
||||
* @return task corresponding to given transmission direction.
|
||||
*/
|
||||
static inline nrf_radio_task_t nrf21540_task_get(nrf21540_trx_t dir)
|
||||
{
|
||||
return dir == NRF21540_TX ? NRF_RADIO_TASK_TXEN : NRF_RADIO_TASK_RXEN;
|
||||
}
|
||||
|
||||
/**@brief Function clears and disbles all PPI connections used by nRF21540 driver.
|
||||
*
|
||||
* @details Changes driver state variable value.
|
||||
*/
|
||||
static void ppi_cleanup(void)
|
||||
{
|
||||
nrf_ppi_channel_disable(NRF21540_PDN_PPI_CHANNEL);
|
||||
nrf_ppi_channel_disable(NRF21540_USER_PPI_CHANNEL);
|
||||
nrf_ppi_channel_disable(NRF21540_TRX_PPI_CHANNEL);
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(NRF21540_PDN_PPI_CHANNEL, 0, 0, 0);
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(NRF21540_USER_PPI_CHANNEL, 0, 0, 0);
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(NRF21540_TRX_PPI_CHANNEL, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**@brief Function clears nRF21540 driver events. */
|
||||
static void events_clear()
|
||||
{
|
||||
nrf_timer_event_clear(NRF21540_TIMER, NRF21540_TIMER_CC_PD_PG_EVENT);
|
||||
nrf_timer_event_clear(NRF21540_TIMER, NRF21540_TIMER_CC_START_TO_PDN_UP_EVENT);
|
||||
NRF21540_RADIO_EVENT_CLEAR(NRF21540_RADIO_EVENT_READY);
|
||||
NRF21540_RADIO_EVENT_CLEAR(NRF21540_RADIO_EVENT_DISABLED);
|
||||
}
|
||||
|
||||
/**@brief Timer interrupt handler.
|
||||
*
|
||||
* @details checking time related events occurences and changing driver state if necessary.
|
||||
*/
|
||||
void NRF21540_TIMER_IRQ_HANDLER(void)
|
||||
{
|
||||
if (nrf_timer_event_check(NRF21540_TIMER, NRF21540_TIMER_CC_PD_PG_EVENT))
|
||||
{
|
||||
nrf_timer_event_clear(NRF21540_TIMER, NRF21540_TIMER_CC_PD_PG_EVENT);
|
||||
if (is_device_off() && nrf_gpio_pin_read(NRF21540_PDN_PIN) == 1)
|
||||
{
|
||||
device_state_set(NRF21540_STATE_READY);
|
||||
}
|
||||
else if (is_device_on() && nrf_gpio_pin_read(NRF21540_PDN_PIN) == 0)
|
||||
{
|
||||
device_state_set(NRF21540_STATE_OFF);
|
||||
ppi_cleanup();
|
||||
m_nrf21540_data.busy = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
device_state_set(NRF21540_STATE_ERROR);
|
||||
ppi_cleanup();
|
||||
m_nrf21540_data.busy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@brief nRF21540 interrupt handler.
|
||||
*
|
||||
* @details checking radio related events occurences and changing driver state if necessary.
|
||||
*/
|
||||
void NRF21540_RADIO_IRQ_HANDLER(void)
|
||||
{
|
||||
if (NRF21540_RADIO_EVENT_CHECK(NRF21540_RADIO_EVENT_READY))
|
||||
{
|
||||
NRF21540_RADIO_EVENT_CLEAR(NRF21540_RADIO_EVENT_READY);
|
||||
nrf_ppi_channel_disable(NRF21540_USER_PPI_CHANNEL);
|
||||
#if NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
if (NRF21540_RADIO_SHORTS_ENABLE_CHECK(RADIO_SHORTS_READY_START_Msk))
|
||||
{
|
||||
nrf_radio_task_trigger(NRF_RADIO_TASK_START);
|
||||
}
|
||||
#endif
|
||||
if (device_state_get() == NRF21540_STATE_READY)
|
||||
{
|
||||
device_state_set(m_nrf21540_data.cur_direction == NRF21540_TX ?
|
||||
NRF21540_STATE_TX : NRF21540_STATE_RX);
|
||||
ppi_cleanup();
|
||||
NRF21540_RADIO_INT_DISABLE(NRF21540_RADIO_READY_Msk);
|
||||
m_nrf21540_data.busy = false;
|
||||
}
|
||||
}
|
||||
if (NRF21540_RADIO_EVENT_CHECK(NRF21540_RADIO_EVENT_DISABLED))
|
||||
{
|
||||
NRF21540_RADIO_EVENT_CLEAR(NRF21540_RADIO_EVENT_DISABLED);
|
||||
nrf_ppi_channel_disable(NRF21540_USER_PPI_CHANNEL);
|
||||
nrf_timer_task_trigger(NRF21540_TIMER, NRF_TIMER_TASK_START);
|
||||
if (is_device_ready_for_transmission())
|
||||
{
|
||||
NRF21540_RADIO_INT_DISABLE(NRF21540_RADIO_DISABLED_Msk);
|
||||
device_state_set(NRF21540_STATE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@brief Function resets nRF21540 driver.
|
||||
*
|
||||
* @details sets driver state variable to NRF21540_STATE_OFF value,
|
||||
* cleans all used PPIs and events.
|
||||
*/
|
||||
static void driver_reset(void)
|
||||
{
|
||||
device_state_set(NRF21540_STATE_OFF);
|
||||
ppi_cleanup();
|
||||
events_clear();
|
||||
NRF21540_RADIO_INT_DISABLE(NRF21540_RADIO_INTERRUPT_MASK);
|
||||
m_nrf21540_data.busy = false;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function sets either TX or RX direction.
|
||||
*
|
||||
* @details Configuration of all necessarily peripherals to transmit or receive data,
|
||||
* dependenly on interface used (SPI, or GPIO). Procedure configures nRF21540 chip and
|
||||
* starts transmitting/receiving. Procedure will be started immediately if
|
||||
* @ref trigger_event is 0. Otherwise event which address is @ref trigger_event value
|
||||
* will start procedure.
|
||||
*
|
||||
* @param[in] dir RX or TX communication that will be performed.
|
||||
* @param[in] trigger_event address of event which will trigger the procedure.
|
||||
* @param[in] mode if NRF21540_EXEC_MODE_BLOCKING the function will wait for tx/rx
|
||||
* possibility.
|
||||
* @return NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_ERROR_BUSY when driver performs another operation at
|
||||
* the moment.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
static ret_code_t trx_set(nrf21540_trx_t dir, uint32_t trigger_event,
|
||||
nrf21540_execution_mode_t mode)
|
||||
{
|
||||
ASSERT(!(mode == NRF21540_EXEC_MODE_BLOCKING && trigger_event != 0));
|
||||
NRF21540_BUSY_CHECK(mode);
|
||||
NRF21540_ERROR_CHECK((dir == NRF21540_TX && device_state_get() == NRF21540_STATE_TX) ||
|
||||
(dir == NRF21540_RX && device_state_get() == NRF21540_STATE_RX));
|
||||
uint32_t ramp_up_time = nrf_radio_modecnf0_ru_get() ? FAST_RAMP_UP_TIME : RAMP_UP_TIME;
|
||||
nrf_radio_task_t radio_task_to_start = nrf21540_task_get(dir);
|
||||
m_nrf21540_data.busy = true;
|
||||
events_clear();
|
||||
NRF21540_RADIO_INT_ENABLE(NRF21540_RADIO_READY_Msk);
|
||||
if (is_device_off())
|
||||
{
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_PDN_PPI_CHANNEL,
|
||||
(uint32_t)nrf_timer_event_address_get(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_START_TO_PDN_UP_EVENT),
|
||||
nrf_gpiote_task_addr_get(NRF21540_PDN_GPIOTE_TASK_SET));
|
||||
nrf_ppi_channel_enable(NRF21540_PDN_PPI_CHANNEL);
|
||||
nrf_timer_cc_write(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_PD_PG_CHANNEL,
|
||||
ramp_up_time - NRF21540_PA_PG_TRX_TIME_US);
|
||||
nrf_timer_cc_write(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL,
|
||||
ramp_up_time - NRF21540_PA_PG_TRX_TIME_US - NRF21540_PD_PG_TIME_US);
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
nrf21540_gpio_trx_enable(dir);
|
||||
#elif NRF21540_USE_SPI_MANAGEMENT
|
||||
nrf21540_spim_for_trx_configure(dir, NRF21540_ENABLE);
|
||||
#endif
|
||||
nrf_timer_shorts_enable(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_STOP_MASK |
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_CLEAR_MASK);
|
||||
NRF21540_RADIO_SHORTS_ENABLE(RADIO_SHORTS_READY_START_Msk);
|
||||
if (trigger_event == 0)
|
||||
{
|
||||
//start immediately.
|
||||
nrf_timer_task_trigger(NRF21540_TIMER, NRF_TIMER_TASK_START);
|
||||
nrf_radio_task_trigger(radio_task_to_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
//start when user event occurs.
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(
|
||||
NRF21540_USER_PPI_CHANNEL,
|
||||
trigger_event,
|
||||
(uint32_t) nrf_timer_task_address_get(NRF21540_TIMER, NRF_TIMER_TASK_START),
|
||||
(uint32_t) nrf_radio_task_address_get(radio_task_to_start));
|
||||
nrf_ppi_channel_enable(NRF21540_USER_PPI_CHANNEL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// at the moment we are not able to switch direction on the fly.
|
||||
// @todo switching between RXEN and TXEN.
|
||||
NRF21540_ERROR_CHECK(device_state_get() == NRF21540_STATE_RX);
|
||||
if (trigger_event == 0)
|
||||
{
|
||||
nrf_radio_task_trigger(radio_task_to_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
// start when user event occurs
|
||||
nrf_ppi_channel_endpoint_setup(
|
||||
NRF21540_USER_PPI_CHANNEL,
|
||||
trigger_event,
|
||||
(uint32_t) nrf_radio_task_address_get(radio_task_to_start));
|
||||
nrf_ppi_channel_enable(NRF21540_USER_PPI_CHANNEL);
|
||||
}
|
||||
}
|
||||
m_nrf21540_data.cur_direction = dir;
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
while (!is_device_ready_for_transmission());
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_init(void)
|
||||
{
|
||||
driver_reset();
|
||||
// GPIOTE for PDN pin configuration
|
||||
nrf_gpiote_task_configure(NRF21540_PDN_GPIOTE_CHANNEL_NO,
|
||||
NRF21540_PDN_PIN,
|
||||
(nrf_gpiote_polarity_t) GPIOTE_CONFIG_POLARITY_None,
|
||||
NRF_GPIOTE_INITIAL_VALUE_LOW);
|
||||
nrf_gpiote_task_enable(NRF21540_PDN_GPIOTE_CHANNEL_NO);
|
||||
nrf21540_gpio_init();
|
||||
NVIC_SetPriority(NRF21540_TIMER_IRQn, NRF21540_INTERRUPT_PRIORITY);
|
||||
NVIC_EnableIRQ(NRF21540_TIMER_IRQn);
|
||||
nrf_timer_int_enable(NRF21540_TIMER, NRF21540_TIM_INTERRUPT_MASK);
|
||||
#if NRF21540_USE_SPI_MANAGEMENT
|
||||
ret_code_t ret = NRF_SUCCESS;
|
||||
ret = nrf21540_spi_init();
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
device_state_set(NRF21540_STATE_ERROR);
|
||||
return ret;
|
||||
}
|
||||
#endif //NRF21540_USE_SPI_MANAGEMENT
|
||||
#if NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL,
|
||||
nrf_radio_event_address_get(NRF_RADIO_EVENT_READY),
|
||||
(uint32_t)nrf_egu_task_address_get(NRF21540_EGU, NRF21540_RADIO_READY_EGU_TASK));
|
||||
nrf_ppi_channel_enable(NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL);
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL,
|
||||
nrf_radio_event_address_get(NRF_RADIO_EVENT_DISABLED),
|
||||
(uint32_t)nrf_egu_task_address_get(NRF21540_EGU, NRF21540_RADIO_DISABLED_EGU_TASK));
|
||||
nrf_ppi_channel_enable(NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL);
|
||||
#endif
|
||||
NVIC_SetPriority(NRF21540_RADIO_IRQn, NRF21540_INTERRUPT_PRIORITY);
|
||||
NVIC_EnableIRQ(NRF21540_RADIO_IRQn);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf21540_pdn_drive(bool state, nrf21540_execution_mode_t mode)
|
||||
{
|
||||
NRF21540_BUSY_CHECK(mode);
|
||||
NRF21540_ERROR_CHECK((state == true && is_device_on()) ||
|
||||
(state == false && is_device_off()));
|
||||
nrf21540_state_t final_state;
|
||||
if (state)
|
||||
{
|
||||
final_state = NRF21540_STATE_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
final_state = NRF21540_STATE_OFF;
|
||||
}
|
||||
nrf_timer_cc_write(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_PD_PG_CHANNEL,
|
||||
state ? NRF21540_PD_PG_TIME_US : 0);
|
||||
nrf_timer_shorts_enable(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_STOP_MASK |
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_CLEAR_MASK);
|
||||
nrf_timer_event_clear(NRF21540_TIMER, NRF21540_TIMER_CC_PD_PG_EVENT);
|
||||
nrf_gpiote_task_force(NRF21540_PDN_GPIOTE_CHANNEL_NO,
|
||||
!state ? NRF_GPIOTE_INITIAL_VALUE_LOW : NRF_GPIOTE_INITIAL_VALUE_HIGH);
|
||||
nrf_timer_task_trigger(NRF21540_TIMER, NRF_TIMER_TASK_START);
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
while (device_state_get() != final_state)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_tx_set(uint32_t user_trigger_event, nrf21540_execution_mode_t mode)
|
||||
{
|
||||
NRF21540_ERROR_CHECK(device_state_get() == NRF21540_STATE_TX);
|
||||
return trx_set(NRF21540_TX, user_trigger_event, mode);
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_rx_set(uint32_t user_trigger_event, nrf21540_execution_mode_t mode)
|
||||
{
|
||||
NRF21540_ERROR_CHECK(device_state_get() == NRF21540_STATE_RX);
|
||||
return trx_set(NRF21540_RX, user_trigger_event, mode);
|
||||
}
|
||||
|
||||
|
||||
bool nrf21540_is_error(void)
|
||||
{
|
||||
return device_state_get() == NRF21540_STATE_ERROR ? true : false;
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_ant_set(nrf21540_antenna_t antenna)
|
||||
{
|
||||
NRF21540_BUSY_CHECK(NRF21540_EXEC_MODE_NON_BLOCKING);
|
||||
return nrf21540_gpio_ant_set(antenna);
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf21540_pwr_mode_set(nrf21540_pwr_mode_t mode)
|
||||
{
|
||||
NRF21540_BUSY_CHECK(NRF21540_EXEC_MODE_NON_BLOCKING);
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
return nrf21540_gpio_pwr_mode_set(mode);
|
||||
#elif NRF21540_USE_SPI_MANAGEMENT
|
||||
return nrf21540_spi_pwr_mode_set(mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_power_down(uint32_t user_trigger_event, nrf21540_execution_mode_t mode)
|
||||
{
|
||||
ASSERT(!(mode == NRF21540_EXEC_MODE_BLOCKING && user_trigger_event != 0));
|
||||
NRF21540_ERROR_CHECK(is_device_off());
|
||||
NRF21540_BUSY_CHECK(mode);
|
||||
m_nrf21540_data.busy = true;
|
||||
events_clear();
|
||||
NRF21540_RADIO_INT_ENABLE(NRF21540_RADIO_DISABLED_Msk);
|
||||
if (device_state_get() == NRF21540_STATE_READY)
|
||||
{
|
||||
// when device is in ready state we jus driving PDN line down and switch off the radio.
|
||||
(void)nrf21540_pdn_drive(false, NRF21540_EXEC_MODE_NON_BLOCKING);
|
||||
nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// When device is in tx/rx state we have to leave it and then drive PDN down.
|
||||
// Line PDN should be driven low after 5us from triggering TXEN/RXEN.
|
||||
uint32_t * trx_drv_task_address;
|
||||
nrf21540_trx_t cur_direction;
|
||||
if (device_state_get() == NRF21540_STATE_TX)
|
||||
{
|
||||
cur_direction = NRF21540_TX;
|
||||
}
|
||||
else if (device_state_get() == NRF21540_STATE_RX)
|
||||
{
|
||||
cur_direction = NRF21540_RX;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INTERNAL;
|
||||
}
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_PDN_PPI_CHANNEL,
|
||||
(uint32_t)nrf_timer_event_address_get(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_TRX_PG_EVENT),
|
||||
nrf_gpiote_task_addr_get(NRF21540_PDN_GPIOTE_TASK_CLR));
|
||||
nrf_ppi_channel_enable(NRF21540_PDN_PPI_CHANNEL);
|
||||
nrf_timer_shorts_enable(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_STOP_MASK |
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_CLEAR_MASK);
|
||||
nrf_timer_cc_write(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_TRX_PG_CHANNEL,
|
||||
NRF21540_TRX_PG_TIME_US);
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
trx_drv_task_address = (uint32_t*) nrf21540_gpio_trx_task_start_address_get(cur_direction,
|
||||
NRF21540_DISABLE);
|
||||
#elif NRF21540_USE_SPI_MANAGEMENT
|
||||
nrf21540_spim_for_trx_configure(cur_direction, NRF21540_DISABLE);
|
||||
trx_drv_task_address = (uint32_t*) nrf21540_spim_trx_task_start_address_get();
|
||||
#endif
|
||||
if (user_trigger_event == 0)
|
||||
{
|
||||
*trx_drv_task_address = 1;
|
||||
nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// start when user event occurs.
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(
|
||||
NRF21540_USER_PPI_CHANNEL,
|
||||
user_trigger_event,
|
||||
(uint32_t)nrf_radio_task_address_get(NRF_RADIO_TASK_DISABLE),
|
||||
(uint32_t) trx_drv_task_address);
|
||||
nrf_ppi_channel_enable(NRF21540_USER_PPI_CHANNEL);
|
||||
}
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
while (is_device_on());
|
||||
}
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
194
components/drivers_ext/nrf21540/nrf21540.h
Normal file
194
components/drivers_ext/nrf21540/nrf21540.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF21540_H_
|
||||
#define NRF21540_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "nrf21540_spi.h"
|
||||
#include "nrf21540_gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @file
|
||||
* @brief nRF21540 front-end Bluetooth range extender.
|
||||
*
|
||||
*
|
||||
* @defgroup nrf21540 nRF21540 front-end Bluetooth range extender.
|
||||
* @{
|
||||
* @ingroup ext_drivers
|
||||
* @brief nRF21540 front-end Bluetooth range extender.
|
||||
*/
|
||||
|
||||
#if NRF21540_USE_SPI_MANAGEMENT
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
#error Only one management manner can be active
|
||||
#endif
|
||||
#elif !NRF21540_USE_GPIO_MANAGEMENT
|
||||
#error At least one management manner must be active
|
||||
#endif // NRF21540_USE_SPI_MANAGEMENT
|
||||
|
||||
/**@brief Initialization of modules needed by nRF21540:
|
||||
* - SPI
|
||||
* - GPIO
|
||||
* - GPIOTE
|
||||
* - PPI
|
||||
* - RADIO
|
||||
* - NVIC
|
||||
*
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_INTERNAL when driver is in error state,
|
||||
* or SPI initialization has failed. Reinitialization is required.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_init(void);
|
||||
|
||||
/**@brief Set nRF21540 to TX mode.
|
||||
*
|
||||
* @note Dependently on configuration GPIO or SPI interface will be used.
|
||||
*
|
||||
* @param[in] user_trigger_event event that triggers start of procedure - this event
|
||||
* will be connected to appropriate PPI channel.
|
||||
* @ref NRF21540_EXECUTE_NOW value causes start procedure
|
||||
* immediately.
|
||||
* @param[in] mode @ref NRF21540_EXEC_MODE_BLOCKING - function will wait for
|
||||
* finishing configuration including settling times required
|
||||
* by nRF21540 (waits till all procedure has finished).
|
||||
* @ref NRF21540_EXEC_MODE_NON_BLOCKING - function will start
|
||||
* procedure and set busy flag. User code can be executed
|
||||
* at this time and busy flag will be unset when done.
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_tx_set(uint32_t user_trigger_event, nrf21540_execution_mode_t mode);
|
||||
|
||||
/**@brief Set nRF21540 to TX mode.
|
||||
*
|
||||
* @note Dependently on configuration GPIO or SPI interface will be used
|
||||
* (NRF21540_USE_SPI_MANAGEMENT/NRF21540_USE_GPIO_MANAGEMENT).
|
||||
*
|
||||
* @param[in] user_trigger_event event that triggers start of procedure - this event
|
||||
* will be connected to appropriate PPI channel.
|
||||
* @ref NRF21540_EXECUTE_NOW value causes start procedure
|
||||
* immediately.
|
||||
* @param[in] mode @ref NRF21540_EXEC_MODE_BLOCKING - function will wait for
|
||||
* finishing configuration including settling times required
|
||||
* by nRF21540 (waits till all procedure has finished).
|
||||
* @ref NRF21540_EXEC_MODE_NON_BLOCKING - function will start
|
||||
* procedure and set busy flag. User code can be executed
|
||||
* at this time and busy flag will be unset when done.
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_rx_set(uint32_t user_trigger_event, nrf21540_execution_mode_t mode);
|
||||
|
||||
/**@brief Function choses one of two physical antenna outputs.
|
||||
*
|
||||
* @param[in] antenna One of antenna outputs. See @ref nrf21540_antenna_t.
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_BUSY when driver performs another operation at
|
||||
* the moment.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_ant_set(nrf21540_antenna_t antenna);
|
||||
|
||||
/**@brief Function choses one of two predefined power modes in nRF21540.
|
||||
*
|
||||
* @details Refer to nRF21540 Objective Product Specification, section: TX power control.
|
||||
*
|
||||
* @param[in] mode Power mode. See @ref nrf21540_pwr_mode_t.
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_BUSY when driver performs another operation at
|
||||
* the moment.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_pwr_mode_set(nrf21540_pwr_mode_t mode);
|
||||
|
||||
/**@brief nRF21540 power down.
|
||||
*
|
||||
* @details Disables chip functionality and enter power save mode.
|
||||
*
|
||||
* @note Dependently on configuration GPIO or SPI interface will be used.
|
||||
*
|
||||
* @param[in] user_trigger_event event that triggers start of procedure - this event
|
||||
* will be connected to appropriate PPI channel.
|
||||
* @ref NRF21540_EXECUTE_NOW value causes start procedure
|
||||
* immediately.
|
||||
* @param[in] mode @ref NRF21540_EXEC_MODE_BLOCKING - function will wait for
|
||||
* finishing configuration including settling times required
|
||||
* by nRF21540 (waits till all procedure has finished).
|
||||
* @ref NRF21540_EXEC_MODE_NON_BLOCKING - function will start
|
||||
* procedure and set busy flag. User code can be executed
|
||||
* at this time and busy flag will be unset when done.
|
||||
* @return NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required then.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_ERROR_BUSY when driver performs another operation at
|
||||
* the moment.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_power_down(uint32_t user_trigger_event, nrf21540_execution_mode_t mode);
|
||||
|
||||
/**@brief Checks if nRF21540 driver is in error state.
|
||||
*
|
||||
* @return true if driver is in error state and should be reinitialized.
|
||||
*/
|
||||
bool nrf21540_is_error(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_H_
|
||||
183
components/drivers_ext/nrf21540/nrf21540_defs.h
Normal file
183
components/drivers_ext/nrf21540/nrf21540_defs.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF21540_DEFS_H_
|
||||
#define NRF21540_DEFS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macros creating instance channels number dependent parameters.
|
||||
*/
|
||||
#define NRF21540_TIMER CONCAT_2(NRF_TIMER, NRF21540_TIMER_NO)
|
||||
#define NRF21540_TIMER_IRQ_HANDLER CONCAT_3(TIMER, NRF21540_TIMER_NO, _IRQHandler)
|
||||
#define NRF21540_TIMER_IRQn CONCAT_3(TIMER, NRF21540_TIMER_NO, _IRQn)
|
||||
#define NRF21540_TIM_INTERRUPT_MASK CONCAT_3(TIMER_INTENSET_COMPARE, \
|
||||
NRF21540_TIMER_CC_PD_PG_CHANNEL_NO, _Msk)
|
||||
|
||||
#if NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL_NO == NRF21540_TIMER_CC_PD_PG_CHANNEL_NO
|
||||
#error These CC channels must be different
|
||||
#endif
|
||||
|
||||
#if (NRF21540_PDN_PPI_CHANNEL_NO == NRF21540_USER_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_PDN_PPI_CHANNEL_NO == NRF21540_TRX_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_TRX_PPI_CHANNEL_NO == NRF21540_USER_PPI_CHANNEL_NO)
|
||||
#error These PPI channels must be different
|
||||
#endif
|
||||
|
||||
#define NRF21540_USER_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_USER_PPI_CHANNEL_NO)
|
||||
#define NRF21540_PDN_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_PDN_PPI_CHANNEL_NO)
|
||||
#define NRF21540_TRX_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_TRX_PPI_CHANNEL_NO)
|
||||
#define NRF21540_USER_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_USER_PPI_CHANNEL_NO)
|
||||
#define NRF21540_PDN_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_PDN_PPI_CHANNEL_NO)
|
||||
#define NRF21540_TRX_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_TRX_PPI_CHANNEL_NO)
|
||||
|
||||
#define NRF21540_TIMER_CC_FINISHED_CHANNEL_STOP_MASK CONCAT_3(NRF_TIMER_SHORT_COMPARE, NRF21540_TIMER_CC_PD_PG_CHANNEL_NO, _STOP_MASK)
|
||||
#define NRF21540_TIMER_CC_FINISHED_CHANNEL_CLEAR_MASK CONCAT_3(NRF_TIMER_SHORT_COMPARE, NRF21540_TIMER_CC_PD_PG_CHANNEL_NO, _CLEAR_MASK)
|
||||
|
||||
#define NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL CONCAT_2(NRF_TIMER_CC_CHANNEL, NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL_NO)
|
||||
#define NRF21540_TIMER_CC_PD_PG_CHANNEL CONCAT_2(NRF_TIMER_CC_CHANNEL, NRF21540_TIMER_CC_PD_PG_CHANNEL_NO)
|
||||
#define NRF21540_TIMER_CC_TRX_PG_CHANNEL NRF21540_TIMER_CC_PD_PG_CHANNEL
|
||||
|
||||
#define NRF21540_TIMER_CC_START_TO_PDN_UP_EVENT CONCAT_2(NRF_TIMER_EVENT_COMPARE, NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL_NO)
|
||||
#define NRF21540_TIMER_CC_PD_PG_EVENT CONCAT_2(NRF_TIMER_EVENT_COMPARE, NRF21540_TIMER_CC_PD_PG_CHANNEL_NO)
|
||||
#define NRF21540_TIMER_CC_TRX_PG_EVENT NRF21540_TIMER_CC_PD_PG_EVENT
|
||||
|
||||
#if (NRF21540_PDN_GPIOTE_CHANNEL_NO == NRF21540_PA_GPIOTE_CHANNEL_NO) || \
|
||||
(NRF21540_PDN_GPIOTE_CHANNEL_NO == NRF21540_LNA_GPIOTE_CHANNEL_NO) || \
|
||||
(NRF21540_LNA_GPIOTE_CHANNEL_NO == NRF21540_PA_GPIOTE_CHANNEL_NO)
|
||||
#error These GPIOTE channels must be different
|
||||
#endif
|
||||
|
||||
#define NRF21540_PDN_GPIOTE_TASK_CLR CONCAT_2(NRF_GPIOTE_TASKS_CLR_, NRF21540_PDN_GPIOTE_CHANNEL_NO)
|
||||
#define NRF21540_LNA_GPIOTE_TASK_CLR CONCAT_2(NRF_GPIOTE_TASKS_CLR_, NRF21540_LNA_GPIOTE_CHANNEL_NO)
|
||||
#define NRF21540_PA_GPIOTE_TASK_CLR CONCAT_2(NRF_GPIOTE_TASKS_CLR_, NRF21540_PA_GPIOTE_CHANNEL_NO)
|
||||
|
||||
#define NRF21540_PDN_GPIOTE_TASK_SET CONCAT_2(NRF_GPIOTE_TASKS_SET_, NRF21540_PDN_GPIOTE_CHANNEL_NO)
|
||||
#define NRF21540_LNA_GPIOTE_TASK_SET CONCAT_2(NRF_GPIOTE_TASKS_SET_, NRF21540_LNA_GPIOTE_CHANNEL_NO)
|
||||
#define NRF21540_PA_GPIOTE_TASK_SET CONCAT_2(NRF_GPIOTE_TASKS_SET_, NRF21540_PA_GPIOTE_CHANNEL_NO)
|
||||
|
||||
#define NRF21540_GPIO_TASK_SET(channel) CONCAT_2(NRF_GPIOTE_TASKS_SET_, channel)
|
||||
#define NRF21540_GPIO_TASK_CLR(channel) CONCAT_2(NRF_GPIOTE_TASKS_CLR_, channel)
|
||||
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_IRQ_HANDLER RADIO_IRQHandler
|
||||
#define NRF21540_RADIO_IRQn RADIO_IRQn
|
||||
#define NRF21540_RADIO_READY_Msk RADIO_INTENSET_READY_Msk
|
||||
#define NRF21540_RADIO_EVENT_READY NRF_RADIO_EVENT_READY
|
||||
#define NRF21540_RADIO_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk
|
||||
#define NRF21540_RADIO_EVENT_DISABLED NRF_RADIO_EVENT_DISABLED
|
||||
#else
|
||||
#if (NRF21540_USER_PPI_CHANNEL_NO == NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_PDN_PPI_CHANNEL_NO == NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_TRX_PPI_CHANNEL_NO == NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_USER_PPI_CHANNEL_NO == NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_PDN_PPI_CHANNEL_NO == NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_TRX_PPI_CHANNEL_NO == NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO == NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO)
|
||||
#error These PPI channels must be different
|
||||
#endif
|
||||
|
||||
#if (NRF21540_RADIO_READY_EGU_CHANNEL_NO == NRF21540_RADIO_DISABLED_EGU_CHANNEL_NO)
|
||||
#error These EGU channels must be different
|
||||
#endif
|
||||
|
||||
#define NRF21540_EGU CONCAT_2(NRF_EGU, NRF21540_EGU_NO)
|
||||
#define SWIx_EGU CONCAT_3(SWI, NRF21540_EGU_NO, _EGU)
|
||||
#define NRF21540_RADIO_IRQ_HANDLER CONCAT_3(SWIx_EGU, NRF21540_EGU_NO, _IRQHandler)
|
||||
#define NRF21540_RADIO_IRQn CONCAT_3(SWIx_EGU, NRF21540_EGU_NO, _IRQn)
|
||||
#define NRF21540_RADIO_READY_Msk (1 << NRF21540_RADIO_READY_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_DISABLED_Msk (1 << NRF21540_RADIO_DISABLED_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_EVENT_READY CONCAT_2(NRF_EGU_EVENT_TRIGGERED, NRF21540_RADIO_READY_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_EVENT_DISABLED CONCAT_2(NRF_EGU_EVENT_TRIGGERED, NRF21540_RADIO_DISABLED_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_READY_EGU_TASK CONCAT_2(NRF_EGU_TASK_TRIGGER, NRF21540_RADIO_READY_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_DISABLED_EGU_TASK CONCAT_2(NRF_EGU_TASK_TRIGGER, NRF21540_RADIO_DISABLED_EGU_CHANNEL_NO)
|
||||
|
||||
#define NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO)
|
||||
#endif //!NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_INTERRUPT_MASK (NRF21540_RADIO_READY_Msk | NRF21540_RADIO_DISABLED_Msk)
|
||||
|
||||
/**@brief Time in microseconds when PA GPIO is activated before the radio is ready for
|
||||
* transmission.
|
||||
*/
|
||||
#define NRF21540_PA_PG_TRX_TIME_US 13
|
||||
|
||||
/**@brief Time in microseconds when LNA GPIO is activated before the radio is ready for
|
||||
* reception.
|
||||
*/
|
||||
#define NRF21540_LNA_PG_TRX_TIME_US 13
|
||||
|
||||
/**@brief The time between activating the PDN and asserting the RX_EN/TX_EN.
|
||||
*/
|
||||
#define NRF21540_PD_PG_TIME_US 18
|
||||
|
||||
/**@brief The time between deasserting the RX_EN/TX_EN and deactivating PDN.
|
||||
*/
|
||||
#define NRF21540_TRX_PG_TIME_US 5
|
||||
|
||||
/**@brief Timing definitions for radio peripheral on nRF uc.
|
||||
*/
|
||||
#define TX_FAST_RAMP_UP_TIME 40 ///< Radio fast ramp up time in us for tx
|
||||
#define RX_FAST_RAMP_UP_TIME 40 ///< Radio fast ramp up time in us for rx
|
||||
#define TX_RAMP_UP_TIME 130 ///< Radio normal ramp up time in us for tx
|
||||
#define RX_RAMP_UP_TIME 130 ///< Radio normal ramp up time in us for rx
|
||||
|
||||
#if (TX_RAMP_UP_TIME == RX_RAMP_UP_TIME && TX_FAST_RAMP_UP_TIME == RX_FAST_RAMP_UP_TIME)
|
||||
#define FAST_RAMP_UP_TIME TX_FAST_RAMP_UP_TIME
|
||||
#define RAMP_UP_TIME TX_RAMP_UP_TIME
|
||||
#else
|
||||
#error ramp up times for rx and tx direction are different. Driver needs rework
|
||||
#endif
|
||||
|
||||
#if (FAST_RAMP_UP_TIME < (NRF21540_PA_PG_TRX_TIME_US + NRF21540_PD_PG_TIME_US))
|
||||
#error fast ramp up time must be greater or equal than (TPD->PG + TPG->TRX)
|
||||
#endif
|
||||
|
||||
#if (FAST_RAMP_UP_TIME > RAMP_UP_TIME)
|
||||
#error fast ramp up time connot be greater than ramp up time
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_DEFS_H_
|
||||
126
components/drivers_ext/nrf21540/nrf21540_gpio.c
Normal file
126
components/drivers_ext/nrf21540/nrf21540_gpio.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "nrf21540_gpio.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "boards.h"
|
||||
#include "nrf21540_defs.h"
|
||||
#include "nrf_gpiote.h"
|
||||
#include "nrf_ppi.h"
|
||||
#include "nrf_timer.h"
|
||||
|
||||
void nrf21540_gpio_init(void)
|
||||
{
|
||||
nrf_gpio_cfg_output(NRF21540_ANTSEL_PIN);
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
nrf_gpio_cfg_output(NRF21540_MODE_PIN);
|
||||
//GPIOTE for TXEN pin configuration
|
||||
nrf_gpiote_task_configure(NRF21540_PA_GPIOTE_CHANNEL_NO,
|
||||
NRF21540_TXEN_PIN,
|
||||
(nrf_gpiote_polarity_t) GPIOTE_CONFIG_POLARITY_None,
|
||||
NRF_GPIOTE_INITIAL_VALUE_LOW);
|
||||
nrf_gpiote_task_enable(NRF21540_PA_GPIOTE_CHANNEL_NO);
|
||||
//GPIOTE for RXEN pin configuration
|
||||
nrf_gpiote_task_configure(NRF21540_LNA_GPIOTE_CHANNEL_NO,
|
||||
NRF21540_RXEN_PIN,
|
||||
(nrf_gpiote_polarity_t) GPIOTE_CONFIG_POLARITY_None,
|
||||
NRF_GPIOTE_INITIAL_VALUE_LOW);
|
||||
nrf_gpiote_task_enable(NRF21540_LNA_GPIOTE_CHANNEL_NO);
|
||||
#endif /*NRF21540_USE_GPIO_MANAGEMENT*/
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_gpio_ant_set(nrf21540_antenna_t antenna)
|
||||
{
|
||||
if (antenna == NRF21540_ANT1)
|
||||
{
|
||||
nrf_gpio_pin_clear(NRF21540_ANTSEL_PIN);
|
||||
}
|
||||
else if (antenna == NRF21540_ANT2)
|
||||
{
|
||||
nrf_gpio_pin_set(NRF21540_ANTSEL_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
|
||||
uint32_t nrf21540_gpio_trx_task_start_address_get(nrf21540_trx_t dir,
|
||||
nrf21540_bool_state_t required_state)
|
||||
{
|
||||
uint8_t gpiote_rx_tx_channel =
|
||||
dir == NRF21540_TX ?
|
||||
NRF21540_PA_GPIOTE_CHANNEL_NO :
|
||||
NRF21540_LNA_GPIOTE_CHANNEL_NO;
|
||||
return required_state == NRF21540_ENABLE ?
|
||||
nrf_gpiote_task_addr_get(nrf_gpiote_set_task_get(gpiote_rx_tx_channel)) :
|
||||
nrf_gpiote_task_addr_get(nrf_gpiote_clr_task_get(gpiote_rx_tx_channel));
|
||||
}
|
||||
|
||||
void nrf21540_gpio_trx_enable(nrf21540_trx_t dir)
|
||||
{
|
||||
uint32_t gpiote_task_start = nrf21540_gpio_trx_task_start_address_get(dir, NRF21540_ENABLE);
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_TRX_PPI_CHANNEL,
|
||||
(uint32_t)nrf_timer_event_address_get(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_PD_PG_EVENT),
|
||||
gpiote_task_start);
|
||||
nrf_ppi_channel_enable(NRF21540_TRX_PPI_CHANNEL);
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_gpio_pwr_mode_set(nrf21540_pwr_mode_t mode)
|
||||
{
|
||||
if (mode == NRF21540_PWR_MODE_A)
|
||||
{
|
||||
nrf_gpio_pin_clear(NRF21540_MODE_PIN);
|
||||
}
|
||||
else if (mode == NRF21540_PWR_MODE_B)
|
||||
{
|
||||
nrf_gpio_pin_set(NRF21540_MODE_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /*NRF21540_USE_GPIO_MANAGEMENT*/
|
||||
97
components/drivers_ext/nrf21540/nrf21540_gpio.h
Normal file
97
components/drivers_ext/nrf21540/nrf21540_gpio.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF21540_GPIO_H_
|
||||
#define NRF21540_GPIO_H_
|
||||
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf21540_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Function initializes GPIO interface.
|
||||
*/
|
||||
void nrf21540_gpio_init(void);
|
||||
|
||||
/**@brief Function choses one of two physical antenna outputs.
|
||||
*
|
||||
* @param[in] antenna one of antenna outputs. See @ref nrf21540_antenna_t.
|
||||
* @return NRF_ERROR_INVALID_PARAM when invalid argument given.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_gpio_ant_set(nrf21540_antenna_t antenna);
|
||||
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
/**@brief Function returns address of task which triggers RX_EN/TX_EN pin
|
||||
* to set nRF21540 radio trasfer direction.
|
||||
*
|
||||
* @param[in] dir Direction of the radio transmission. See @ref nrf21540_trx_t.
|
||||
* @param[in] required_state State of RX/TX transfer. See @ref nrf21540_bool_state_t.
|
||||
* @return Address of appropriate task.
|
||||
*/
|
||||
uint32_t nrf21540_gpio_trx_task_start_address_get(nrf21540_trx_t dir,
|
||||
nrf21540_bool_state_t required_state);
|
||||
|
||||
/**@brief Function configures the chip and peripherals for TX/RX transfer purpose.
|
||||
*
|
||||
* @details enables/disables RX/TX transfers.
|
||||
*
|
||||
* @param[in] dir direction of radio transfer. See @ref nrf21540_trx_t.
|
||||
*/
|
||||
void nrf21540_gpio_trx_enable(nrf21540_trx_t dir);
|
||||
|
||||
/**@brief Function choses one of two predefined power modes in nRF21540.
|
||||
*
|
||||
* @details Refer to nRF21540 Objective Product Specification, section: TX power control.
|
||||
*
|
||||
* @param[in] mode Power mode. See @ref nrf21540_pwr_mode_t.
|
||||
* @return NRF_ERROR_INVALID_PARAM when invalid argument given.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_gpio_pwr_mode_set(nrf21540_pwr_mode_t mode);
|
||||
|
||||
#endif /*NRF21540_USE_GPIO_MANAGEMENT*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_GPIO_H_
|
||||
125
components/drivers_ext/nrf21540/nrf21540_macro.h
Normal file
125
components/drivers_ext/nrf21540/nrf21540_macro.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF21540_MACRO_H_
|
||||
#define NRF21540_MACRO_H_
|
||||
|
||||
#include "nrf21540_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Macro for retrieving the state of the nRF21540 radio event. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_EVENT_CHECK(event) \
|
||||
nrf_radio_event_check(event)
|
||||
#else
|
||||
#define NRF21540_RADIO_EVENT_CHECK(event) \
|
||||
nrf_egu_event_check(NRF21540_EGU, event)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for clearing the nRF21540 radio event. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_EVENT_CLEAR(event) \
|
||||
nrf_radio_event_clear(event)
|
||||
#else
|
||||
#define NRF21540_RADIO_EVENT_CLEAR(event) \
|
||||
nrf_egu_event_clear(NRF21540_EGU, event)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for triggering the nRF21540 radio task. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_TASK_TRIGGER(task) \
|
||||
nrf_radio_task_trigger(event)
|
||||
#else
|
||||
#define NRF21540_RADIO_TASK_TRIGGER(task) \
|
||||
nrf_egu_task_trigger(NRF21540_EGU, event)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for disabling the nRF21540 interrupts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_INT_DISABLE(mask) \
|
||||
nrf_radio_int_disable(mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_INT_DISABLE(mask) \
|
||||
nrf_egu_int_disable(NRF21540_EGU, mask)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for enabling the nRF21540 interrupts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_INT_ENABLE(mask) \
|
||||
nrf_radio_int_enable(mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_INT_ENABLE(mask) \
|
||||
nrf_egu_int_enable(NRF21540_EGU, mask)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for enabling the nRF21540 shorts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_SHORTS_ENABLE(shorts_mask) \
|
||||
nrf_radio_shorts_enable(shorts_mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_SHORTS_ENABLE(shorts_mask) \
|
||||
(m_nrf21540_data.shorts |= shorts_mask)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for disabling the nRF21540 shorts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_SHORTS_DISABLE(shorts_mask) \
|
||||
nrf_radio_shorts_disable(shorts_mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_SHORTS_DISABLE(shorts_mask) \
|
||||
(m_nrf21540_data.shorts &= ~shorts_mask)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for disabling the nRF21540 shorts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_SHORTS_ENABLE_CHECK(shorts_mask) \
|
||||
(nrf_radio_shorts_get() && shorts_mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_SHORTS_ENABLE_CHECK(shorts_mask) \
|
||||
(m_nrf21540_data.shorts && shorts_mask)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_MACRO_H_
|
||||
269
components/drivers_ext/nrf21540/nrf21540_spi.c
Normal file
269
components/drivers_ext/nrf21540/nrf21540_spi.c
Normal file
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "nrf21540_spi.h"
|
||||
#include <string.h>
|
||||
#include "nrf_assert.h"
|
||||
#include "boards.h"
|
||||
#include "nrf_ppi.h"
|
||||
#include "nrf21540_defs.h"
|
||||
#include "nrf_timer.h"
|
||||
|
||||
#if NRF21540_USE_SPI_MANAGEMENT
|
||||
|
||||
static uint8_t m_spi_tx_data[NRF21540_SPI_LENGTH_BYTES]; ///< SPI tx buffer.
|
||||
static uint8_t m_spi_rx_data[NRF21540_SPI_LENGTH_BYTES]; ///< SPI rx buffer.
|
||||
static volatile bool m_spi_xfer_done; ///< Flag indicates that SPI completed the transfer.
|
||||
|
||||
/**@brief Structure keeps content of important registers of nRF21540.
|
||||
*
|
||||
* @details Driver keeps this data because it needs to operate at single bits
|
||||
* included in these registers (otherwise it should read it content
|
||||
* during every operation).
|
||||
*/
|
||||
|
||||
static struct {
|
||||
uint8_t CONFREG0; ///< CONFREG0 register's content.
|
||||
uint8_t CONFREG1; ///< CONFREG1 register's content.
|
||||
} m_confreg_statics;
|
||||
|
||||
static const nrfx_spim_t spi = NRFX_SPIM_INSTANCE(NRF21540_SPIM_NO); /**< SPI instance. */
|
||||
|
||||
/**@brief Function waits for SPI transfer has finished
|
||||
*
|
||||
* @details Used in blocking mode transfer
|
||||
*/
|
||||
static inline void wait_for_transfer_end(void)
|
||||
{
|
||||
while (!m_spi_xfer_done)
|
||||
{}
|
||||
m_spi_xfer_done = false;
|
||||
}
|
||||
|
||||
/**@brief Handler called by nrfx driver when SPI event occurs.
|
||||
*
|
||||
* @param[in] p_event Event which triggers the handler.
|
||||
* @param[in] p_context Context.
|
||||
*/
|
||||
static void spim_event_handler(nrfx_spim_evt_t const *p_event, void *p_context)
|
||||
{
|
||||
m_spi_xfer_done = true;
|
||||
}
|
||||
|
||||
/**@brief Function reads the content of nRF21540 chip register.
|
||||
*
|
||||
* @details Preparation of read register operation. Every register has one byte size.
|
||||
*
|
||||
* @param[in] reg Register address to read.
|
||||
* @param[in] mode if NRF21540_EXEC_MODE_BLOCKING the function will wait for data
|
||||
* received.
|
||||
* @param[in] start_now if enabled, transmision immediately initialized,
|
||||
* otherwise transfer will be triggered by external event.
|
||||
*/
|
||||
static uint8_t spi_reg_read(nrf21540_reg_t reg, nrf21540_execution_mode_t mode, bool start_now)
|
||||
{
|
||||
ASSERT(!(mode == NRF21540_EXEC_MODE_BLOCKING && start_now == false));
|
||||
nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(m_spi_tx_data,
|
||||
NRF21540_SPI_LENGTH_BYTES,
|
||||
m_spi_rx_data,
|
||||
NRF21540_SPI_LENGTH_BYTES);
|
||||
m_spi_tx_data[NRF21540_SPI_COMMAND_ADDR_BYTE] =
|
||||
(NRF21540_SPI_COMMAND_READ << NRF21540_SPI_COMMAND_Pos) | (reg << NRF21540_SPI_REG_Pos);
|
||||
(void)nrfx_spim_xfer(&spi, &xfer_desc, 0);
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
wait_for_transfer_end();
|
||||
}
|
||||
return m_spi_rx_data[NRF21540_SPI_DATA_BYTE];
|
||||
}
|
||||
|
||||
/**@brief Function writes the content of nRF21540 chip register.
|
||||
*
|
||||
* @details Preparation of data to send. Every register has one byte size.
|
||||
*
|
||||
* @param[in] reg Register address to write.
|
||||
* @param[in] data Data to write.
|
||||
* @param[in] mode if NRF21540_EXEC_MODE_BLOCKING the function will wait for transfer
|
||||
* finished after sending data.
|
||||
* @param[in] start_now if enabled, transmision immediately initialized,
|
||||
* otherwise transfer will be triggered by external event.
|
||||
*/
|
||||
static void spi_reg_write(nrf21540_reg_t reg, uint8_t data, nrf21540_execution_mode_t mode, bool start_now)
|
||||
{
|
||||
ASSERT(!(mode == NRF21540_EXEC_MODE_BLOCKING && start_now == false));
|
||||
nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(m_spi_tx_data,
|
||||
NRF21540_SPI_LENGTH_BYTES,
|
||||
m_spi_rx_data,
|
||||
NRF21540_SPI_LENGTH_BYTES);
|
||||
m_spi_tx_data[NRF21540_SPI_COMMAND_ADDR_BYTE] =
|
||||
(NRF21540_SPI_COMMAND_WRITE << NRF21540_SPI_COMMAND_Pos) | (reg << NRF21540_SPI_REG_Pos);
|
||||
m_spi_tx_data[NRF21540_SPI_DATA_BYTE] = data;
|
||||
uint32_t flags = start_now ? 0 : NRFX_SPIM_FLAG_HOLD_XFER;
|
||||
(void)nrfx_spim_xfer(&spi, &xfer_desc, flags);
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
wait_for_transfer_end();
|
||||
}
|
||||
}
|
||||
|
||||
/**@brief Function reads content of important nRF21540's registers and stores
|
||||
* it to dedicated structure (@ref m_confreg_statics).
|
||||
*
|
||||
* @return Return NRF based error code.
|
||||
*/
|
||||
static ret_code_t m_confreg_statics_content_update(void)
|
||||
{
|
||||
ret_code_t ret = nrf21540_pdn_drive(true, NRF21540_EXEC_MODE_BLOCKING);
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
m_confreg_statics.CONFREG0 = spi_reg_read(NRF21540_REG_CONFREG0,
|
||||
NRF21540_EXEC_MODE_BLOCKING, true);
|
||||
m_confreg_statics.CONFREG1 = spi_reg_read(NRF21540_REG_CONFREG1,
|
||||
NRF21540_EXEC_MODE_BLOCKING, true);
|
||||
return nrf21540_pdn_drive(false, NRF21540_EXEC_MODE_BLOCKING);
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_spi_init(void)
|
||||
{
|
||||
ret_code_t ret;
|
||||
nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
|
||||
spi_config.frequency = NRF_SPIM_FREQ_4M;
|
||||
spi_config.ss_pin = NRF21540_CS_PIN;
|
||||
spi_config.miso_pin = NRF21540_MISO_PIN;
|
||||
spi_config.mosi_pin = NRF21540_MOSI_PIN;
|
||||
spi_config.sck_pin = NRF21540_CLK_PIN;
|
||||
spi_config.ss_active_high = false;
|
||||
ret = nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL);
|
||||
if (ret != NRFX_SUCCESS)
|
||||
{
|
||||
return NRF_ERROR_INTERNAL;
|
||||
}
|
||||
return m_confreg_statics_content_update();
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function enables or disables nRF21540 TX mode.
|
||||
*
|
||||
* @details Preparation of appropriate register content and tranfer initialization.
|
||||
*
|
||||
* @param[in] state NRF21540_DISABLE/NRF21540_ENABLE causes TX mode disabled/enabled.
|
||||
*/
|
||||
static void tx_en_drive(nrf21540_bool_state_t state)
|
||||
{
|
||||
uint8_t reg_val;
|
||||
if (state == NRF21540_ENABLE)
|
||||
{
|
||||
reg_val = m_confreg_statics.CONFREG0 | NRF21540_BITS_CONFREG0_TX_EN_Enable;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_val = m_confreg_statics.CONFREG0 &(~NRF21540_BITS_CONFREG0_TX_EN_Enable);
|
||||
}
|
||||
spi_reg_write(NRF21540_REG_CONFREG0, reg_val, NRF21540_EXEC_MODE_NON_BLOCKING, false);
|
||||
}
|
||||
|
||||
/**@brief Function enables or disables nRF21540 RX mode.
|
||||
*
|
||||
* @details Preparation of appropriate register content and tranfer initialization.
|
||||
*
|
||||
* @param[in] state NRF21540_DISABLE/NRF21540_ENABLE causes RX mode disabled/enabled.
|
||||
*/
|
||||
static void rx_en_drive(nrf21540_bool_state_t state)
|
||||
{
|
||||
uint8_t reg_val;
|
||||
if (state == NRF21540_ENABLE)
|
||||
{
|
||||
reg_val = m_confreg_statics.CONFREG1 | NRF21540_BITS_CONFREG1_RX_EN_Enable;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_val = m_confreg_statics.CONFREG1 &(~NRF21540_BITS_CONFREG1_RX_EN_Disable);
|
||||
}
|
||||
spi_reg_write(NRF21540_REG_CONFREG1, reg_val, NRF21540_EXEC_MODE_NON_BLOCKING, false);
|
||||
}
|
||||
|
||||
inline uint32_t nrf21540_spim_trx_task_start_address_get(void)
|
||||
{
|
||||
return nrfx_spim_start_task_get(&spi);
|
||||
}
|
||||
|
||||
void nrf21540_spim_for_trx_configure(nrf21540_trx_t dir, nrf21540_bool_state_t required_state)
|
||||
{
|
||||
if (dir == NRF21540_TX)
|
||||
{
|
||||
tx_en_drive(required_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx_en_drive(required_state);
|
||||
}
|
||||
if (required_state == NRF21540_ENABLE)
|
||||
{
|
||||
uint32_t task_start_address = nrfx_spim_start_task_get(&spi);
|
||||
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_TRX_PPI_CHANNEL,
|
||||
(uint32_t)nrf_timer_event_address_get(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_PD_PG_EVENT),
|
||||
task_start_address);
|
||||
nrf_ppi_channel_enable(NRF21540_TRX_PPI_CHANNEL);
|
||||
}
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_spi_pwr_mode_set(nrf21540_pwr_mode_t mode)
|
||||
{
|
||||
if (mode == NRF21540_PWR_MODE_A)
|
||||
{
|
||||
spi_reg_write(NRF21540_REG_CONFREG0, NRF21540_BITS_CONFREG0_MODE_0,
|
||||
NRF21540_EXEC_MODE_BLOCKING, true);
|
||||
}
|
||||
else if (mode == NRF21540_PWR_MODE_B)
|
||||
{
|
||||
spi_reg_write(NRF21540_REG_CONFREG0, NRF21540_BITS_CONFREG0_MODE_1,
|
||||
NRF21540_EXEC_MODE_BLOCKING, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /*NRF21540_USE_SPI_MANAGEMENT*/
|
||||
213
components/drivers_ext/nrf21540/nrf21540_spi.h
Normal file
213
components/drivers_ext/nrf21540/nrf21540_spi.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF21540_SPI_H_
|
||||
#define NRF21540_SPI_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "nrfx_spim.h"
|
||||
#include "nrf21540_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief nRF21540 SPI interface parameters defines.
|
||||
*/
|
||||
#define NRF21540_SPI_LENGTH_BYTES 2 ///< SPI tx/rx buffer size in bytes.
|
||||
#define NRF21540_SPI_COMMAND_ADDR_BYTE 0 ///< Position of command field in SPI frame.
|
||||
#define NRF21540_SPI_DATA_BYTE 1 ///< Position of data field in SPI frame.
|
||||
#define NRF21540_SPI_COMMAND_Pos 6 ///< Command code bit-position in command field.
|
||||
#define NRF21540_SPI_REG_Pos 0 ///< Register address bit-position in command field.
|
||||
#define NRF21540_SPI_COMMAND_NOP 0x00 ///< 'NOP' command code.
|
||||
#define NRF21540_SPI_COMMAND_READ 0x02 ///< 'READ' command code.
|
||||
#define NRF21540_SPI_COMMAND_WRITE 0x03 ///< 'WRITE' command code.
|
||||
|
||||
/**@brief CONFREG0 register bitfields.
|
||||
*/
|
||||
#define NRF21540_BITS_CONFREG0_TX_EN_Pos 0 ///< Position of TX_EN field.
|
||||
#define NRF21540_BITS_CONFREG0_TX_EN_Msk (1 << NRF21540_BITS_CONFREG0_TX_EN_Pos) ///< Bit mask of TX_EN field.
|
||||
#define NRF21540_BITS_CONFREG0_TX_EN_Disable 0 ///< Disable TX mode.
|
||||
#define NRF21540_BITS_CONFREG0_TX_EN_Enable 1 ///< Enable TX mode.
|
||||
|
||||
#define NRF21540_BITS_CONFREG0_MODE_Pos 1 ///< Position of MODE field.
|
||||
#define NRF21540_BITS_CONFREG0_MODE_Msk (1 << NRF21540_BITS_CONFREG0_MODE_Pos) ///< Bit mask of MODE field.
|
||||
#define NRF21540_BITS_CONFREG0_MODE_0 0 ///< Selects MODE 0.
|
||||
#define NRF21540_BITS_CONFREG0_MODE_1 1 ///< Selects MODE 1.
|
||||
|
||||
#define NRF21540_BITS_CONFREG0_TX_GAIN_Pos 2 ///< Position of TX_GAIN field.
|
||||
#define NRF21540_BITS_CONFREG0_TX_GAIN_Msk (0x1F << NRF21540_BITS_CONFREG0_TX_GAIN_Pos) ///< Bit mask of TX_GAIN field.
|
||||
#define NRF21540_BITS_CONFREG0_TX_GAIN_Min 0 ///< Minimum TX_GAIN register value
|
||||
#define NRF21540_BITS_CONFREG0_TX_GAIN_Max 31 ///< Maximum TX_GAIN register value
|
||||
|
||||
/**@brief CONFREG1 register bitfields.
|
||||
*/
|
||||
#define NRF21540_BITS_CONFREG1_RX_EN_Pos 0 ///< Position of RX_EN field.
|
||||
#define NRF21540_BITS_CONFREG1_RX_EN_Msk (1 << NRF21540_BITS_CONFREG1_RX_EN_Pos) ///< Bit mask of TX_EN field.
|
||||
#define NRF21540_BITS_CONFREG1_RX_EN_Disable 0 ///< Disable RX mode.
|
||||
#define NRF21540_BITS_CONFREG1_RX_EN_Enable 1 ///< Enable RX mode.
|
||||
|
||||
#define NRF21540_BITS_CONFREG1_UICR_EN_Pos 2 ///< Position of UICR_EN field.
|
||||
#define NRF21540_BITS_CONFREG1_UICR_EN_Msk (1 << NRF21540_BITS_CONFREG1_UICR_EN_Pos) ///< Bit mask of UICR_EN field.
|
||||
#define NRF21540_BITS_CONFREG1_UICR_EN_Disable 0 ///< Disable UICR program mode.
|
||||
#define NRF21540_BITS_CONFREG1_UICR_EN_Enable 1 ///< Enable UICR program mode.
|
||||
|
||||
#define NRF21540_BITS_CONFREG1_KEY_Pos 4 ///< Position of KEY field.
|
||||
#define NRF21540_BITS_CONFREG1_KEY_Msk (0x0F << NRF21540_BITS_CONFREG1_KEY_Pos) ///< Bit mask of KEY field.
|
||||
#define NRF21540_BITS_CONFREG1_KEY_Enter 15 ///< Enter UICR program mode.
|
||||
#define NRF21540_BITS_CONFREG1_KEY_Leave 0 ///< Leave UICR program mode.
|
||||
|
||||
/**@brief CONFREG2 register bitfields.
|
||||
*/
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_UICR_Pos 0 ///< Position of POUTA_UICR field.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_UICR_Msk (0x1F << NRF21540_BITS_CONFREG2_POUTA_UICR_Pos) ///< Bit mask of POUTA_UICR field.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_UICR_Min 0 ///< Minimum POUTA_UICR register value
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_UICR_Max 31 ///< Maximum POUTA_UICR register value
|
||||
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_SEL_Pos 5 ///< Position of POUTA_SEL field.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_SEL_Msk (1 << NRF21540_BITS_CONFREG2_POUTA_SEL_Pos) ///< Bit mask of POUTA_SEL field.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_SEL_PROD 0 ///< Initialize TX_GAIN register with 20dBm value.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_SEL_UICR 1 ///< Initialize TX_GAIN register with POUTA_UICR value.
|
||||
|
||||
#define NRF21540_BITS_CONFREG2_WR_UICR_Pos 7 ///< Position of WR_UICR field.
|
||||
#define NRF21540_BITS_CONFREG2_WR_UICR_Msk (1 << NRF21540_BITS_CONFREG2_WR_UICR_Pos) ///< Bit mask of WR_UICR field.
|
||||
#define NRF21540_BITS_CONFREG2_WR_UICR_IDLE 0 ///< EFUSE idle .
|
||||
#define NRF21540_BITS_CONFREG2_WR_UICR_WRITE 1 ///< EFUSE write.
|
||||
|
||||
/**@brief CONFREG3 register bitfields.
|
||||
*/
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_UICR_Pos 0 ///< Position of POUTB_UICR field.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_UICR_Msk (0x1F << NRF21540_BITS_CONFREG3_POUTB_SEL_Pos) ///< Bit mask of POUTB_UICR field.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_UICR_Min 0 ///< Minimum POUTB_UICR register value
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_UICR_Max 31 ///< Maximum POUTB_UICR register value
|
||||
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_SEL_Pos 5 ///< Position of POUTB_SEL field.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_SEL_Msk (1 << NRF21540_BITS_CONFREG3_POUTB_SEL_Pos) ///< Bit mask of POUTB_SEL field.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_SEL_PROD 0 ///< Initialize TX_GAIN register with 20dBm value.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_SEL_UICR 1 ///< Initialize TX_GAIN register with POUTB_UICR value.
|
||||
|
||||
/**@brief PARTNUMBER register bitfields.
|
||||
*/
|
||||
#define NRF21540_PARTNUMBER_PARTNUMBER_Pos 0 ///< Position of PARTNUMBER field.
|
||||
#define NRF21540_PARTNUMBER_PARTNUMBER_Msk (0xFF << NRF21540_PARTNUMBER_PARTNUMBER_Pos) ///< Bit mask of PARTNUMBER field.
|
||||
|
||||
/**@brief HW_REVISON register bitfields.
|
||||
*/
|
||||
#define NRF21540_HW_REVISON_HW_REVISION_Pos 4 ///< Position of HW_REVISON field.
|
||||
#define NRF21540_HW_REVISON_HW_REVISION_Msk (0xF << NRF21540_HW_REVISON_HW_REVISION_Pos) ///< Bit mask of HW_REVISON field.
|
||||
|
||||
/**@brief HW_ID0 register bitfields.
|
||||
*/
|
||||
#define NRF21540_HW_ID0_Pos 0 ///< Position of HW_ID0 field.
|
||||
#define NRF21540_HW_ID0_Msk (0xFF << NRF21540_HW_ID0_Pos) ///< Bit mask of HW_ID0 field.
|
||||
|
||||
/**@brief HW_ID1 register bitfields.
|
||||
*/
|
||||
#define NRF21540_HW_ID1_Pos 0 ///< Position of HW_ID1 field.
|
||||
#define NRF21540_HW_ID1_Msk (0xFF << NRF21540_HW_ID1_Pos) ///< Bit mask of HW_ID1 field.
|
||||
|
||||
/**@brief nRF21540 internal registers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_REG_CONFREG0 = 0x00, ///< CONFREG0 register address.
|
||||
NRF21540_REG_CONFREG1 = 0x01, ///< CONFREG1 register address.
|
||||
NRF21540_REG_CONFREG2 = 0x02, ///< CONFREG2 register address.
|
||||
NRF21540_REG_CONFREG3 = 0x03, ///< CONFREG3 register address.
|
||||
NRF21540_REG_PARTNUMBER = 0x14, ///< PARTNUMBER register address.
|
||||
NRF21540_REG_HW_REVISION = 0x15, ///< HW_REVISION register address.
|
||||
NRF21540_REG_HW_ID0 = 0x16, ///< HW_ID0 register address.
|
||||
NRF21540_REG_HW_ID1 = 0x17, ///< HW_ID1 register address.
|
||||
} nrf21540_reg_t;
|
||||
|
||||
/**@brief Function initializes SPI interface.
|
||||
*
|
||||
* @return NRF_ERROR_INTERNAL when SPIM driver initialization error occured.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_spi_init(void);
|
||||
|
||||
/**@brief Function returns address of task which triggers SPI transfer.
|
||||
*
|
||||
* @return address of appropriate task.
|
||||
*/
|
||||
uint32_t nrf21540_spim_trx_task_start_address_get(void);
|
||||
|
||||
/**@brief Function configures the chip and peripherals for TX/RX transfer purpose.
|
||||
*
|
||||
* @details It can enable/disable RX/TX transfers.
|
||||
*
|
||||
* @param[in] dir Direction of the radio transmission. See @ref nrf21540_trx_t.
|
||||
* @param[in] required_state State of RX/TX transfer. See @ref nrf21540_bool_state_t.
|
||||
* chosen transfer type.
|
||||
*/
|
||||
void nrf21540_spim_for_trx_configure(nrf21540_trx_t dir, nrf21540_bool_state_t required_state);
|
||||
|
||||
/**@brief Function choses one of predefined power modes in nRF21540.
|
||||
*
|
||||
* @details Refer to nRF21540 Objective Product Specification, section: TX power control.
|
||||
*
|
||||
* @param[in] mode Power mode. See @ref nrf21540_pwr_mode_t.
|
||||
* @return NRF_ERROR_INVALID_PARAM when invalid argument given.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_spi_pwr_mode_set(nrf21540_pwr_mode_t mode);
|
||||
|
||||
/**@brief Function sets nRF21540 power state by driving PDN pin.
|
||||
*
|
||||
* @param[in] state Required PDN pin state.
|
||||
* @param[in] mode Execution mode. See @ref nrf21540_execution_mode_t.
|
||||
* @return NRF_ERROR_INVALID_PARAM when invalid argument given.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_pdn_drive(bool state, nrf21540_execution_mode_t mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_SPI_H_
|
||||
111
components/drivers_ext/nrf21540/nrf21540_types.h
Normal file
111
components/drivers_ext/nrf21540/nrf21540_types.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF21540_TYPES_H_
|
||||
#define NRF21540_TYPES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* @defgroup nrf21540_types nRF21540 front-end Bluetooth range extender types
|
||||
* @{
|
||||
* @ingroup nrf21540
|
||||
*/
|
||||
|
||||
/**@brief Value used as event zero-address - for immediate function execution.
|
||||
* This is useful in functions with 'user_trigger_event' input parameter.
|
||||
*/
|
||||
#define NRF21540_EXECUTE_NOW ((uint32_t)0)
|
||||
|
||||
/**@brief nRF21540 antenna outputs.
|
||||
*
|
||||
* @note Read more in the Product Specification.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_ANT1, ///< Antenna 1 output.
|
||||
NRF21540_ANT2 ///< Antenna 2 output.
|
||||
} nrf21540_antenna_t;
|
||||
|
||||
|
||||
/**@brief nRF21540 power modes.
|
||||
*
|
||||
* @note Read more in the Product Specification.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_PWR_MODE_A, ///< Power mode A.
|
||||
NRF21540_PWR_MODE_B ///< Power mode B.
|
||||
} nrf21540_pwr_mode_t;
|
||||
|
||||
|
||||
/**@brief nRF21540 transmission direction modes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_TX, ///< Transmission direction mode transmit.
|
||||
NRF21540_RX ///< Transmission direction mode receive.
|
||||
} nrf21540_trx_t;
|
||||
|
||||
/**@brief State type for nRF21540 purposes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_DISABLE, ///< State disable.
|
||||
NRF21540_ENABLE ///< State enable.
|
||||
} nrf21540_bool_state_t;
|
||||
|
||||
/**@brief Modes (blocking/non-blocking) for nRF21540 purposes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_EXEC_MODE_NON_BLOCKING, ///< Non-blocking execution mode.
|
||||
NRF21540_EXEC_MODE_BLOCKING ///< Blocking execution mode.
|
||||
} nrf21540_execution_mode_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_TYPES_H_
|
||||
Reference in New Issue
Block a user