Initial commit

This commit is contained in:
2026-04-24 10:52:47 +09:00
commit 1707dc6349
1423 changed files with 1161776 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
/**
* Copyright (c) 2016 - 2021, 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 NRF_BITMASK_H
#define NRF_BITMASK_H
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_bitmask Bitmask module
* @{
* @ingroup nrfx
* @brief Bitmask managing module.
*/
/** @brief Macro for getting index of byte in byte stream where @c abs_bit is put. */
#define BITMASK_BYTE_GET(abs_bit) ((abs_bit)/8)
/** @brief Macro for getting relative index of bit in byte. */
#define BITMASK_RELBIT_GET(abs_bit) ((abs_bit) & 0x00000007)
/**
* @brief Function for checking if bit in the multi-byte bit mask is set.
*
* @param[in] bit Bit index.
* @param[in] p_mask Pointer to mask with bit fields.
*
* @return 0 if bit is not set, positive value otherwise.
*/
__STATIC_INLINE uint32_t nrf_bitmask_bit_is_set(uint32_t bit, void const * p_mask)
{
uint8_t const * p_mask8 = (uint8_t const *)p_mask;
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
bit = BITMASK_RELBIT_GET(bit);
return (1 << bit) & p_mask8[byte_idx];
}
/**
* @brief Function for setting a bit in the multi-byte bit mask.
*
* @param[in] bit Bit index.
* @param[in] p_mask Pointer to mask with bit fields.
*/
__STATIC_INLINE void nrf_bitmask_bit_set(uint32_t bit, void * p_mask)
{
uint8_t * p_mask8 = (uint8_t *)p_mask;
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
bit = BITMASK_RELBIT_GET(bit);
p_mask8[byte_idx] |= (1 << bit);
}
/**
* @brief Function for clearing a bit in the multi-byte bit mask.
*
* @param[in] bit Bit index.
* @param[in] p_mask Pointer to mask with bit fields.
*/
__STATIC_INLINE void nrf_bitmask_bit_clear(uint32_t bit, void * p_mask)
{
uint8_t * p_mask8 = (uint8_t *)p_mask;
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
bit = BITMASK_RELBIT_GET(bit);
p_mask8[byte_idx] &= ~(1 << bit);
}
/**
* @brief Function for performing bitwise OR operation on two multi-byte bit masks.
*
* @param[in] p_mask1 Pointer to the first bit mask.
* @param[in] p_mask2 Pointer to the second bit mask.
* @param[in] p_out_mask Pointer to the output bit mask.
* @param[in] length Length of output mask in bytes.
*/
__STATIC_INLINE void nrf_bitmask_masks_or(void const * p_mask1,
void const * p_mask2,
void * p_out_mask,
uint32_t length)
{
uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
uint32_t i;
for (i = 0; i < length; i++)
{
p_mask8_out[i] = p_mask8_1[i] | p_mask8_2[i];
}
}
/**
* @brief Function for performing bitwise AND operation on two multi-byte bit masks.
*
* @param[in] p_mask1 Pointer to the first bit mask.
* @param[in] p_mask2 Pointer to the second bit mask.
* @param[in] p_out_mask Pointer to the output bit mask.
* @param[in] length Length of output mask in bytes.
*/
__STATIC_INLINE void nrf_bitmask_masks_and(void const * p_mask1,
void const * p_mask2,
void * p_out_mask,
uint32_t length)
{
uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
uint32_t i;
for (i = 0; i < length; i++)
{
p_mask8_out[i] = p_mask8_1[i] & p_mask8_2[i];
}
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_BITMASK_H
+206
View File
@@ -0,0 +1,206 @@
/**
* Copyright (c) 2016 - 2021, 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 NRFX_CLOCK_H__
#define NRFX_CLOCK_H__
#include <nrfx.h>
#include <hal/nrf_clock.h>
#include <nrfx_power_clock.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_clock CLOCK driver
* @{
* @ingroup nrf_clock
* @brief CLOCK peripheral driver.
*/
/** @brief Clock events. */
typedef enum
{
NRFX_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started.
NRFX_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started.
NRFX_CLOCK_EVT_CTTO, ///< Calibration timeout.
NRFX_CLOCK_EVT_CAL_DONE ///< Calibration has been done.
} nrfx_clock_evt_type_t;
/**
* @brief Clock event handler.
*
* @param[in] event Event.
*/
typedef void (*nrfx_clock_event_handler_t)(nrfx_clock_evt_type_t event);
/**
* @brief Function for initializing internal structures in the nrfx_clock module.
*
* After initialization, the module is in power off state (clocks are not started).
*
* @param[in] event_handler Event handler provided by the user.
* Must not be NULL.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_ALREADY_INITIALIZED The driver is already initialized.
*/
nrfx_err_t nrfx_clock_init(nrfx_clock_event_handler_t event_handler);
/** @brief Function for enabling interrupts in the clock module. */
void nrfx_clock_enable(void);
/** @brief Function for disabling interrupts in the clock module. */
void nrfx_clock_disable(void);
/** @brief Function for uninitializing the clock module. */
void nrfx_clock_uninit(void);
/** @brief Function for starting the LFCLK. */
void nrfx_clock_lfclk_start(void);
/** @brief Function for stopping the LFCLK. */
void nrfx_clock_lfclk_stop(void);
/**
* @brief Function for checking the LFCLK state.
*
* @retval true The LFCLK is running.
* @retval false The LFCLK is not running.
*/
__STATIC_INLINE bool nrfx_clock_lfclk_is_running(void);
/** @brief Function for starting the high-accuracy source HFCLK. */
void nrfx_clock_hfclk_start(void);
/** @brief Function for stopping the external high-accuracy source HFCLK. */
void nrfx_clock_hfclk_stop(void);
/**
* @brief Function for checking the HFCLK state.
*
* @retval true The HFCLK is running (XTAL source).
* @retval false The HFCLK is not running.
*/
__STATIC_INLINE bool nrfx_clock_hfclk_is_running(void);
/**
* @brief Function for starting the calibration of internal LFCLK.
*
* This function starts the calibration process. The process cannot be aborted. LFCLK and HFCLK
* must be running before this function is called.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_INVALID_STATE The low-frequency of high-frequency clock is off.
* @retval NRFX_ERROR_BUSY Clock is in the calibration phase.
*/
nrfx_err_t nrfx_clock_calibration_start(void);
/**
* @brief Function for checking if calibration is in progress.
*
* This function indicates that the system is in calibration phase.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY Clock is in the calibration phase.
*/
nrfx_err_t nrfx_clock_is_calibrating(void);
/**
* @brief Function for starting calibration timer.
*
* @param[in] interval Time after which the CTTO event and interrupt will be generated (in 0.25 s units).
*/
void nrfx_clock_calibration_timer_start(uint8_t interval);
/** @brief Function for stopping the calibration timer. */
void nrfx_clock_calibration_timer_stop(void);
/**@brief Function for returning a requested task address for the clock driver module.
*
* @param[in] task One of the peripheral tasks.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_clock_ppi_task_addr(nrf_clock_task_t task);
/**@brief Function for returning a requested event address for the clock driver module.
*
* @param[in] event One of the peripheral events.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_clock_ppi_event_addr(nrf_clock_event_t event);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t nrfx_clock_ppi_task_addr(nrf_clock_task_t task)
{
return nrf_clock_task_address_get(task);
}
__STATIC_INLINE uint32_t nrfx_clock_ppi_event_addr(nrf_clock_event_t event)
{
return nrf_clock_event_address_get(event);
}
__STATIC_INLINE bool nrfx_clock_hfclk_is_running(void)
{
return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY);
}
__STATIC_INLINE bool nrfx_clock_lfclk_is_running(void)
{
return nrf_clock_lf_is_running();
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
void nrfx_clock_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_CLOCK_H__
+494
View File
@@ -0,0 +1,494 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_GPIOTE_H__
#define NRFX_GPIOTE_H__
#include <nrfx.h>
#include <hal/nrf_gpiote.h>
#include <hal/nrf_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_gpiote GPIOTE driver
* @{
* @ingroup nrf_gpiote
* @brief GPIO Task Event (GPIOTE) peripheral driver.
*/
/** @brief Input pin configuration. */
typedef struct
{
nrf_gpiote_polarity_t sense; /**< Transition that triggers the interrupt. */
nrf_gpio_pin_pull_t pull; /**< Pulling mode. */
bool is_watcher : 1; /**< True when the input pin is tracking an output pin. */
bool hi_accuracy : 1; /**< True when high accuracy (IN_EVENT) is used. */
bool skip_gpio_setup : 1; /**< Do not change GPIO configuration */
} nrfx_gpiote_in_config_t;
/**
* @brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect low-to-high transition.
* @details Set hi_accu to true to use IN_EVENT.
*/
#define NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(hi_accu) \
{ \
.sense = NRF_GPIOTE_POLARITY_LOTOHI, \
.pull = NRF_GPIO_PIN_NOPULL, \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.skip_gpio_setup = false, \
}
/**
* @brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect high-to-low transition.
* @details Set hi_accu to true to use IN_EVENT.
*/
#define NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(hi_accu) \
{ \
.sense = NRF_GPIOTE_POLARITY_HITOLO, \
.pull = NRF_GPIO_PIN_NOPULL, \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.skip_gpio_setup = false, \
}
/**
* @brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect any change on the pin.
* @details Set hi_accu to true to use IN_EVENT.
*/
#define NRFX_GPIOTE_CONFIG_IN_SENSE_TOGGLE(hi_accu) \
{ \
.sense = NRF_GPIOTE_POLARITY_TOGGLE, \
.pull = NRF_GPIO_PIN_NOPULL, \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.skip_gpio_setup = false, \
}
/**
* @brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect low-to-high transition.
* @details Set hi_accu to true to use IN_EVENT.
* @note This macro prepares configuration that skips the GPIO setup.
*/
#define NRFX_GPIOTE_RAW_CONFIG_IN_SENSE_LOTOHI(hi_accu) \
{ \
.sense = NRF_GPIOTE_POLARITY_LOTOHI, \
.pull = NRF_GPIO_PIN_NOPULL, \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.skip_gpio_setup = true, \
}
/**
* @brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect high-to-low transition.
* @details Set hi_accu to true to use IN_EVENT.
* @note This macro prepares configuration that skips the GPIO setup.
*/
#define NRFX_GPIOTE_RAW_CONFIG_IN_SENSE_HITOLO(hi_accu) \
{ \
.sense = NRF_GPIOTE_POLARITY_HITOLO, \
.pull = NRF_GPIO_PIN_NOPULL, \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.skip_gpio_setup = true, \
}
/**
* @brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect any change on the pin.
* @details Set hi_accu to true to use IN_EVENT.
* @note This macro prepares configuration that skips the GPIO setup.
*/
#define NRFX_GPIOTE_RAW_CONFIG_IN_SENSE_TOGGLE(hi_accu) \
{ \
.sense = NRF_GPIOTE_POLARITY_TOGGLE, \
.pull = NRF_GPIO_PIN_NOPULL, \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.skip_gpio_setup = true, \
}
/** @brief Output pin configuration. */
typedef struct
{
nrf_gpiote_polarity_t action; /**< Configuration of the pin task. */
nrf_gpiote_outinit_t init_state; /**< Initial state of the output pin. */
bool task_pin; /**< True if the pin is controlled by a GPIOTE task. */
} nrfx_gpiote_out_config_t;
/** @brief Macro for configuring a pin to use as output. GPIOTE is not used for the pin. */
#define NRFX_GPIOTE_CONFIG_OUT_SIMPLE(init_high) \
{ \
.action = NRF_GPIOTE_POLARITY_LOTOHI, \
.init_state = init_high ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW, \
.task_pin = false, \
}
/**
* @brief Macro for configuring a pin to use the GPIO OUT TASK to change the state from high to low.
* @details The task will clear the pin. Therefore, the pin is set initially.
*/
#define NRFX_GPIOTE_CONFIG_OUT_TASK_LOW \
{ \
.init_state = NRF_GPIOTE_INITIAL_VALUE_HIGH, \
.task_pin = true, \
.action = NRF_GPIOTE_POLARITY_HITOLO, \
}
/**
* @brief Macro for configuring a pin to use the GPIO OUT TASK to change the state from low to high.
* @details The task will set the pin. Therefore, the pin is cleared initially.
*/
#define NRFX_GPIOTE_CONFIG_OUT_TASK_HIGH \
{ \
.action = NRF_GPIOTE_POLARITY_LOTOHI, \
.init_state = NRF_GPIOTE_INITIAL_VALUE_LOW, \
.task_pin = true, \
}
/**
* @brief Macro for configuring a pin to use the GPIO OUT TASK to toggle the pin state.
* @details The initial pin state must be provided.
*/
#define NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(init_high) \
{ \
.action = NRF_GPIOTE_POLARITY_TOGGLE, \
.init_state = init_high ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW, \
.task_pin = true, \
}
/** @brief Pin. */
typedef uint32_t nrfx_gpiote_pin_t;
/**
* @brief Pin event handler prototype.
*
* @param[in] pin Pin that triggered this event.
* @param[in] action Action that led to triggering this event.
*/
typedef void (*nrfx_gpiote_evt_handler_t)(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action);
/**
* @brief Function for initializing the GPIOTE module.
*
* @details Only static configuration is supported to prevent the shared
* resource being customized by the initiator.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver was already initialized.
*/
nrfx_err_t nrfx_gpiote_init(void);
/**
* @brief Function for checking if the GPIOTE module is initialized.
*
* @details The GPIOTE module is a shared module. Therefore, check if
* the module is already initialized and skip initialization if it is.
*
* @retval true The module is already initialized.
* @retval false The module is not initialized.
*/
bool nrfx_gpiote_is_init(void);
/** @brief Function for uninitializing the GPIOTE module. */
void nrfx_gpiote_uninit(void);
/**
* @brief Function for initializing a GPIOTE output pin.
* @details The output pin can be controlled by the CPU or by PPI. The initial
* configuration specifies which mode is used. If PPI mode is used, the driver
* attempts to allocate one of the available GPIOTE channels. If no channel is
* available, an error is returned.
*
* @param[in] pin Pin.
* @param[in] p_config Initial configuration.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver is not initialized or the pin is already used.
* @retval NRFX_ERROR_NO_MEM No GPIOTE channel is available.
*/
nrfx_err_t nrfx_gpiote_out_init(nrfx_gpiote_pin_t pin,
nrfx_gpiote_out_config_t const * p_config);
/**
* @brief Function for uninitializing a GPIOTE output pin.
* @details The driver frees the GPIOTE channel if the output pin was using one.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_uninit(nrfx_gpiote_pin_t pin);
/**
* @brief Function for setting a GPIOTE output pin.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_set(nrfx_gpiote_pin_t pin);
/**
* @brief Function for clearing a GPIOTE output pin.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_clear(nrfx_gpiote_pin_t pin);
/**
* @brief Function for toggling a GPIOTE output pin.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_toggle(nrfx_gpiote_pin_t pin);
/**
* @brief Function for enabling a GPIOTE output pin task.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_task_enable(nrfx_gpiote_pin_t pin);
/**
* @brief Function for disabling a GPIOTE output pin task.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_task_disable(nrfx_gpiote_pin_t pin);
/**
* @brief Function for getting the OUT task for the specified output pin.
*
* @details The returned task identifier can be used within @ref nrf_gpiote_hal,
* for example, to configure a DPPI channel.
*
* @param[in] pin Pin.
*
* @return OUT task associated with the specified output pin.
*/
nrf_gpiote_tasks_t nrfx_gpiote_out_task_get(nrfx_gpiote_pin_t pin);
/**
* @brief Function for getting the address of the OUT task for the specified output pin.
*
* @param[in] pin Pin.
*
* @return Address of OUT task.
*/
uint32_t nrfx_gpiote_out_task_addr_get(nrfx_gpiote_pin_t pin);
#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the SET task for the specified output pin.
*
* @details The returned task identifier can be used within @ref nrf_gpiote_hal,
* for example, to configure a DPPI channel.
*
* @param[in] pin Pin.
*
* @return SET task associated with the specified output pin.
*/
nrf_gpiote_tasks_t nrfx_gpiote_set_task_get(nrfx_gpiote_pin_t pin);
/**
* @brief Function for getting the address of the SET task for the specified output pin.
*
* @param[in] pin Pin.
*
* @return Address of SET task.
*/
uint32_t nrfx_gpiote_set_task_addr_get(nrfx_gpiote_pin_t pin);
#endif // defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the CLR task for the specified output pin.
*
* @details The returned task identifier can be used within @ref nrf_gpiote_hal,
* for example, to configure a DPPI channel.
*
* @param[in] pin Pin.
*
* @return CLR task associated with the specified output pin.
*/
nrf_gpiote_tasks_t nrfx_gpiote_clr_task_get(nrfx_gpiote_pin_t pin);
/**
* @brief Function for getting the address of the SET task for the specified output pin.
*
* @param[in] pin Pin.
*
* @return Address of CLR task.
*/
uint32_t nrfx_gpiote_clr_task_addr_get(nrfx_gpiote_pin_t pin);
#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for initializing a GPIOTE input pin.
* @details The input pin can act in two ways:
* - lower accuracy but low power (high frequency clock not needed)
* - higher accuracy (high frequency clock required)
*
* The initial configuration specifies which mode is used.
* If high-accuracy mode is used, the driver attempts to allocate one
* of the available GPIOTE channels. If no channel is
* available, an error is returned.
* In low accuracy mode SENSE feature is used. In this case, only one active pin
* can be detected at a time. It can be worked around by setting all of the used
* low accuracy pins to toggle mode.
* For more information about SENSE functionality, refer to Product Specification.
*
* @param[in] pin Pin.
* @param[in] p_config Initial configuration.
* @param[in] evt_handler User function to be called when the configured transition occurs.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver is not initialized or the pin is already used.
* @retval NRFX_ERROR_NO_MEM No GPIOTE channel is available.
*/
nrfx_err_t nrfx_gpiote_in_init(nrfx_gpiote_pin_t pin,
nrfx_gpiote_in_config_t const * p_config,
nrfx_gpiote_evt_handler_t evt_handler);
/**
* @brief Function for uninitializing a GPIOTE input pin.
* @details The driver frees the GPIOTE channel if the input pin was using one.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_in_uninit(nrfx_gpiote_pin_t pin);
/**
* @brief Function for enabling sensing of a GPIOTE input pin.
*
* @details If the input pin is configured as high-accuracy pin, the function
* enables an IN_EVENT. Otherwise, the function enables the GPIO sense mechanism.
* The PORT event is shared between multiple pins, therefore the interrupt is always enabled.
*
* @param[in] pin Pin.
* @param[in] int_enable True to enable the interrupt. Always valid for a high-accuracy pin.
*/
void nrfx_gpiote_in_event_enable(nrfx_gpiote_pin_t pin, bool int_enable);
/**
* @brief Function for disabling a GPIOTE input pin.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_in_event_disable(nrfx_gpiote_pin_t pin);
/**
* @brief Function for checking if a GPIOTE input pin is set.
*
* @param[in] pin Pin.
*
* @retval true The input pin is set.
* @retval false The input pin is not set.
*/
bool nrfx_gpiote_in_is_set(nrfx_gpiote_pin_t pin);
/**
* @brief Function for getting the GPIOTE event for the specified input pin.
*
* @details The returned event identifier can be used within @ref nrf_gpiote_hal,
* for example, to configure a DPPI channel.
* If the pin is configured to use low-accuracy mode, the PORT event
* is returned.
*
* @param[in] pin Pin.
*
* @return Event associated with the specified input pin.
*/
nrf_gpiote_events_t nrfx_gpiote_in_event_get(nrfx_gpiote_pin_t pin);
/**
* @brief Function for getting the address of a GPIOTE input pin event.
* @details If the pin is configured to use low-accuracy mode, the address of the PORT event is returned.
*
* @param[in] pin Pin.
*
* @return Address of the specified input pin event.
*/
uint32_t nrfx_gpiote_in_event_addr_get(nrfx_gpiote_pin_t pin);
/**
* @brief Function for forcing a specific state on the pin configured as task.
*
* @param[in] pin Pin.
* @param[in] state Pin state.
*/
void nrfx_gpiote_out_task_force(nrfx_gpiote_pin_t pin, uint8_t state);
/**
* @brief Function for triggering the task OUT manually.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_task_trigger(nrfx_gpiote_pin_t pin);
#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for triggering the task SET manually.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_set_task_trigger(nrfx_gpiote_pin_t pin);
#endif // defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for triggering the task CLR manually.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_clr_task_trigger(nrfx_gpiote_pin_t pin);
#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
/** @} */
void nrfx_gpiote_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_GPIOTE_H__
+295
View File
@@ -0,0 +1,295 @@
/**
* Copyright (c) 2019 - 2021, 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 NRFX_NVMC_H__
#define NRFX_NVMC_H__
#include <nrfx.h>
#include <hal/nrf_nvmc.h>
#include <hal/nrf_ficr.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_nvmc NVMC driver
* @{
* @ingroup nrf_nvmc
* @brief Non-Volatile Memory Controller (NVMC) peripheral driver.
*/
/**
* @brief Function for erasing a page in flash.
*
* This function blocks until the erase operation finishes.
*
* @note Depending on the source of the code being executed,
* the CPU may be halted during the operation.
* Refer to the Product Specification for more information.
*
* @param address Address of the first word in the page to erase.
*
* @retval NRFX_SUCCESS Page erase complete.
* @retval NRFX_ERROR_INVALID_ADDR Address is not aligned to the size of the page.
*/
nrfx_err_t nrfx_nvmc_page_erase(uint32_t address);
/**
* @brief Function for erasing the user information configuration register (UICR).
*
* @note Depending on the source of the code being executed,
* the CPU may be halted during the operation.
* Refer to the Product Specification for more information.
*
* @retval NRFX_SUCCESS UICR has been successfully erased.
* @retval NRFX_ERROR_NOT_SUPPORTED UICR erase is not supported.
*/
nrfx_err_t nrfx_nvmc_uicr_erase(void);
/**
* @brief Function for erasing the whole flash memory.
*
* @note All user code and UICR will be erased.
*/
void nrfx_nvmc_all_erase(void);
#if defined(NRF_NVMC_PARTIAL_ERASE_PRESENT)
/**
* @brief Function for initiating a complete page erase split into parts (also known as partial erase).
*
* This function initiates a partial erase with the specified duration.
* To execute each part of the partial erase, use @ref nrfx_nvmc_page_partial_erase_continue.
*
* @param address Address of the first word in the page to erase.
* @param duration_ms Time in milliseconds that each partial erase will take.
*
* @retval NRFX_SUCCESS Partial erase started.
* @retval NRFX_ERROR_INVALID_ADDR Address is not aligned to the size of the page.
*
* @sa nrfx_nvmc_page_partial_erase_continue()
*/
nrfx_err_t nrfx_nvmc_page_partial_erase_init(uint32_t address, uint32_t duration_ms);
/**
* @brief Function for performing a part of the complete page erase (also known as partial erase).
*
* This function must be called several times to erase the whole page, once for each erase part.
*
* @note The actual time needed to perform each part of the page erase is longer than the partial
* erase duration specified in the call to @ref nrfx_nvmc_page_partial_erase_init,
* since the NVMC peripheral needs certain additional amount of time to handle the process.
* For details regarding this additional time, see the "Electrical specification" section
* for the NVMC peripheral in the Product Specification.
*
* @note Using a page that was not completely erased leads to undefined behavior.
* Depending on the source of the code being executed,
* the CPU may be halted during the operation.
* Refer to the Product Specification for more information.
*
* @retval true Partial erase finished.
* @retval false Partial erase not finished.
* Call the function again to process the next part.
*/
bool nrfx_nvmc_page_partial_erase_continue(void);
#endif // defined(NRF_NVMC_PARTIAL_ERASE_PRESENT)
/**
* @brief Function for checking whether a byte is writable at the specified address.
*
* The NVMC is only able to write '0' to bits in the flash that are erased (set to '1').
* It cannot rewrite a bit back to '1'. This function checks if the value currently
* residing at the specified address can be transformed to the desired value
* without any '0' to '1' transitions.
*
* @param address Address to be checked.
* @param value Value to be checked.
*
* @retval true Byte can be written at the specified address.
* @retval false Byte cannot be written at the specified address.
* Erase the page or change the address.
*/
bool nrfx_nvmc_byte_writable_check(uint32_t address, uint8_t value);
/**
* @brief Function for writing a single byte to flash.
*
* To determine if the flash write has been completed, use @ref nrfx_nvmc_write_done_check().
*
* @note Depending on the source of the code being executed,
* the CPU may be halted during the operation.
* Refer to the Product Specification for more information.
*
* @param address Address to write to.
* @param value Value to write.
*/
void nrfx_nvmc_byte_write(uint32_t address, uint8_t value);
/**
* @brief Function for checking whether a word is writable at the specified address.
*
* The NVMC is only able to write '0' to bits in the Flash that are erased (set to '1').
* It cannot rewrite a bit back to '1'. This function checks if the value currently
* residing at the specified address can be transformed to the desired value
* without any '0' to '1' transitions.
*
* @param address Address to be checked. Must be word-aligned.
* @param value Value to be checked.
*
* @retval true Word can be written at the specified address.
* @retval false Word cannot be written at the specified address.
* Erase page or change address.
*/
bool nrfx_nvmc_word_writable_check(uint32_t address, uint32_t value);
/**
* @brief Function for writing a 32-bit word to flash.
*
* To determine if the flash write has been completed, use @ref nrfx_nvmc_write_done_check().
*
* @note Depending on the source of the code being executed,
* the CPU may be halted during the operation.
* Refer to the Product Specification for more information.
*
* @param address Address to write to. Must be word-aligned.
* @param value Value to write.
*/
void nrfx_nvmc_word_write(uint32_t address, uint32_t value);
/**
* @brief Function for writing consecutive bytes to flash.
*
* To determine if the last flash write has been completed, use @ref nrfx_nvmc_write_done_check().
*
* @note Depending on the source of the code being executed,
* the CPU may be halted during the operation.
* Refer to the Product Specification for more information.
*
* @param address Address to write to.
* @param src Pointer to the data to copy from.
* @param num_bytes Number of bytes to write.
*/
void nrfx_nvmc_bytes_write(uint32_t address, void const * src, uint32_t num_bytes);
/**
* @brief Function for writing consecutive words to flash.
*
* To determine if the last flash write has been completed, use @ref nrfx_nvmc_write_done_check().
*
* @note Depending on the source of the code being executed,
* the CPU may be halted during the operation.
* Refer to the Product Specification for more information.
*
* @param address Address to write to. Must be word-aligned.
* @param src Pointer to data to copy from. Must be word-aligned.
* @param num_words Number of words to write.
*/
void nrfx_nvmc_words_write(uint32_t address, void const * src, uint32_t num_words);
/**
* @brief Function for getting the total flash size in bytes.
*
* @return Flash total size in bytes.
*/
uint32_t nrfx_nvmc_flash_size_get(void);
/**
* @brief Function for getting the flash page size in bytes.
*
* @return Flash page size in bytes.
*/
uint32_t nrfx_nvmc_flash_page_size_get(void);
/**
* @brief Function for getting the flash page count.
*
* @return Flash page count.
*/
uint32_t nrfx_nvmc_flash_page_count_get(void);
/**
* @brief Function for checking if the last flash write has been completed.
*
* @retval true Last write completed successfully.
* @retval false Last write is still in progress.
*/
__STATIC_INLINE bool nrfx_nvmc_write_done_check(void);
#if defined(NRF_NVMC_ICACHE_PRESENT)
/**
* @brief Function for enabling the Instruction Cache (ICache).
*
* Enabling ICache reduces the amount of accesses to flash memory,
* which can boost performance and lower power consumption.
*/
__STATIC_INLINE void nrfx_nvmc_icache_enable(void);
/** @brief Function for disabling ICache. */
__STATIC_INLINE void nrfx_nvmc_icache_disable(void);
#endif // defined(NRF_NVMC_ICACHE_PRESENT)
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE bool nrfx_nvmc_write_done_check(void)
{
return nrf_nvmc_ready_check(NRF_NVMC);
}
#if defined(NRF_NVMC_ICACHE_PRESENT)
__STATIC_INLINE void nrfx_nvmc_icache_enable(void)
{
nrf_nvmc_icache_config_set(NRF_NVMC, NRF_NVMC_ICACHE_ENABLE_WITH_PROFILING);
}
__STATIC_INLINE void nrfx_nvmc_icache_disable(void)
{
nrf_nvmc_icache_config_set(NRF_NVMC, NRF_NVMC_ICACHE_DISABLE);
}
#endif // defined(NRF_NVMC_ICACHE_PRESENT)
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_NVMC_H__
+380
View File
@@ -0,0 +1,380 @@
/**
* Copyright (c) 2017 - 2021, 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 NRFX_POWER_H__
#define NRFX_POWER_H__
#include <nrfx.h>
#include <hal/nrf_power.h>
#include <nrfx_power_clock.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_power POWER driver
* @{
* @ingroup nrf_power
* @brief POWER peripheral driver.
*/
/**
* @brief Power mode possible configurations
*/
typedef enum
{
NRFX_POWER_MODE_CONSTLAT, /**< Constant latency mode */
NRFX_POWER_MODE_LOWPWR /**< Low power mode */
}nrfx_power_mode_t;
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
* @brief Events from power system
*/
typedef enum
{
NRFX_POWER_SLEEP_EVT_ENTER, /**< CPU entered WFI/WFE sleep
*
* Keep in mind that if this interrupt is enabled,
* it means that CPU was waken up just after WFI by this interrupt.
*/
NRFX_POWER_SLEEP_EVT_EXIT /**< CPU exited WFI/WFE sleep */
}nrfx_power_sleep_evt_t;
#endif /* NRF_POWER_HAS_SLEEPEVT */
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Events from USB power system
*/
typedef enum
{
NRFX_POWER_USB_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */
NRFX_POWER_USB_EVT_REMOVED, /**< USB power removed from the connector. */
NRFX_POWER_USB_EVT_READY /**< USB power regulator ready. */
}nrfx_power_usb_evt_t;
/**
* @brief USB power state
*
* The single enumerator that holds all data about current state of USB
* related POWER.
*
* Organized this way that higher power state has higher numeric value
*/
typedef enum
{
NRFX_POWER_USB_STATE_DISCONNECTED, /**< No power on USB lines detected. */
NRFX_POWER_USB_STATE_CONNECTED, /**< The USB power is detected, but USB power regulator is not ready. */
NRFX_POWER_USB_STATE_READY /**< From the power viewpoint, USB is ready for working. */
}nrfx_power_usb_state_t;
#endif /* NRF_POWER_HAS_USBREG */
/**
* @name Callback types
*
* Defined types of callback functions.
* @{
*/
/**
* @brief Event handler for power failure warning.
*/
typedef void (*nrfx_power_pofwarn_event_handler_t)(void);
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
* @brief Event handler for the sleep events.
*
* @param event Event type
*/
typedef void (*nrfx_power_sleep_event_handler_t)(nrfx_power_sleep_evt_t event);
#endif
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Event handler for the USB-related power events.
*
* @param event Event type
*/
typedef void (*nrfx_power_usb_event_handler_t)(nrfx_power_usb_evt_t event);
#endif
/** @} */
/**
* @brief General power configuration
*
* Parameters required to initialize power driver.
*/
typedef struct
{
/**
* @brief Enable main DCDC regulator.
*
* This bit only informs the driver that elements for DCDC regulator
* are installed and the regulator can be used.
* The regulator will be enabled or disabled automatically
* by the hardware, basing on current power requirement.
*/
bool dcdcen:1;
#if NRF_POWER_HAS_VDDH || defined(__NRFX_DOXYGEN__)
/**
* @brief Enable HV DCDC regulator.
*
* This bit only informs the driver that elements for DCDC regulator
* are installed and the regulator can be used.
* The regulator will be enabled or disabled automatically
* by the hardware, basing on current power requirement.
*/
bool dcdcenhv: 1;
#endif
}nrfx_power_config_t;
/**
* @brief The configuration for power failure comparator.
*
* Configuration used to enable and configure the power failure comparator.
*/
typedef struct
{
nrfx_power_pofwarn_event_handler_t handler; //!< Event handler.
#if NRF_POWER_HAS_POFCON || defined(__NRFX_DOXYGEN__)
nrf_power_pof_thr_t thr; //!< Threshold for power failure detection
#endif
#if NRF_POWER_HAS_VDDH || defined(__NRFX_DOXYGEN__)
nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on the VDDH pin.
#endif
}nrfx_power_pofwarn_config_t;
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
* @brief The configuration of sleep event processing.
*
* Configuration used to enable and configure sleep event handling.
*/
typedef struct
{
nrfx_power_sleep_event_handler_t handler; //!< Event handler.
bool en_enter:1; //!< Enable event on sleep entering.
bool en_exit :1; //!< Enable event on sleep exiting.
}nrfx_power_sleepevt_config_t;
#endif
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief The configuration of the USB-related power events.
*
* Configuration used to enable and configure USB power event handling.
*/
typedef struct
{
nrfx_power_usb_event_handler_t handler; //!< Event processing.
}nrfx_power_usbevt_config_t;
#endif /* NRF_POWER_HAS_USBREG */
/**
* @brief Function for getting the handler of the power failure comparator.
* @return Handler of the power failure comparator.
*/
nrfx_power_pofwarn_event_handler_t nrfx_power_pof_handler_get(void);
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the handler of the USB power.
* @return Handler of the USB power.
*/
nrfx_power_usb_event_handler_t nrfx_power_usb_handler_get(void);
#endif
/**
* @brief Function for initializing the power module driver.
*
* Enabled power module driver processes all the interrupts from the power system.
*
* @param[in] p_config Pointer to the structure with the initial configuration.
*
* @retval NRFX_SUCCESS Successfully initialized.
* @retval NRFX_ERROR_ALREADY_INITIALIZED Module was already initialized.
*/
nrfx_err_t nrfx_power_init(nrfx_power_config_t const * p_config);
/**
* @brief Function for unintializing the power module driver.
*
* Disables all the interrupt handling in the module.
*
* @sa nrfx_power_init
*/
void nrfx_power_uninit(void);
#if NRF_POWER_HAS_POFCON || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for initializing the power failure comparator.
*
* Configures the power failure comparator. This function does not set it up and enable it.
* These steps can be done with functions @ref nrfx_power_pof_enable and @ref nrfx_power_pof_disable
* or with the SoftDevice API (when in use).
*
* @param[in] p_config Configuration with values and event handler.
* If event handler is set to NULL, the interrupt will be disabled.
*/
void nrfx_power_pof_init(nrfx_power_pofwarn_config_t const * p_config);
/**
* @brief Function for enabling the power failure comparator.
* Sets and enables the interrupt of the power failure comparator. This function cannot be in use
* when SoftDevice is enabled. If the event handler set in the init function is set to NULL, the interrupt
* will be disabled.
*
* @param[in] p_config Configuration with values and event handler.
*/
void nrfx_power_pof_enable(nrfx_power_pofwarn_config_t const * p_config);
/**
* @brief Function for disabling the power failure comparator.
*
* Disables the power failure comparator interrupt.
*/
void nrfx_power_pof_disable(void);
/**
* @brief Function for clearing the power failure comparator settings.
*
* Clears the settings of the power failure comparator.
*/
void nrfx_power_pof_uninit(void);
#endif // NRF_POWER_HAS_POFCON || defined(__NRFX_DOXYGEN__)
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for initializing the processing of the sleep events.
*
* Configures and sets up the sleep event processing.
*
* @param[in] p_config Configuration with values and event handler.
*
* @sa nrfx_power_sleepevt_uninit
*
*/
void nrfx_power_sleepevt_init(nrfx_power_sleepevt_config_t const * p_config);
/**
* @brief Function for enabling the processing of the sleep events.
*
* @param[in] p_config Configuration with values and event handler.
*/
void nrfx_power_sleepevt_enable(nrfx_power_sleepevt_config_t const * p_config);
/** @brief Function for disabling the processing of the sleep events. */
void nrfx_power_sleepevt_disable(void);
/**
* @brief Function for uninitializing the processing of the sleep events.
*
* @sa nrfx_power_sleepevt_init
*/
void nrfx_power_sleepevt_uninit(void);
#endif /* NRF_POWER_HAS_SLEEPEVT */
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for initializing the processing of USB power event.
*
* Configures and sets up the USB power event processing.
*
* @param[in] p_config Configuration with values and event handler.
*
* @sa nrfx_power_usbevt_uninit
*/
void nrfx_power_usbevt_init(nrfx_power_usbevt_config_t const * p_config);
/** @brief Function for enabling the processing of USB power event. */
void nrfx_power_usbevt_enable(void);
/** @brief Function for disabling the processing of USB power event. */
void nrfx_power_usbevt_disable(void);
/**
* @brief Function for uninitalizing the processing of USB power event.
*
* @sa nrfx_power_usbevt_init
*/
void nrfx_power_usbevt_uninit(void);
/**
* @brief Function for getting the status of USB power.
*
* @return Current USB power status.
*/
__STATIC_INLINE nrfx_power_usb_state_t nrfx_power_usbstatus_get(void);
#endif /* NRF_POWER_HAS_USBREG */
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
#if NRF_POWER_HAS_USBREG
__STATIC_INLINE nrfx_power_usb_state_t nrfx_power_usbstatus_get(void)
{
uint32_t status = nrf_power_usbregstatus_get();
if(0 == (status & NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK))
{
return NRFX_POWER_USB_STATE_DISCONNECTED;
}
if(0 == (status & NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK))
{
return NRFX_POWER_USB_STATE_CONNECTED;
}
return NRFX_POWER_USB_STATE_READY;
}
#endif /* NRF_POWER_HAS_USBREG */
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
/** @} */
void nrfx_power_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif /* NRFX_POWER_H__ */
@@ -0,0 +1,92 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_POWER_CLOCK_H__
#define NRFX_POWER_CLOCK_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
__STATIC_INLINE void nrfx_power_clock_irq_init(void);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrfx_power_clock_irq_init(void)
{
uint8_t priority;
#if NRFX_CHECK(NRFX_POWER_ENABLED) && NRFX_CHECK(NRFX_CLOCK_ENABLED)
#if NRFX_POWER_CONFIG_IRQ_PRIORITY != NRFX_CLOCK_CONFIG_IRQ_PRIORITY
#error "IRQ priorities for POWER and CLOCK must be the same. Check <nrfx_config.h>."
#endif
priority = NRFX_POWER_CONFIG_IRQ_PRIORITY;
#elif NRFX_CHECK(NRFX_POWER_ENABLED)
priority = NRFX_POWER_CONFIG_IRQ_PRIORITY;
#elif NRFX_CHECK(NRFX_CLOCK_ENABLED)
priority = NRFX_CLOCK_CONFIG_IRQ_PRIORITY;
#else
#error "This code is not supposed to be compiled when neither POWER nor CLOCK is enabled."
#endif
if (!NRFX_IRQ_IS_ENABLED(nrfx_get_irq_number(NRF_CLOCK)))
{
NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_CLOCK), priority);
NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_CLOCK));
}
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#if NRFX_CHECK(NRFX_POWER_ENABLED) && NRFX_CHECK(NRFX_CLOCK_ENABLED)
void nrfx_power_clock_irq_handler(void);
#elif NRFX_CHECK(NRFX_POWER_ENABLED)
#define nrfx_power_irq_handler nrfx_power_clock_irq_handler
#elif NRFX_CHECK(NRFX_CLOCK_ENABLED)
#define nrfx_clock_irq_handler nrfx_power_clock_irq_handler
#endif
#ifdef __cplusplus
}
#endif
#endif // NRFX_POWER_CLOCK_H__
+331
View File
@@ -0,0 +1,331 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_PPI_H__
#define NRFX_PPI_H__
#include <nrfx.h>
#include <hal/nrf_ppi.h>
/**
* @defgroup nrfx_ppi PPI allocator
* @{
* @ingroup nrf_ppi
* @brief Programmable Peripheral Interconnect (PPI) allocator.
*/
#ifdef __cplusplus
extern "C" {
#endif
#if !defined (NRFX_PPI_CHANNELS_USED) || defined(__NRFX_DOXYGEN__)
/** @brief Bitfield representing PPI channels used by external modules. */
#define NRFX_PPI_CHANNELS_USED 0
#endif
#if !defined(NRFX_PPI_GROUPS_USED) || defined(__NRFX_DOXYGEN__)
/** @brief Bitfield representing PPI groups used by external modules. */
#define NRFX_PPI_GROUPS_USED 0
#endif
#if (PPI_CH_NUM > 16) || defined(__NRFX_DOXYGEN__)
/** @brief Bitfield representing all PPI channels available to the application. */
#define NRFX_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFFFFFFFuL & ~(NRFX_PPI_CHANNELS_USED))
/** @brief Bitfield representing programmable PPI channels available to the application. */
#define NRFX_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x000FFFFFuL & ~(NRFX_PPI_CHANNELS_USED))
#else
#define NRFX_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFF0FFFFuL & ~(NRFX_PPI_CHANNELS_USED))
#define NRFX_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x0000FFFFuL & ~(NRFX_PPI_CHANNELS_USED))
#endif
/** @brief Bitfield representing all PPI groups available to the application. */
#define NRFX_PPI_ALL_APP_GROUPS_MASK (((1uL << PPI_GROUP_NUM) - 1) & ~(NRFX_PPI_GROUPS_USED))
/**
* @brief Function for uninitializing the PPI module.
*
* This function disables all channels and clears the channel groups.
*/
void nrfx_ppi_free_all(void);
/**
* @brief Function for allocating a PPI channel.
* @details This function allocates the first unused PPI channel.
*
* @param[out] p_channel Pointer to the PPI channel that has been allocated.
*
* @retval NRFX_SUCCESS The channel was successfully allocated.
* @retval NRFX_ERROR_NO_MEM There is no available channel to be used.
*/
nrfx_err_t nrfx_ppi_channel_alloc(nrf_ppi_channel_t * p_channel);
/**
* @brief Function for freeing a PPI channel.
* @details This function also disables the chosen channel.
*
* @param[in] channel PPI channel to be freed.
*
* @retval NRFX_SUCCESS The channel was successfully freed.
* @retval NRFX_ERROR_INVALID_PARAM The channel is not user-configurable.
*/
nrfx_err_t nrfx_ppi_channel_free(nrf_ppi_channel_t channel);
/**
* @brief Function for assigning task and event endpoints to the PPI channel.
*
* @param[in] channel PPI channel to be assigned endpoints.
* @param[in] eep Event endpoint address.
* @param[in] tep Task endpoint address.
*
* @retval NRFX_SUCCESS The channel was successfully assigned.
* @retval NRFX_ERROR_INVALID_STATE The channel is not allocated for the user.
* @retval NRFX_ERROR_INVALID_PARAM The channel is not user-configurable.
*/
nrfx_err_t nrfx_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep);
/**
* @brief Function for assigning fork endpoint to the PPI channel or clearing it.
*
* @param[in] channel PPI channel to be assigned endpoints.
* @param[in] fork_tep Fork task endpoint address or 0 to clear.
*
* @retval NRFX_SUCCESS The channel was successfully assigned.
* @retval NRFX_ERROR_INVALID_STATE The channel is not allocated for the user.
* @retval NRFX_ERROR_NOT_SUPPORTED Function is not supported.
*/
nrfx_err_t nrfx_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep);
/**
* @brief Function for enabling a PPI channel.
*
* @param[in] channel PPI channel to be enabled.
*
* @retval NRFX_SUCCESS The channel was successfully enabled.
* @retval NRFX_ERROR_INVALID_STATE The user-configurable channel is not allocated.
* @retval NRFX_ERROR_INVALID_PARAM The channel cannot be enabled by the user.
*/
nrfx_err_t nrfx_ppi_channel_enable(nrf_ppi_channel_t channel);
/**
* @brief Function for disabling a PPI channel.
*
* @param[in] channel PPI channel to be disabled.
*
* @retval NRFX_SUCCESS The channel was successfully disabled.
* @retval NRFX_ERROR_INVALID_STATE The user-configurable channel is not allocated.
* @retval NRFX_ERROR_INVALID_PARAM The channel cannot be disabled by the user.
*/
nrfx_err_t nrfx_ppi_channel_disable(nrf_ppi_channel_t channel);
/**
* @brief Function for allocating a PPI channel group.
* @details This function allocates the first unused PPI group.
*
* @param[out] p_group Pointer to the PPI channel group that has been allocated.
*
* @retval NRFX_SUCCESS The channel group was successfully allocated.
* @retval NRFX_ERROR_NO_MEM There is no available channel group to be used.
*/
nrfx_err_t nrfx_ppi_group_alloc(nrf_ppi_channel_group_t * p_group);
/**
* @brief Function for freeing a PPI channel group.
* @details This function also disables the chosen group.
*
* @param[in] group PPI channel group to be freed.
*
* @retval NRFX_SUCCESS The channel group was successfully freed.
* @retval NRFX_ERROR_INVALID_PARAM The channel group is not user-configurable.
*/
nrfx_err_t nrfx_ppi_group_free(nrf_ppi_channel_group_t group);
/**
* @brief Compute a channel mask for NRF_PPI registers.
*
* @param[in] channel Channel number to transform to a mask.
*
* @return Channel mask.
*/
__STATIC_INLINE uint32_t nrfx_ppi_channel_to_mask(nrf_ppi_channel_t channel)
{
return (1uL << (uint32_t) channel);
}
/**
* @brief Function for including multiple PPI channels in a channel group.
*
* @param[in] channel_mask PPI channels to be added.
* @param[in] group Channel group in which to include the channels.
*
* @retval NRFX_SUCCESS The channels was successfully included.
* @retval NRFX_ERROR_INVALID_PARAM Group is not an application group or channels are not an
* application channels.
* @retval NRFX_ERROR_INVALID_STATE Group is not an allocated group.
*/
nrfx_err_t nrfx_ppi_channels_include_in_group(uint32_t channel_mask,
nrf_ppi_channel_group_t group);
/**
* @brief Function for including a PPI channel in a channel group.
*
* @param[in] channel PPI channel to be added.
* @param[in] group Channel group in which to include the channel.
*
* @retval NRFX_SUCCESS The channel was successfully included.
* @retval NRFX_ERROR_INVALID_PARAM Group is not an application group or channel is not an
* application channel.
* @retval NRFX_ERROR_INVALID_STATE Group is not an allocated group.
*/
__STATIC_INLINE nrfx_err_t nrfx_ppi_channel_include_in_group(nrf_ppi_channel_t channel,
nrf_ppi_channel_group_t group)
{
return nrfx_ppi_channels_include_in_group(nrfx_ppi_channel_to_mask(channel), group);
}
/**
* @brief Function for removing multiple PPI channels from a channel group.
*
* @param[in] channel_mask PPI channels to be removed.
* @param[in] group Channel group from which to remove the channels.
*
* @retval NRFX_SUCCESS The channel was successfully removed.
* @retval NRFX_ERROR_INVALID_PARAM Group is not an application group or channels are not an
* application channels.
* @retval NRFX_ERROR_INVALID_STATE Group is not an allocated group.
*/
nrfx_err_t nrfx_ppi_channels_remove_from_group(uint32_t channel_mask,
nrf_ppi_channel_group_t group);
/**
* @brief Function for removing a single PPI channel from a channel group.
*
* @param[in] channel PPI channel to be removed.
* @param[in] group Channel group from which to remove the channel.
*
* @retval NRFX_SUCCESS The channel was successfully removed.
* @retval NRFX_ERROR_INVALID_PARAM Group is not an application group or channel is not an
* application channel.
* @retval NRFX_ERROR_INVALID_STATE Group is not an allocated group.
*/
__STATIC_INLINE nrfx_err_t nrfx_ppi_channel_remove_from_group(nrf_ppi_channel_t channel,
nrf_ppi_channel_group_t group)
{
return nrfx_ppi_channels_remove_from_group(nrfx_ppi_channel_to_mask(channel), group);
}
/**
* @brief Function for clearing a PPI channel group.
*
* @param[in] group Channel group to be cleared.
*
* @retval NRFX_SUCCESS The group was successfully cleared.
* @retval NRFX_ERROR_INVALID_PARAM Group is not an application group.
* @retval NRFX_ERROR_INVALID_STATE Group is not an allocated group.
*/
__STATIC_INLINE nrfx_err_t nrfx_ppi_group_clear(nrf_ppi_channel_group_t group)
{
return nrfx_ppi_channels_remove_from_group(NRFX_PPI_ALL_APP_CHANNELS_MASK, group);
}
/**
* @brief Function for enabling a PPI channel group.
*
* @param[in] group Channel group to be enabled.
*
* @retval NRFX_SUCCESS The group was successfully enabled.
* @retval NRFX_ERROR_INVALID_PARAM Group is not an application group.
* @retval NRFX_ERROR_INVALID_STATE Group is not an allocated group.
*/
nrfx_err_t nrfx_ppi_group_enable(nrf_ppi_channel_group_t group);
/**
* @brief Function for disabling a PPI channel group.
*
* @param[in] group Channel group to be disabled.
*
* @retval NRFX_SUCCESS The group was successfully disabled.
* @retval NRFX_ERROR_INVALID_PARAM Group is not an application group.
* @retval NRFX_ERROR_INVALID_STATE Group is not an allocated group.
*/
nrfx_err_t nrfx_ppi_group_disable(nrf_ppi_channel_group_t group);
/**
* @brief Function for getting the address of a PPI task.
*
* @param[in] task Task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_ppi_task_addr_get(nrf_ppi_task_t task)
{
return (uint32_t) nrf_ppi_task_address_get(task);
}
/**
* @brief Function for getting the address of the enable task of a PPI group.
*
* @param[in] group PPI channel group
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_ppi_task_addr_group_enable_get(nrf_ppi_channel_group_t group)
{
return (uint32_t) nrf_ppi_task_group_enable_address_get(group);
}
/**
* @brief Function for getting the address of the enable task of a PPI group.
*
* @param[in] group PPI channel group
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_ppi_task_addr_group_disable_get(nrf_ppi_channel_group_t group)
{
return (uint32_t) nrf_ppi_task_group_disable_address_get(group);
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_PPI_H__
+476
View File
@@ -0,0 +1,476 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_PWM_H__
#define NRFX_PWM_H__
#include <nrfx.h>
#include <hal/nrf_pwm.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_pwm PWM driver
* @{
* @ingroup nrf_pwm
* @brief Pulse Width Modulation (PWM) peripheral driver.
*/
/** @brief PWM driver instance data structure. */
typedef struct
{
NRF_PWM_Type * p_registers; ///< Pointer to the structure with PWM peripheral instance registers.
uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
} nrfx_pwm_t;
/** @brief Macro for creating a PWM driver instance. */
#define NRFX_PWM_INSTANCE(id) \
{ \
.p_registers = NRFX_CONCAT_2(NRF_PWM, id), \
.drv_inst_idx = NRFX_CONCAT_3(NRFX_PWM, id, _INST_IDX), \
}
#ifndef __NRFX_DOXYGEN__
enum {
#if NRFX_CHECK(NRFX_PWM0_ENABLED)
NRFX_PWM0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_PWM1_ENABLED)
NRFX_PWM1_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_PWM2_ENABLED)
NRFX_PWM2_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_PWM3_ENABLED)
NRFX_PWM3_INST_IDX,
#endif
NRFX_PWM_ENABLED_COUNT
};
#endif
/**
* @brief This value can be provided instead of a pin number for any channel
* to specify that its output is not used and therefore does not need
* to be connected to a pin.
*/
#define NRFX_PWM_PIN_NOT_USED 0xFF
/** @brief This value can be added to a pin number to invert its polarity (set idle state = 1). */
#define NRFX_PWM_PIN_INVERTED 0x80
/** @brief PWM driver configuration structure. */
typedef struct
{
uint8_t output_pins[NRF_PWM_CHANNEL_COUNT]; ///< Pin numbers for individual output channels (optional).
/**< Use @ref NRFX_PWM_PIN_NOT_USED
* if a given output channel is not needed. */
uint8_t irq_priority; ///< Interrupt priority.
nrf_pwm_clk_t base_clock; ///< Base clock frequency.
nrf_pwm_mode_t count_mode; ///< Operating mode of the pulse generator counter.
uint16_t top_value; ///< Value up to which the pulse generator counter counts.
nrf_pwm_dec_load_t load_mode; ///< Mode of loading sequence data from RAM.
nrf_pwm_dec_step_t step_mode; ///< Mode of advancing the active sequence.
} nrfx_pwm_config_t;
/** @brief PWM driver default configuration. */
#define NRFX_PWM_DEFAULT_CONFIG \
{ \
.output_pins = { NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN, \
NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN, \
NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN, \
NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN }, \
.irq_priority = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY, \
.base_clock = (nrf_pwm_clk_t)NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK, \
.count_mode = (nrf_pwm_mode_t)NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE, \
.top_value = NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE, \
.load_mode = (nrf_pwm_dec_load_t)NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE, \
.step_mode = (nrf_pwm_dec_step_t)NRFX_PWM_DEFAULT_CONFIG_STEP_MODE, \
}
/** @brief PWM flags that provide additional playback options. */
typedef enum
{
NRFX_PWM_FLAG_STOP = 0x01, /**< When the requested playback is finished,
the peripheral will be stopped.
@note The STOP task is triggered when
the last value of the final sequence is
loaded from RAM, and the peripheral stops
at the end of the current PWM period.
For sequences with configured repeating
of duty cycle values, this might result in
less than the requested number of repeats
of the last value. */
NRFX_PWM_FLAG_LOOP = 0x02, /**< When the requested playback is finished,
it will be started from the beginning.
This flag is ignored if used together
with @ref NRFX_PWM_FLAG_STOP.
@note The playback restart is done via a
shortcut configured in the PWM peripheral.
This shortcut triggers the proper starting
task when the final value of previous
playback is read from RAM and applied to
the pulse generator counter.
When this mechanism is used together with
the @ref NRF_PWM_STEP_TRIGGERED mode,
the playback restart will occur right
after switching to the final value (this
final value will be played only once). */
NRFX_PWM_FLAG_SIGNAL_END_SEQ0 = 0x04, /**< The event handler is to be
called when the last value
from sequence 0 is loaded. */
NRFX_PWM_FLAG_SIGNAL_END_SEQ1 = 0x08, /**< The event handler is to be
called when the last value
from sequence 1 is loaded. */
NRFX_PWM_FLAG_NO_EVT_FINISHED = 0x10, /**< The playback finished event
(enabled by default) is to be
suppressed. */
NRFX_PWM_FLAG_START_VIA_TASK = 0x80, /**< The playback must not be
started directly by the called
function. Instead, the function
must only prepare it and
return the address of the task
to be triggered to start the
playback. */
} nrfx_pwm_flag_t;
/** @brief PWM driver event type. */
typedef enum
{
NRFX_PWM_EVT_FINISHED, ///< Sequence playback finished.
NRFX_PWM_EVT_END_SEQ0, /**< End of sequence 0 reached. Its data can be
safely modified now. */
NRFX_PWM_EVT_END_SEQ1, /**< End of sequence 1 reached. Its data can be
safely modified now. */
NRFX_PWM_EVT_STOPPED, ///< The PWM peripheral has been stopped.
} nrfx_pwm_evt_type_t;
/** @brief PWM driver event handler type. */
typedef void (* nrfx_pwm_handler_t)(nrfx_pwm_evt_type_t event_type);
/**
* @brief Function for initializing the PWM driver.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] handler Event handler provided by the user. If NULL is passed
* instead, event notifications are not done and PWM
* interrupts are disabled.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver was already initialized.
*/
nrfx_err_t nrfx_pwm_init(nrfx_pwm_t const * const p_instance,
nrfx_pwm_config_t const * p_config,
nrfx_pwm_handler_t handler);
/**
* @brief Function for uninitializing the PWM driver.
*
* If any sequence playback is in progress, it is stopped immediately.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_pwm_uninit(nrfx_pwm_t const * const p_instance);
/**
* @brief Function for starting a single sequence playback.
*
* To take advantage of the looping mechanism in the PWM peripheral, both
* sequences must be used (single sequence can be played back only once by
* the peripheral). Therefore, the provided sequence is internally set and
* played back as both sequence 0 and sequence 1. Consequently, if the end of
* sequence notifications are required, events for both sequences must be
* used (that is, both the @ref NRFX_PWM_FLAG_SIGNAL_END_SEQ0 flag
* and the @ref NRFX_PWM_FLAG_SIGNAL_END_SEQ1 flag must be specified, and
* the @ref NRFX_PWM_EVT_END_SEQ0 event and the @ref NRFX_PWM_EVT_END_SEQ1
* event must be handled in the same way).
*
* Use the @ref NRFX_PWM_FLAG_START_VIA_TASK flag if you want the playback
* to be only prepared by this function, and you want to start it later by
* triggering a task (for example, by using PPI). The function will then return
* the address of the task to be triggered.
*
* @note The array containing the duty cycle values for the specified sequence
* must be in RAM and cannot be allocated on the stack.
* For detailed information, see @ref nrf_pwm_sequence_t.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_sequence Sequence to be played back.
* @param[in] playback_count Number of playbacks to be performed (must not be 0).
* @param[in] flags Additional options. Pass any combination of
* @ref nrfx_pwm_flag_t "playback flags", or 0
* for default settings.
*
* @return Address of the task to be triggered to start the playback if the @ref
* NRFX_PWM_FLAG_START_VIA_TASK flag was used, 0 otherwise.
*/
uint32_t nrfx_pwm_simple_playback(nrfx_pwm_t const * const p_instance,
nrf_pwm_sequence_t const * p_sequence,
uint16_t playback_count,
uint32_t flags);
/**
* @brief Function for starting a two-sequence playback.
*
* Use the @ref NRFX_PWM_FLAG_START_VIA_TASK flag if you want the playback
* to be only prepared by this function, and you want to start it later by
* triggering a task (using PPI for instance). The function will then return
* the address of the task to be triggered.
*
* @note The array containing the duty cycle values for the specified sequence
* must be in RAM and cannot be allocated on the stack.
* For detailed information, see @ref nrf_pwm_sequence_t.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_sequence_0 First sequence to be played back.
* @param[in] p_sequence_1 Second sequence to be played back.
* @param[in] playback_count Number of playbacks to be performed (must not be 0).
* @param[in] flags Additional options. Pass any combination of
* @ref nrfx_pwm_flag_t "playback flags", or 0
* for default settings.
*
* @return Address of the task to be triggered to start the playback if the @ref
* NRFX_PWM_FLAG_START_VIA_TASK flag was used, 0 otherwise.
*/
uint32_t nrfx_pwm_complex_playback(nrfx_pwm_t const * const p_instance,
nrf_pwm_sequence_t const * p_sequence_0,
nrf_pwm_sequence_t const * p_sequence_1,
uint16_t playback_count,
uint32_t flags);
/**
* @brief Function for advancing the active sequence.
*
* This function only applies to @ref NRF_PWM_STEP_TRIGGERED mode.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
__STATIC_INLINE void nrfx_pwm_step(nrfx_pwm_t const * const p_instance);
/**
* @brief Function for stopping the sequence playback.
*
* The playback is stopped at the end of the current PWM period.
* This means that if the active sequence is configured to repeat each duty
* cycle value for a certain number of PWM periods, the last played value
* might appear on the output less times than requested.
*
* @note This function can be instructed to wait until the playback is stopped
* (by setting @p wait_until_stopped to true). Depending on
* the length of the PMW period, this might take a significant amount of
* time. Alternatively, the @ref nrfx_pwm_is_stopped function can be
* used to poll the status, or the @ref NRFX_PWM_EVT_STOPPED event can
* be used to get the notification when the playback is stopped, provided
* the event handler is defined.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] wait_until_stopped If true, the function will not return until
* the playback is stopped.
*
* @retval true The PWM peripheral is stopped.
* @retval false The PWM peripheral is not stopped.
*/
bool nrfx_pwm_stop(nrfx_pwm_t const * const p_instance, bool wait_until_stopped);
/**
* @brief Function for checking the status of the PWM peripheral.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @retval true The PWM peripheral is stopped.
* @retval false The PWM peripheral is not stopped.
*/
bool nrfx_pwm_is_stopped(nrfx_pwm_t const * const p_instance);
/**
* @brief Function for updating the sequence data during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] p_sequence Pointer to the new sequence definition.
*/
__STATIC_INLINE void nrfx_pwm_sequence_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
nrf_pwm_sequence_t const * p_sequence);
/**
* @brief Function for updating the pointer to the duty cycle values
* in the specified sequence during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] values New pointer to the duty cycle values.
*/
__STATIC_INLINE void nrfx_pwm_sequence_values_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
nrf_pwm_values_t values);
/**
* @brief Function for updating the number of duty cycle values
* in the specified sequence during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] length New number of the duty cycle values.
*/
__STATIC_INLINE void nrfx_pwm_sequence_length_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint16_t length);
/**
* @brief Function for updating the number of repeats for duty cycle values
* in the specified sequence during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] repeats New number of repeats.
*/
__STATIC_INLINE void nrfx_pwm_sequence_repeats_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint32_t repeats);
/**
* @brief Function for updating the additional delay after the specified
* sequence during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] end_delay New end delay value (in PWM periods).
*/
__STATIC_INLINE void nrfx_pwm_sequence_end_delay_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint32_t end_delay);
/**
* @brief Function for returning the address of a specified PWM task that can
* be used in PPI module.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] task Requested task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_pwm_task_address_get(nrfx_pwm_t const * const p_instance,
nrf_pwm_task_t task);
/**
* @brief Function for returning the address of a specified PWM event that can
* be used in PPI module.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] event Requested event.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_pwm_event_address_get(nrfx_pwm_t const * const p_instance,
nrf_pwm_event_t event);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrfx_pwm_step(nrfx_pwm_t const * const p_instance)
{
nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_NEXTSTEP);
}
__STATIC_INLINE void nrfx_pwm_sequence_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
nrf_pwm_sequence_t const * p_sequence)
{
nrf_pwm_sequence_set(p_instance->p_registers, seq_id, p_sequence);
}
__STATIC_INLINE void nrfx_pwm_sequence_values_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
nrf_pwm_values_t values)
{
nrf_pwm_seq_ptr_set(p_instance->p_registers, seq_id, values.p_raw);
}
__STATIC_INLINE void nrfx_pwm_sequence_length_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint16_t length)
{
nrf_pwm_seq_cnt_set(p_instance->p_registers, seq_id, length);
}
__STATIC_INLINE void nrfx_pwm_sequence_repeats_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint32_t repeats)
{
nrf_pwm_seq_refresh_set(p_instance->p_registers, seq_id, repeats);
}
__STATIC_INLINE void nrfx_pwm_sequence_end_delay_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint32_t end_delay)
{
nrf_pwm_seq_end_delay_set(p_instance->p_registers, seq_id, end_delay);
}
__STATIC_INLINE uint32_t nrfx_pwm_task_address_get(nrfx_pwm_t const * const p_instance,
nrf_pwm_task_t task)
{
return nrf_pwm_task_address_get(p_instance->p_registers, task);
}
__STATIC_INLINE uint32_t nrfx_pwm_event_address_get(nrfx_pwm_t const * const p_instance,
nrf_pwm_event_t event)
{
return nrf_pwm_event_address_get(p_instance->p_registers, event);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
void nrfx_pwm_0_irq_handler(void);
void nrfx_pwm_1_irq_handler(void);
void nrfx_pwm_2_irq_handler(void);
void nrfx_pwm_3_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_PWM_H__
+120
View File
@@ -0,0 +1,120 @@
/**
* Copyright (c) 2016 - 2021, 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 NRFX_RNG_H__
#define NRFX_RNG_H__
#include <nrfx.h>
#include <hal/nrf_rng.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_rng RNG driver
* @{
* @ingroup nrf_rng
* @brief Random Number Generator (RNG) peripheral driver.
*/
/** @brief Struct for RNG configuration. */
typedef struct
{
bool error_correction : 1; /**< Error correction flag. */
uint8_t interrupt_priority; /**< Interrupt priority. */
} nrfx_rng_config_t;
/**
* @brief RNG default configuration.
* Basic usage:
* @code
* nrfx_rng_config_t config = NRFX_RNG_DEFAULT_CONFIG;
* if (nrfx_rng_init(&config, handler)
* { ...
* @endcode
*/
#define NRFX_RNG_DEFAULT_CONFIG \
{ \
.error_correction = NRFX_RNG_CONFIG_ERROR_CORRECTION, \
.interrupt_priority = NRFX_RNG_CONFIG_IRQ_PRIORITY, \
}
/** @brief RNG driver event handler type. */
typedef void (* nrfx_rng_evt_handler_t)(uint8_t rng_data);
/**
* @brief Function for initializing the nrfx_rng module.
*
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] handler Event handler provided by the user. Must not be NULL.
*
* @retval NRFX_SUCCESS Driver was successfully initialized.
* @retval NRFX_ERROR_ALREADY_INITIALIZED Driver was already initialized.
*/
nrfx_err_t nrfx_rng_init(nrfx_rng_config_t const * p_config, nrfx_rng_evt_handler_t handler);
/**
* @brief Function for starting the generation of random values.
*
* New data should be handled by handler passed to the @ref nrfx_rng_init() function.
*/
void nrfx_rng_start(void);
/**
* @brief Function for stopping the generation of random values.
*
* Function disables interrupts in peripheral and stops the generation of new random values.
*/
void nrfx_rng_stop(void);
/** @brief Function for uninitializing the nrfx_rng module. */
void nrfx_rng_uninit(void);
/** @} */
void nrfx_rng_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_RNG_H__
+378
View File
@@ -0,0 +1,378 @@
/**
* Copyright (c) 2014 - 2021, 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 NRFX_RTC_H__
#define NRFX_RTC_H__
#include <nrfx.h>
#include <hal/nrf_rtc.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_rtc RTC driver
* @{
* @ingroup nrf_rtc
* @brief Real Timer Counter (RTC) peripheral driver.
*/
/** @brief Macro for converting microseconds into ticks. */
#define NRFX_RTC_US_TO_TICKS(us,freq) (((us) * (freq)) / 1000000U)
/** @brief RTC driver interrupt types. */
typedef enum
{
NRFX_RTC_INT_COMPARE0 = 0, /**< Interrupt from COMPARE0 event. */
NRFX_RTC_INT_COMPARE1 = 1, /**< Interrupt from COMPARE1 event. */
NRFX_RTC_INT_COMPARE2 = 2, /**< Interrupt from COMPARE2 event. */
NRFX_RTC_INT_COMPARE3 = 3, /**< Interrupt from COMPARE3 event. */
NRFX_RTC_INT_TICK = 4, /**< Interrupt from TICK event. */
NRFX_RTC_INT_OVERFLOW = 5 /**< Interrupt from OVERFLOW event. */
} nrfx_rtc_int_type_t;
/** @brief RTC driver instance structure. */
typedef struct
{
NRF_RTC_Type * p_reg; /**< Pointer to instance register set. */
IRQn_Type irq; /**< Instance IRQ ID. */
uint8_t instance_id; /**< Index of the driver instance. For internal use only. */
uint8_t cc_channel_count; /**< Number of capture/compare channels. */
} nrfx_rtc_t;
/** @brief Macro for creating an RTC driver instance. */
#define NRFX_RTC_INSTANCE(id) \
{ \
.p_reg = NRFX_CONCAT_2(NRF_RTC, id), \
.irq = NRFX_CONCAT_3(RTC, id, _IRQn), \
.instance_id = NRFX_CONCAT_3(NRFX_RTC, id, _INST_IDX), \
.cc_channel_count = NRF_RTC_CC_CHANNEL_COUNT(id), \
}
#ifndef __NRFX_DOXYGEN__
enum {
#if NRFX_CHECK(NRFX_RTC0_ENABLED)
NRFX_RTC0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_RTC1_ENABLED)
NRFX_RTC1_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_RTC2_ENABLED)
NRFX_RTC2_INST_IDX,
#endif
NRFX_RTC_ENABLED_COUNT
};
#endif
/** @brief RTC driver instance configuration structure. */
typedef struct
{
uint16_t prescaler; /**< Prescaler. */
uint8_t interrupt_priority; /**< Interrupt priority. */
uint8_t tick_latency; /**< Maximum length of the interrupt handler in ticks (maximum 7.7 ms). */
bool reliable; /**< Reliable mode flag. */
} nrfx_rtc_config_t;
/** @brief RTC instance default configuration. */
#define NRFX_RTC_DEFAULT_CONFIG \
{ \
.prescaler = RTC_FREQ_TO_PRESCALER(NRFX_RTC_DEFAULT_CONFIG_FREQUENCY), \
.interrupt_priority = NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY, \
.tick_latency = NRFX_RTC_US_TO_TICKS(NRFX_RTC_MAXIMUM_LATENCY_US, \
NRFX_RTC_DEFAULT_CONFIG_FREQUENCY), \
.reliable = NRFX_RTC_DEFAULT_CONFIG_RELIABLE, \
}
/** @brief RTC driver instance handler type. */
typedef void (*nrfx_rtc_handler_t)(nrfx_rtc_int_type_t int_type);
/**
* @brief Function for initializing the RTC driver instance.
*
* After initialization, the instance is in power off state.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] handler Event handler provided by the user.
* Must not be NULL.
*
* @retval NRFX_SUCCESS Successfully initialized.
* @retval NRFX_ERROR_INVALID_STATE The instance is already initialized.
*/
nrfx_err_t nrfx_rtc_init(nrfx_rtc_t const * const p_instance,
nrfx_rtc_config_t const * p_config,
nrfx_rtc_handler_t handler);
/**
* @brief Function for uninitializing the RTC driver instance.
*
* After uninitialization, the instance is in idle state. The hardware should return to the state
* before initialization.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_rtc_uninit(nrfx_rtc_t const * const p_instance);
/**
* @brief Function for enabling the RTC driver instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_rtc_enable(nrfx_rtc_t const * const p_instance);
/**
* @brief Function for disabling the RTC driver instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_rtc_disable(nrfx_rtc_t const * const p_instance);
/**
* @brief Function for setting a compare channel.
*
* The function powers on the instance if the instance was in power off state.
*
* The driver is not entering a critical section when configuring RTC, which means that it can be
* preempted for a certain amount of time. When the driver was preempted and the value to be set
* is short in time, there is a risk that the driver sets a compare value that is
* behind. In this case, if the reliable mode is enabled for the specified instance,
* the risk is handled.
* However, to detect if the requested value is behind, this mode makes the following assumptions:
* - The maximum preemption time in ticks (8-bit value) is known and is less than 7.7 ms
* (for prescaler = 0, RTC frequency 32 kHz).
* - The requested absolute compare value is not bigger than (0x00FFFFFF)-tick_latency. It is
* the user's responsibility to ensure this.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] channel One of the channels of the instance.
* @param[in] val Absolute value to be set in the compare register.
* @param[in] enable_irq True to enable the interrupt. False to disable the interrupt.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_TIMEOUT The compare is not set because the request value is behind the
* current counter value. This error can only be reported
* if the reliable mode is enabled.
*/
nrfx_err_t nrfx_rtc_cc_set(nrfx_rtc_t const * const p_instance,
uint32_t channel,
uint32_t val,
bool enable_irq);
/**
* @brief Function for disabling a channel.
*
* This function disables channel events and channel interrupts.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] channel One of the channels of the instance.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_TIMEOUT Interrupt is pending on the requested channel.
*/
nrfx_err_t nrfx_rtc_cc_disable(nrfx_rtc_t const * const p_instance, uint32_t channel);
/**
* @brief Function for enabling the TICK event.
*
* This function enables the tick event and optionally the interrupt.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] enable_irq True to enable the interrupt. False to disable the interrupt.
*/
void nrfx_rtc_tick_enable(nrfx_rtc_t const * const p_instance, bool enable_irq);
/**
* @brief Function for disabling the TICK event.
*
* This function disables the TICK event and interrupt.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_rtc_tick_disable(nrfx_rtc_t const * const p_instance);
/**
* @brief Function for enabling overflow.
*
* This function enables the overflow event and optionally the interrupt.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] enable_irq True to enable the interrupt. False to disable the interrupt.
*/
void nrfx_rtc_overflow_enable(nrfx_rtc_t const * const p_instance, bool enable_irq);
/**
* @brief Function for disabling overflow.
*
* This function disables the overflow event and interrupt.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_rtc_overflow_disable(nrfx_rtc_t const * const p_instance);
/**
* @brief Function for getting the maximum relative tick value that can be set in the compare channel.
*
* When a stack (for example SoftDevice) is used and it occupies high priority interrupts,
* the application code can be interrupted at any moment for a certain period of time.
* If the reliable mode is enabled, the provided maximum latency is taken into account
* and the return value is smaller than the RTC counter resolution.
* If the reliable mode is disabled, the return value equals the counter resolution.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return Maximum ticks value.
*/
uint32_t nrfx_rtc_max_ticks_get(nrfx_rtc_t const * const p_instance);
/**
* @brief Function for disabling all instance interrupts.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_mask Pointer to the location where the mask is filled.
*/
__STATIC_INLINE void nrfx_rtc_int_disable(nrfx_rtc_t const * const p_instance,
uint32_t * p_mask);
/**
* @brief Function for enabling instance interrupts.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] mask Mask of interrupts to enable.
*/
__STATIC_INLINE void nrfx_rtc_int_enable(nrfx_rtc_t const * const p_instance, uint32_t mask);
/**
* @brief Function for retrieving the current counter value.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return Counter value.
*/
__STATIC_INLINE uint32_t nrfx_rtc_counter_get(nrfx_rtc_t const * const p_instance);
/**
* @brief Function for clearing the counter value.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
__STATIC_INLINE void nrfx_rtc_counter_clear(nrfx_rtc_t const * const p_instance);
/**
* @brief Function for returning a requested task address for the RTC driver instance.
*
* The task address can be used by the PPI module.
*
* @param[in] p_instance Pointer to the instance.
* @param[in] task One of the peripheral tasks.
*
* @return Address of task register.
*/
__STATIC_INLINE uint32_t nrfx_rtc_task_address_get(nrfx_rtc_t const * const p_instance,
nrf_rtc_task_t task);
/**
* @brief Function for returning a requested event address for the RTC driver instance.
*
* The event address can be used by the PPI module.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] event One of the peripheral events.
*
* @return Address of event register.
*/
__STATIC_INLINE uint32_t nrfx_rtc_event_address_get(nrfx_rtc_t const * const p_instance,
nrf_rtc_event_t event);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrfx_rtc_int_disable(nrfx_rtc_t const * const p_instance,
uint32_t * p_mask)
{
*p_mask = nrf_rtc_int_get(p_instance->p_reg);
nrf_rtc_int_disable(p_instance->p_reg, NRF_RTC_INT_TICK_MASK |
NRF_RTC_INT_OVERFLOW_MASK |
NRF_RTC_INT_COMPARE0_MASK |
NRF_RTC_INT_COMPARE1_MASK |
NRF_RTC_INT_COMPARE2_MASK |
NRF_RTC_INT_COMPARE3_MASK);
}
__STATIC_INLINE void nrfx_rtc_int_enable(nrfx_rtc_t const * const p_instance, uint32_t mask)
{
nrf_rtc_int_enable(p_instance->p_reg, mask);
}
__STATIC_INLINE uint32_t nrfx_rtc_counter_get(nrfx_rtc_t const * const p_instance)
{
return nrf_rtc_counter_get(p_instance->p_reg);
}
__STATIC_INLINE void nrfx_rtc_counter_clear(nrfx_rtc_t const * const p_instance)
{
nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_CLEAR);
}
__STATIC_INLINE uint32_t nrfx_rtc_task_address_get(nrfx_rtc_t const * const p_instance,
nrf_rtc_task_t task)
{
return nrf_rtc_task_address_get(p_instance->p_reg, task);
}
__STATIC_INLINE uint32_t nrfx_rtc_event_address_get(nrfx_rtc_t const * const p_instance,
nrf_rtc_event_t event)
{
return nrf_rtc_event_address_get(p_instance->p_reg, event);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
void nrfx_rtc_0_irq_handler(void);
void nrfx_rtc_1_irq_handler(void);
void nrfx_rtc_2_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_RTC_H__
+322
View File
@@ -0,0 +1,322 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_SAADC_H__
#define NRFX_SAADC_H__
#include <nrfx.h>
#include <hal/nrf_saadc.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(NRFX_SAADC_API_V2)
#include "nrfx_saadc_v2.h"
#else
/**
* @defgroup nrfx_saadc SAADC legacy driver
* @{
* @ingroup nrf_saadc
* @brief Successive Approximation Analog-to-Digital Converter (SAADC) peripheral legacy driver.
*/
/** @brief Value to be set as high limit to disable limit detection. */
#define NRFX_SAADC_LIMITH_DISABLED (2047)
/** @brief Value to be set as low limit to disable limit detection. */
#define NRFX_SAADC_LIMITL_DISABLED (-2048)
/** @brief Macro for setting @ref nrfx_saadc_config_t to default settings. */
#define NRFX_SAADC_DEFAULT_CONFIG \
{ \
.resolution = (nrf_saadc_resolution_t)NRFX_SAADC_CONFIG_RESOLUTION, \
.oversample = (nrf_saadc_oversample_t)NRFX_SAADC_CONFIG_OVERSAMPLE, \
.interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY, \
.low_power_mode = NRFX_SAADC_CONFIG_LP_MODE \
}
/**
* @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings
* in single-ended mode.
*
* @param PIN_P Analog input.
*/
#define NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \
{ \
.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \
.resistor_n = NRF_SAADC_RESISTOR_DISABLED, \
.gain = NRF_SAADC_GAIN1_6, \
.reference = NRF_SAADC_REFERENCE_INTERNAL, \
.acq_time = NRF_SAADC_ACQTIME_10US, \
.mode = NRF_SAADC_MODE_SINGLE_ENDED, \
.burst = NRF_SAADC_BURST_DISABLED, \
.pin_p = (nrf_saadc_input_t)(PIN_P), \
.pin_n = NRF_SAADC_INPUT_DISABLED \
}
/**
* @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings
* in differential mode.
*
* @param PIN_P Positive analog input.
* @param PIN_N Negative analog input.
*/
#define NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(PIN_P, PIN_N) \
{ \
.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \
.resistor_n = NRF_SAADC_RESISTOR_DISABLED, \
.gain = NRF_SAADC_GAIN1_6, \
.reference = NRF_SAADC_REFERENCE_INTERNAL, \
.acq_time = NRF_SAADC_ACQTIME_10US, \
.mode = NRF_SAADC_MODE_DIFFERENTIAL, \
.burst = NRF_SAADC_BURST_DISABLED, \
.pin_p = (nrf_saadc_input_t)(PIN_P), \
.pin_n = (nrf_saadc_input_t)(PIN_N) \
}
/** @brief SAADC driver configuration structure. */
typedef struct
{
nrf_saadc_resolution_t resolution; ///< Resolution configuration.
nrf_saadc_oversample_t oversample; ///< Oversampling configuration.
uint8_t interrupt_priority; ///< Interrupt priority.
bool low_power_mode; ///< Indicates if low power mode is active.
} nrfx_saadc_config_t;
/** @brief SAADC driver event types. */
typedef enum
{
NRFX_SAADC_EVT_DONE, ///< Event generated when the buffer is filled with samples.
NRFX_SAADC_EVT_LIMIT, ///< Event generated after one of the limits is reached.
NRFX_SAADC_EVT_CALIBRATEDONE ///< Event generated when the calibration is complete.
} nrfx_saadc_evt_type_t;
/** @brief SAADC driver done event data. */
typedef struct
{
nrf_saadc_value_t * p_buffer; ///< Pointer to buffer with converted samples.
uint16_t size; ///< Number of samples in the buffer.
} nrfx_saadc_done_evt_t;
/** @brief SAADC driver limit event data. */
typedef struct
{
uint8_t channel; ///< Channel on which the limit was detected.
nrf_saadc_limit_t limit_type; ///< Type of limit detected.
} nrfx_saadc_limit_evt_t;
/** @brief SAADC driver event structure. */
typedef struct
{
nrfx_saadc_evt_type_t type; ///< Event type.
union
{
nrfx_saadc_done_evt_t done; ///< Data for @ref NRFX_SAADC_EVT_DONE event.
nrfx_saadc_limit_evt_t limit; ///< Data for @ref NRFX_SAADC_EVT_LIMIT event.
} data; ///< Union to store event data.
} nrfx_saadc_evt_t;
/**
* @brief SAADC driver event handler.
*
* @param[in] p_event Pointer to an SAADC driver event. The event structure is allocated on
* the stack, so it is valid only within the context of the event handler.
*/
typedef void (* nrfx_saadc_event_handler_t)(nrfx_saadc_evt_t const * p_event);
/**
* @brief Function for initializing the SAADC.
*
* @param[in] p_config Pointer to the structure with initial configuration.
* @param[in] event_handler Event handler provided by the user.
* Must not be NULL.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver is already initialized.
*/
nrfx_err_t nrfx_saadc_init(nrfx_saadc_config_t const * p_config,
nrfx_saadc_event_handler_t event_handler);
/**
* @brief Function for uninitializing the SAADC.
*
* This function stops all ongoing conversions and disables all channels.
*/
void nrfx_saadc_uninit(void);
/**
* @brief Function for getting the address of a SAMPLE SAADC task.
*
* @return Task address.
*/
uint32_t nrfx_saadc_sample_task_get(void);
/**
* @brief Function for initializing an SAADC channel.
*
* This function configures and enables the channel.
*
* @param[in] channel Channel index.
* @param[in] p_config Pointer to the structure with the initial configuration.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The SAADC was not initialized.
* @retval NRFX_ERROR_NO_MEM The specified channel was already allocated.
*/
nrfx_err_t nrfx_saadc_channel_init(uint8_t channel,
nrf_saadc_channel_config_t const * const p_config);
/**
* @brief Function for uninitializing an SAADC channel.
*
* @param[in] channel Channel index.
*
* @retval NRFX_SUCCESS Uninitialization was successful.
* @retval NRFX_ERROR_BUSY The SAADC is busy.
*/
nrfx_err_t nrfx_saadc_channel_uninit(uint8_t channel);
/**
* @brief Function for starting the SAADC sampling.
*
* @retval NRFX_SUCCESS The SAADC sampling was triggered.
* @retval NRFX_ERROR_INVALID_STATE The SAADC is in idle state.
*/
nrfx_err_t nrfx_saadc_sample(void);
/**
* @brief Blocking function for executing a single SAADC conversion.
*
* This function selects the desired input, starts a single conversion,
* waits for it to finish, and returns the result.
*
* The function fails if the SAADC is busy.
*
* @param[in] channel Channel.
* @param[out] p_value Pointer to the location where the result is to be placed.
*
* @retval NRFX_SUCCESS The conversion was successful.
* @retval NRFX_ERROR_BUSY The SAADC driver is busy.
*/
nrfx_err_t nrfx_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value);
/**
* @brief Function for issuing conversion of data to the buffer.
*
* This function is non-blocking. The application is notified about filling the buffer by the event
* handler. Conversion will be done on all enabled channels. If the SAADC is in idle state, the
* function will set up EasyDMA for the conversion. The SAADC will be ready for sampling and wait
* for the SAMPLE task. It can be triggered manually by the @ref nrfx_saadc_sample function
* or by PPI using the @ref NRF_SAADC_TASK_SAMPLE task. If one buffer is already set and the
* conversion is ongoing, calling this function will result in queuing the given buffer.
* The driver will start filling the issued buffer when the first one is completed.
* If the function is called again before the first buffer is filled or calibration
* is in progress, it will return with error.
*
* @param[in] buffer Result buffer.
* @param[in] size Buffer size in words.
*
* @retval NRFX_SUCCESS The conversion was successful.
* @retval NRFX_ERROR_BUSY The driver already has two buffers set or the calibration is in progress.
*/
nrfx_err_t nrfx_saadc_buffer_convert(nrf_saadc_value_t * buffer, uint16_t size);
/**
* @brief Function for triggering the SAADC offset calibration.
*
* This function is non-blocking. The application is notified about completion by the event handler.
* Calibration will also trigger DONE and RESULTDONE events.
*
* The function will fail if the SAADC is busy or calibration is already in progress.
*
* @retval NRFX_SUCCESS The calibration was started successfully.
* @retval NRFX_ERROR_BUSY The SAADC driver is busy.
*/
nrfx_err_t nrfx_saadc_calibrate_offset(void);
/**
* @brief Function for retrieving the SAADC state.
*
* @retval true The SAADC is busy.
* @retval false The SAADC is ready.
*/
bool nrfx_saadc_is_busy(void);
/**
* @brief Function for aborting the ongoing and buffered conversions.
*
* @note @ref NRFX_SAADC_EVT_DONE event will be generated if there is a conversion in progress.
* Event will contain number of words in the sample buffer.
*
* @warning This function must not be called from the context of event handler of the SAADC driver
* or from the context of interrupt with priority equal to or higher than priority
* of the SAADC interrupt.
*/
void nrfx_saadc_abort(void);
/**
* @brief Function for setting the SAADC channel limits.
* When limits are enabled and the result exceeds the defined bounds, the limit handler
* function is called.
*
* @param[in] channel SAADC channel number.
* @param[in] limit_low Lower limit (valid values from @ref NRFX_SAADC_LIMITL_DISABLED to
* @ref NRFX_SAADC_LIMITH_DISABLED). Conversion results below this value will
* trigger the handler function. Set to @ref NRFX_SAADC_LIMITL_DISABLED
* to disable this limit.
* @param[in] limit_high Upper limit (valid values from @ref NRFX_SAADC_LIMITL_DISABLED to
* @ref NRFX_SAADC_LIMITH_DISABLED). Conversion results above this value will
* trigger the handler function. Set to @ref NRFX_SAADC_LIMITH_DISABLED
* to disable this limit.
*/
void nrfx_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high);
/** @} */
#endif // defined(NRFX_SAADC_API_V2)
void nrfx_saadc_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_SAADC_H__
@@ -0,0 +1,382 @@
/**
* Copyright (c) 2019 - 2021, 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 NRFX_SAADC_V2_H__
#define NRFX_SAADC_V2_H__
#ifndef NRFX_SAADC_H__
#error "This file should not be included directly. Include nrfx_saadc.h instead."
#endif
/**
* @defgroup nrfx_saadc_v2 SAADC v2 driver
* @{
* @ingroup nrf_saadc
* @brief Successive Approximation Analog-to-Digital Converter (SAADC) peripheral v2 driver.
* @details API description can be found <a href="../../drivers/include/nrfx_saadc_v2.h">here</a>.
* @}
*/
/**
* @brief SAADC channel default configuration for the single-ended mode.
*
* This configuration sets up single-ended SAADC channel with the following options:
* - resistor ladder disabled
* - gain: 1/6
* - reference voltage: internal 0.6 V
* - sample acquisition time: 10 us
* - burst disabled
*
* @param[in] _pin_p Positive input analog pin.
* @param[in] _index Channel index.
*
* @sa nrfx_saadc_channel_t
*/
#define NRFX_SAADC_DEFAULT_CHANNEL_SE(_pin_p, _index) \
{ \
.channel_config = \
{ \
.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \
.resistor_n = NRF_SAADC_RESISTOR_DISABLED, \
.gain = NRF_SAADC_GAIN1_6, \
.reference = NRF_SAADC_REFERENCE_INTERNAL, \
.acq_time = NRF_SAADC_ACQTIME_10US, \
.mode = NRF_SAADC_MODE_SINGLE_ENDED, \
.burst = NRF_SAADC_BURST_DISABLED, \
}, \
.pin_p = (nrf_saadc_input_t)_pin_p, \
.pin_n = NRF_SAADC_INPUT_DISABLED, \
.channel_index = _index, \
}
/**
* @brief SAADC channel default configuration for the differential mode.
*
* This configuration sets up differential SAADC channel with the following options:
* - resistor ladder disabled
* - gain: 1/6
* - reference voltage: internal 0.6 V
* - sample acquisition time: 10 us
* - burst disabled
*
* @param[in] _pin_p Positive input analog pin.
* @param[in] _pin_n Negative input analog pin.
* @param[in] _index Channel index.
*
* @sa nrfx_saadc_channel_t
*/
#define NRFX_SAADC_DEFAULT_CHANNEL_DIFFERENTIAL(_pin_p, _pin_n, _index) \
{ \
.channel_config = \
{ \
.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \
.resistor_n = NRF_SAADC_RESISTOR_DISABLED, \
.gain = NRF_SAADC_GAIN1_6, \
.reference = NRF_SAADC_REFERENCE_INTERNAL, \
.acq_time = NRF_SAADC_ACQTIME_10US, \
.mode = NRF_SAADC_MODE_DIFFERENTIAL, \
.burst = NRF_SAADC_BURST_DISABLED, \
}, \
.pin_p = (nrf_saadc_input_t)_pin_p, \
.pin_n = (nrf_saadc_input_t)_pin_n, \
.channel_index = _index, \
}
/**
* @brief SAADC driver advanced mode default configuration.
*
* This configuration sets up advanced mode of the SAADC driver with the following options:
* - oversampling disabled
* - burst disabled
* - internal sampling timer disabled
* - triggering of the START task on the END event disabled
*
* @param[in] _pin_p Positive input analog pin.
* @param[in] _pin_n Negative input analog pin.
* @param[in] _index Channel index.
*
* @sa nrfx_saadc_adv_config_t
*/
#define NRFX_SAADC_DEFAULT_ADV_CONFIG \
{ \
.oversampling = NRF_SAADC_OVERSAMPLE_DISABLED, \
.burst = NRF_SAADC_BURST_DISABLED, \
.internal_timer_cc = 0, \
.start_on_end = false, \
}
/** @brief SAADC channel configuration structure. */
typedef struct
{
nrf_saadc_channel_config_t channel_config; ///< Channel hardware configuration.
nrf_saadc_input_t pin_p; ///< Input positive pin selection.
nrf_saadc_input_t pin_n; ///< Input negative pin selection.
uint8_t channel_index; ///< Channel index.
} nrfx_saadc_channel_t;
/** @brief SAADC driver advanced mode configuration structure. */
typedef struct
{
nrf_saadc_oversample_t oversampling; ///< Oversampling configuration.
nrf_saadc_burst_t burst; ///< Burst configuration.
uint16_t internal_timer_cc; ///< Internal timer capture and compare value.
bool start_on_end; ///< Flag indicating if the START task is to be triggered on the END event.
} nrfx_saadc_adv_config_t;
/** @brief SAADC driver event types. */
typedef enum
{
NRFX_SAADC_EVT_DONE, ///< Event generated when the buffer is filled with samples.
NRFX_SAADC_EVT_LIMIT, ///< Event generated when one of the limits is reached.
NRFX_SAADC_EVT_CALIBRATEDONE, ///< Event generated when the calibration is complete.
NRFX_SAADC_EVT_BUF_REQ, ///< Event generated when the next buffer for continuous conversion is requested.
NRFX_SAADC_EVT_READY, ///< Event generated when the first buffer is acquired by the peripheral and sampling can be started.
NRFX_SAADC_EVT_FINISHED, ///< Event generated when all supplied buffers are filled with results.
} nrfx_saadc_evt_type_t;
/** @brief SAADC driver done event data. */
typedef struct
{
nrf_saadc_value_t * p_buffer; ///< Pointer to the buffer with converted samples.
uint16_t size; ///< Number of samples in the buffer.
} nrfx_saadc_done_evt_t;
/** @brief SAADC driver limit event data. */
typedef struct
{
uint8_t channel; ///< Channel on which the limit was detected.
nrf_saadc_limit_t limit_type; ///< Type of limit detected.
} nrfx_saadc_limit_evt_t;
/** @brief SAADC driver event structure. */
typedef struct
{
nrfx_saadc_evt_type_t type; ///< Event type.
union
{
nrfx_saadc_done_evt_t done; ///< Data for @ref NRFX_SAADC_EVT_DONE event.
nrfx_saadc_limit_evt_t limit; ///< Data for @ref NRFX_SAADC_EVT_LIMIT event.
} data; ///< Union to store event data.
} nrfx_saadc_evt_t;
/**
* @brief SAADC driver event handler.
*
* When operating in the advanced mode:
* - when the sampling is performed by the external timer, the external timer can be safely started
* on @ref NRFX_SAADC_EVT_READY and stopped on @ref NRFX_SAADC_EVT_FINISHED.
* - call the @ref nrfx_saadc_buffer_set() on @ref NRFX_SAADC_EVT_BUF_REQ to achieve the continuous conversion.
*
* @param[in] p_event Pointer to an SAADC driver event. The event structure is allocated on
* the stack, so it is valid only within the context of the event handler.
*/
typedef void (* nrfx_saadc_event_handler_t)(nrfx_saadc_evt_t const * p_event);
/**
* @brief Function for initializing the SAADC driver.
*
* @param[in] interrupt_priority Interrupt priority.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver is already initialized.
*/
nrfx_err_t nrfx_saadc_init(uint8_t interrupt_priority);
/**
* @brief Function for uninitializing the SAADC driver.
*
* This function stops all ongoing conversions and disables all channels.
*/
void nrfx_saadc_uninit(void);
/**
* @brief Function for configuring the SAADC channels.
*
* @note The values of the @ref nrf_saadc_channel_config_t.burst fields in channel configurations
* are ignored. They will be overridden with the value suitable for the selected driver
* operation mode.
* @note The desired mode (simple or advanced) must be set after the channels are configured.
*
* @param[in] p_channels Pointer to the array of channel configuration structures.
* @param[in] channel_count Number of channels to be configured.
*
* @retval NRFX_SUCCESS Configuration was successful.
* @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing.
* @retval NRFX_ERROR_INVALID_PARAM Attempt to configure the same channel more than once.
*/
nrfx_err_t nrfx_saadc_channels_config(nrfx_saadc_channel_t const * p_channels,
uint32_t channel_count);
/**
* @brief Function for setting the SAADC driver in the simple mode.
*
* The simple mode allows obtaining a single sample from each requested channel.
* The conversion can be done in a blocking or non-blocking manner.
* Sampling is initiated by calling @ref nrfx_saadc_mode_trigger() once.
*
* @param[in] channel_mask Bitmask of channels to be used in the simple mode.
* @param[in] resolution Resolution configuration.
* @param[in] oversampling Oversampling configuration.
* @param[in] event_handler Event handler provided by the user. In case of providing NULL,
* the conversion will be performed in the blocking manner.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing.
* @retval NRFX_ERROR_INVALID_PARAM Attempt to activate channel that is not configured.
*/
nrfx_err_t nrfx_saadc_simple_mode_set(uint32_t channel_mask,
nrf_saadc_resolution_t resolution,
nrf_saadc_oversample_t oversampling,
nrfx_saadc_event_handler_t event_handler);
/**
* @brief Function for setting the SAADC driver in the advanced mode.
*
* The advanced mode allows performing double-buffered conversions of arbitrary length.
* The conversions can be done in a blocking or non-blocking manner. When performing conversions
* in the non-blocking manner and @ref nrfx_saadc_adv_config_t.internal_timer_cc is set to 0,
* sampling needs to be done by triggering @ref NRF_SAADC_TASK_SAMPLE externally
* (for example by using the TIMER and/or the PPI/DPPI).
* When performing conversions in the non-blocking manner and @ref nrfx_saadc_adv_config_t.start_on_end
* is false, the @ref NRF_SAADC_TASK_START needs to be triggered on @ref NRF_SAADC_EVENT_END
* externally (for example by using the PPI/DPPI).
* Sampling is initiated by calling @ref nrfx_saadc_mode_trigger(). In case of performing
* conversions in the blocking manner, @ref nrfx_saadc_mode_trigger() may need to be called several
* times as each call sample each requested channel once.
*
* @note The internal timer can only be used when a single input channel is enabled.
* @note The internal timer can only be used in the non-blocking mode.
*
* @param[in] channel_mask Bitmask of channels to be used in the advanced mode.
* @param[in] resolution Resolution configuration.
* @param[in] p_config Pointer to the structure with the advanced mode configuration.
* @param[in] event_handler Event handler provided by the user. In case of providing NULL,
* the conversion will be performed in the blocking manner.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing.
* @retval NRFX_ERROR_INVALID_PARAM Attempt to activate channel that is not configured.
* @retval NRFX_ERROR_NOT_SUPPORTED Attempt to activate internal timer or oversampling without burst
* with multiple channels enabled.
*/
nrfx_err_t nrfx_saadc_advanced_mode_set(uint32_t channel_mask,
nrf_saadc_resolution_t resolution,
nrfx_saadc_adv_config_t const * p_config,
nrfx_saadc_event_handler_t event_handler);
/**
* @brief Function for supplying the buffer to be used in the next part of
* the conversion.
*
* @param[in] p_buffer Pointer to the buffer to be filled with conversion results.
* @param[in] size Number of @ref nrf_saadc_value_t samples in buffer.
*
* @retval NRFX_SUCCESS Buffer was supplied successfully.
* @retval NRFX_ERROR_INVALID_ADDR The provided buffer is not in the Data RAM region.
* @retval NRFX_ERROR_INVALID_LENGTH The provided buffer is not aligned to the number of activated channels
* or is too long for the EasyDMA to handle.
* @retval NRFX_ERROR_INVALID_STATE The driver is in the idle mode.
* @retval NRFX_ERROR_ALREADY_INITIALIZED Both buffers for double-buffered conversions are already set.
*/
nrfx_err_t nrfx_saadc_buffer_set(nrf_saadc_value_t * p_buffer, uint16_t size);
/**
* @brief Function for triggering the conversion in the configured mode.
*
* @retval NRFX_SUCCESS Operation finished successfully in the blocking manner or started
* successfully in the non-blocking manner.
* @retval NRFX_ERROR_BUSY The driver is performing the conversion in the advanced blocking mode.
* Call the function again to continue the conversion.
* @retval NRFX_ERROR_NO_MEM There is no buffer provided.
* Supply the buffer using @ref nrfx_saadc_buffer_set() and try again.
* @retval NRFX_ERROR_INVALID_STATE There is an ongoing conversion being performed in the non-blocking manner
* or the driver is in the idle mode.
*/
nrfx_err_t nrfx_saadc_mode_trigger(void);
/**
* @brief Function for aborting the ongoing and buffered conversions.
*
* @note @ref NRFX_SAADC_EVT_DONE event will be generated if there is a conversion in progress.
* Event will contain number of words in the sample buffer.
*/
void nrfx_saadc_abort(void);
/**
* @brief Function for setting the SAADC channel limits.
*
* When limits are enabled and the conversion result exceeds the defined bounds,
* the handler function is called with the corresponding event as parameter.
*
* @note Before the limits are set, the driver operation mode (simple or advanced) has
* to be configured. Only non-blocking conversions can be monitored.
*
* @note Changing of the driver operation mode disables all configured limits.
*
* @param[in] channel Channel index.
* @param[in] limit_low Limit low value to generate interrupt. Use @c INT16_MIN
* to disable interrupt generation.
* @param[in] limit_high Limit high value to generate interrupt. Use @c INT16_MAX
* to disable interrupt generation.
*
* @retval NRFX_SUCCESS Requested channel limits were set.
* @retval NRFX_ERROR_INVALID_PARAM Attempt to activate the limits on disabled channel.
* @retval NRFX_ERROR_FORBIDDEN Attempt to activate the limits for blocking conversions.
* @retval NRFX_ERROR_INVALID_STATE Attempt to activate the limits without configured mode.
*/
nrfx_err_t nrfx_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high);
/**
* @brief Function for starting the SAADC offset calibration.
*
* @note This function cancels the currently selected driver operation mode, if any.
* The desired mode (simple or advanced) must be set after the calibration process completes.
*
* @param[in] event_handler Event handler provided by the user. In case of providing NULL,
* the calibration will be performed in the blocking manner.
*
* @retval NRFX_SUCCESS Calibration finished successfully in the blocking manner
* or started successfully in the non-blocking manner.
* @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing.
*/
nrfx_err_t nrfx_saadc_offset_calibrate(nrfx_saadc_event_handler_t event_handler);
#endif // NRFX_SAADC_V2_H__
+255
View File
@@ -0,0 +1,255 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_SPI_H__
#define NRFX_SPI_H__
#include <nrfx.h>
#include <hal/nrf_spi.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_spi SPI driver
* @{
* @ingroup nrf_spi
* @brief Serial Peripheral Interface master (SPI) driver.
*/
/** @brief Data structure of the Serial Peripheral Interface master (SPI) driver instance. */
typedef struct
{
NRF_SPI_Type * p_reg; ///< Pointer to a structure with SPI registers.
uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
} nrfx_spi_t;
enum {
#if NRFX_CHECK(NRFX_SPI0_ENABLED)
NRFX_SPI0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_SPI1_ENABLED)
NRFX_SPI1_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_SPI2_ENABLED)
NRFX_SPI2_INST_IDX,
#endif
NRFX_SPI_ENABLED_COUNT
};
/** @brief Macro for creating an instance of the SPI master driver. */
#define NRFX_SPI_INSTANCE(id) \
{ \
.p_reg = NRFX_CONCAT_2(NRF_SPI, id), \
.drv_inst_idx = NRFX_CONCAT_3(NRFX_SPI, id, _INST_IDX), \
}
/**
* @brief This value can be provided instead of a pin number for signals MOSI,
* MISO, and Slave Select to specify that the given signal is not used and
* therefore does not need to be connected to a pin.
*/
#define NRFX_SPI_PIN_NOT_USED 0xFF
/** @brief Configuration structure of the SPI master driver instance. */
typedef struct
{
uint8_t sck_pin; ///< SCK pin number.
uint8_t mosi_pin; ///< MOSI pin number (optional).
/**< Set to @ref NRFX_SPI_PIN_NOT_USED
* if this signal is not needed. */
uint8_t miso_pin; ///< MISO pin number (optional).
/**< Set to @ref NRFX_SPI_PIN_NOT_USED
* if this signal is not needed. */
uint8_t ss_pin; ///< Slave Select pin number (optional).
/**< Set to @ref NRFX_SPI_PIN_NOT_USED
* if this signal is not needed. The driver
* supports only active low for this signal.
* If the signal must be active high,
* it must be controlled externally. */
uint8_t irq_priority; ///< Interrupt priority.
uint8_t orc; ///< Overrun character.
/**< This character is used when all bytes from the TX buffer are sent,
but the transfer continues due to RX. */
nrf_spi_frequency_t frequency; ///< SPI frequency.
nrf_spi_mode_t mode; ///< SPI mode.
nrf_spi_bit_order_t bit_order; ///< SPI bit order.
} nrfx_spi_config_t;
/** @brief SPI master instance default configuration. */
#define NRFX_SPI_DEFAULT_CONFIG \
{ \
.sck_pin = NRFX_SPI_PIN_NOT_USED, \
.mosi_pin = NRFX_SPI_PIN_NOT_USED, \
.miso_pin = NRFX_SPI_PIN_NOT_USED, \
.ss_pin = NRFX_SPI_PIN_NOT_USED, \
.irq_priority = NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \
.orc = 0xFF, \
.frequency = NRF_SPI_FREQ_4M, \
.mode = NRF_SPI_MODE_0, \
.bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST, \
}
/** @brief Single transfer descriptor structure. */
typedef struct
{
uint8_t const * p_tx_buffer; ///< Pointer to TX buffer.
size_t tx_length; ///< TX buffer length.
uint8_t * p_rx_buffer; ///< Pointer to RX buffer.
size_t rx_length; ///< RX buffer length.
}nrfx_spi_xfer_desc_t;
/**
* @brief Macro for setting up single transfer descriptor.
*
* This macro is for internal use only.
*/
#define NRFX_SPI_SINGLE_XFER(p_tx, tx_len, p_rx, rx_len) \
{ \
.p_tx_buffer = (uint8_t const *)(p_tx), \
.tx_length = (tx_len), \
.p_rx_buffer = (p_rx), \
.rx_length = (rx_len), \
}
/** @brief Macro for setting the duplex TX RX transfer. */
#define NRFX_SPI_XFER_TRX(p_tx_buf, tx_length, p_rx_buf, rx_length) \
NRFX_SPI_SINGLE_XFER(p_tx_buf, tx_length, p_rx_buf, rx_length)
/** @brief Macro for setting the TX transfer. */
#define NRFX_SPI_XFER_TX(p_buf, length) \
NRFX_SPI_SINGLE_XFER(p_buf, length, NULL, 0)
/** @brief Macro for setting the RX transfer. */
#define NRFX_SPI_XFER_RX(p_buf, length) \
NRFX_SPI_SINGLE_XFER(NULL, 0, p_buf, length)
/**
* @brief SPI master driver event types, passed to the handler routine provided
* during initialization.
*/
typedef enum
{
NRFX_SPI_EVENT_DONE, ///< Transfer done.
} nrfx_spi_evt_type_t;
/** @brief SPI master event description with transmission details. */
typedef struct
{
nrfx_spi_evt_type_t type; ///< Event type.
nrfx_spi_xfer_desc_t xfer_desc; ///< Transfer details.
} nrfx_spi_evt_t;
/** @brief SPI master driver event handler type. */
typedef void (* nrfx_spi_evt_handler_t)(nrfx_spi_evt_t const * p_event,
void * p_context);
/**
* @brief Function for initializing the SPI master driver instance.
*
* This function configures and enables the specified peripheral.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] handler Event handler provided by the user. If NULL, transfers
* will be performed in blocking mode.
* @param[in] p_context Context passed to the event handler.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver was already initialized.
* @retval NRFX_ERROR_BUSY Some other peripheral with the same
* instance ID is already in use. This is
* possible only if @ref nrfx_prs module
* is enabled.
*/
nrfx_err_t nrfx_spi_init(nrfx_spi_t const * const p_instance,
nrfx_spi_config_t const * p_config,
nrfx_spi_evt_handler_t handler,
void * p_context);
/**
* @brief Function for uninitializing the SPI master driver instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_spi_uninit(nrfx_spi_t const * const p_instance);
/**
* @brief Function for starting the SPI data transfer.
*
* If an event handler was provided in the @ref nrfx_spi_init call, this function
* returns immediately and the handler is called when the transfer is done.
* Otherwise, the transfer is performed in blocking mode, which means that this function
* returns when the transfer is finished.
*
* @param p_instance Pointer to the driver instance structure.
* @param p_xfer_desc Pointer to the transfer descriptor.
* @param flags Transfer options (0 for default settings).
* Currently, no additional flags are available.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_NOT_SUPPORTED The provided parameters are not supported.
*/
nrfx_err_t nrfx_spi_xfer(nrfx_spi_t const * const p_instance,
nrfx_spi_xfer_desc_t const * p_xfer_desc,
uint32_t flags);
/**
* @brief Function for aborting the ongoing transfer.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_spi_abort(nrfx_spi_t const * p_instance);
/** @} */
void nrfx_spi_0_irq_handler(void);
void nrfx_spi_1_irq_handler(void);
void nrfx_spi_2_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_SPI_H__
+385
View File
@@ -0,0 +1,385 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_SPIM_H__
#define NRFX_SPIM_H__
#include <nrfx.h>
#include <hal/nrf_spim.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_spim SPIM driver
* @{
* @ingroup nrf_spim
* @brief Serial Peripheral Interface Master with EasyDMA (SPIM) driver.
*/
/** @brief Data structure of the Serial Peripheral Interface Master with EasyDMA (SPIM) driver instance. */
typedef struct
{
NRF_SPIM_Type * p_reg; ///< Pointer to a structure with SPIM registers.
uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
} nrfx_spim_t;
#ifndef __NRFX_DOXYGEN__
enum {
#if NRFX_CHECK(NRFX_SPIM0_ENABLED)
NRFX_SPIM0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_SPIM1_ENABLED)
NRFX_SPIM1_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_SPIM2_ENABLED)
NRFX_SPIM2_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_SPIM3_ENABLED)
NRFX_SPIM3_INST_IDX,
#endif
NRFX_SPIM_ENABLED_COUNT
};
#endif
/** @brief Macro for creating an instance of the SPIM driver. */
#define NRFX_SPIM_INSTANCE(id) \
{ \
.p_reg = NRFX_CONCAT_2(NRF_SPIM, id), \
.drv_inst_idx = NRFX_CONCAT_3(NRFX_SPIM, id, _INST_IDX), \
}
/**
* @brief This value can be provided instead of a pin number for signals MOSI,
* MISO, and Slave Select to specify that the given signal is not used and
* therefore does not need to be connected to a pin.
*/
#define NRFX_SPIM_PIN_NOT_USED 0xFF
/** @brief Configuration structure of the SPIM driver instance. */
typedef struct
{
uint8_t sck_pin; ///< SCK pin number.
uint8_t mosi_pin; ///< MOSI pin number (optional).
/**< Set to @ref NRFX_SPIM_PIN_NOT_USED
* if this signal is not needed. */
uint8_t miso_pin; ///< MISO pin number (optional).
/**< Set to @ref NRFX_SPIM_PIN_NOT_USED
* if this signal is not needed. */
uint8_t ss_pin; ///< Slave Select pin number (optional).
/**< Set to @ref NRFX_SPIM_PIN_NOT_USED
* if this signal is not needed. */
bool ss_active_high; ///< Polarity of the Slave Select pin during transmission.
uint8_t irq_priority; ///< Interrupt priority.
uint8_t orc; ///< Overrun character.
/**< This character is used when all bytes from the TX buffer are sent,
but the transfer continues due to RX. */
nrf_spim_frequency_t frequency; ///< SPIM frequency.
nrf_spim_mode_t mode; ///< SPIM mode.
nrf_spim_bit_order_t bit_order; ///< SPIM bit order.
#if NRFX_CHECK(NRFX_SPIM_EXTENDED_ENABLED) || defined(__NRFX_DOXYGEN__)
uint8_t dcx_pin; ///< D/CX pin number (optional).
uint8_t rx_delay; ///< Sample delay for input serial data on MISO.
/**< The value specifies the delay, in number of 64 MHz clock cycles
* (15.625 ns), from the the sampling edge of SCK (leading edge for
* CONFIG.CPHA = 0, trailing edge for CONFIG.CPHA = 1) until
* the input serial data is sampled. */
bool use_hw_ss; ///< Indication to use software or hardware controlled Slave Select pin.
uint8_t ss_duration; ///< Slave Select duration before and after transmission.
/**< Minimum duration between the edge of CSN and the edge of SCK and minimum
* duration of CSN must stay inactive between transactions.
* The value is specified in number of 64 MHz clock cycles (15.625 ns).
* Supported only for hardware-controlled Slave Select. */
#endif
} nrfx_spim_config_t;
#if NRFX_CHECK(NRFX_SPIM_EXTENDED_ENABLED) || defined(__NRFX_DOXYGEN__)
/**
* @brief Extended default configuration of the SPIM instance.
*/
#define NRFX_SPIM_DEFAULT_EXTENDED_CONFIG \
.dcx_pin = NRFX_SPIM_PIN_NOT_USED, \
.rx_delay = 0x02, \
.use_hw_ss = false, \
.ss_duration = 0x02,
#else
#define NRFX_SPIM_DEFAULT_EXTENDED_CONFIG
#endif
/** @brief The default configuration of the SPIM master instance. */
#define NRFX_SPIM_DEFAULT_CONFIG \
{ \
.sck_pin = NRFX_SPIM_PIN_NOT_USED, \
.mosi_pin = NRFX_SPIM_PIN_NOT_USED, \
.miso_pin = NRFX_SPIM_PIN_NOT_USED, \
.ss_pin = NRFX_SPIM_PIN_NOT_USED, \
.ss_active_high = false, \
.irq_priority = NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY, \
.orc = 0xFF, \
.frequency = NRF_SPIM_FREQ_4M, \
.mode = NRF_SPIM_MODE_0, \
.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, \
NRFX_SPIM_DEFAULT_EXTENDED_CONFIG \
}
/** @brief Flag indicating that TX buffer address will be incremented after transfer. */
#define NRFX_SPIM_FLAG_TX_POSTINC (1UL << 0)
/** @brief Flag indicating that RX buffer address will be incremented after transfer. */
#define NRFX_SPIM_FLAG_RX_POSTINC (1UL << 1)
/** @brief Flag indicating that the interrupt after each transfer will be suppressed, and the event handler will not be called. */
#define NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER (1UL << 2)
/** @brief Flag indicating that the transfer will be set up, but not started. */
#define NRFX_SPIM_FLAG_HOLD_XFER (1UL << 3)
/** @brief Flag indicating that the transfer will be executed multiple times. */
#define NRFX_SPIM_FLAG_REPEATED_XFER (1UL << 4)
/** @brief Single transfer descriptor structure. */
typedef struct
{
uint8_t const * p_tx_buffer; ///< Pointer to TX buffer.
size_t tx_length; ///< TX buffer length.
uint8_t * p_rx_buffer; ///< Pointer to RX buffer.
size_t rx_length; ///< RX buffer length.
} nrfx_spim_xfer_desc_t;
/**
* @brief Macro for setting up single transfer descriptor.
*
* This macro is for internal use only.
*/
#define NRFX_SPIM_SINGLE_XFER(p_tx, tx_len, p_rx, rx_len) \
{ \
.p_tx_buffer = (uint8_t const *)(p_tx), \
.tx_length = (tx_len), \
.p_rx_buffer = (p_rx), \
.rx_length = (rx_len), \
}
/** @brief Macro for setting the duplex TX RX transfer. */
#define NRFX_SPIM_XFER_TRX(p_tx_buf, tx_length, p_rx_buf, rx_length) \
NRFX_SPIM_SINGLE_XFER(p_tx_buf, tx_length, p_rx_buf, rx_length)
/** @brief Macro for setting the TX transfer. */
#define NRFX_SPIM_XFER_TX(p_buf, length) \
NRFX_SPIM_SINGLE_XFER(p_buf, length, NULL, 0)
/** @brief Macro for setting the RX transfer. */
#define NRFX_SPIM_XFER_RX(p_buf, length) \
NRFX_SPIM_SINGLE_XFER(NULL, 0, p_buf, length)
/**
* @brief SPIM master driver event types, passed to the handler routine provided
* during initialization.
*/
typedef enum
{
NRFX_SPIM_EVENT_DONE, ///< Transfer done.
} nrfx_spim_evt_type_t;
/** @brief SPIM event description with transmission details. */
typedef struct
{
nrfx_spim_evt_type_t type; ///< Event type.
nrfx_spim_xfer_desc_t xfer_desc; ///< Transfer details.
} nrfx_spim_evt_t;
/** @brief SPIM driver event handler type. */
typedef void (* nrfx_spim_evt_handler_t)(nrfx_spim_evt_t const * p_event,
void * p_context);
/**
* @brief Function for initializing the SPIM driver instance.
*
* This function configures and enables the specified peripheral.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] handler Event handler provided by the user. If NULL, transfers
* will be performed in blocking mode.
* @param[in] p_context Context passed to event handler.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver was already initialized.
* @retval NRFX_ERROR_BUSY Some other peripheral with the same
* instance ID is already in use. This is
* possible only if @ref nrfx_prs module
* is enabled.
* @retval NRFX_ERROR_NOT_SUPPORTED Requested configuration is not supported
* by the SPIM instance.
*/
nrfx_err_t nrfx_spim_init(nrfx_spim_t const * const p_instance,
nrfx_spim_config_t const * p_config,
nrfx_spim_evt_handler_t handler,
void * p_context);
/**
* @brief Function for uninitializing the SPIM driver instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_spim_uninit(nrfx_spim_t const * const p_instance);
/**
* @brief Function for starting the SPIM data transfer.
*
* Additional options are provided using the @c flags parameter:
*
* - @ref NRFX_SPIM_FLAG_TX_POSTINC and @ref NRFX_SPIM_FLAG_RX_POSTINC -
* Post-incrementation of buffer addresses.
* - @ref NRFX_SPIM_FLAG_HOLD_XFER - Driver is not starting the transfer. Use this
* flag if the transfer is triggered externally by PPI. Use
* @ref nrfx_spim_start_task_get to get the address of the start task.
* - @ref NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER - No user event handler after transfer
* completion. This also means no interrupt at the end of the transfer.
* If @ref NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER is used, the driver does not set the instance into
* busy state, so you must ensure that the next transfers are set up when SPIM is not active.
* @ref nrfx_spim_end_event_get function can be used to detect end of transfer. Option can be used
* together with @ref NRFX_SPIM_FLAG_REPEATED_XFER to prepare a sequence of SPI transfers
* without interruptions.
* - @ref NRFX_SPIM_FLAG_REPEATED_XFER - Prepare for repeated transfers. You can set
* up a number of transfers that will be triggered externally (for example by PPI). An example is
* a TXRX transfer with the options @ref NRFX_SPIM_FLAG_RX_POSTINC,
* @ref NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER, and @ref NRFX_SPIM_FLAG_REPEATED_XFER. After the
* transfer is set up, a set of transfers can be triggered by PPI that will read, for example,
* the same register of an external component and put it into a RAM buffer without any interrupts.
* @ref nrfx_spim_end_event_get can be used to get the address of the END event, which can be
* used to count the number of transfers. If @ref NRFX_SPIM_FLAG_REPEATED_XFER is used,
* the driver does not set the instance into busy state, so you must ensure that the next
* transfers are set up when SPIM is not active.
*
* @note Peripherals using EasyDMA (including SPIM) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met,
* this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
*
* @param p_instance Pointer to the driver instance structure.
* @param p_xfer_desc Pointer to the transfer descriptor.
* @param flags Transfer options (0 for default settings).
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_NOT_SUPPORTED The provided parameters are not supported.
* @retval NRFX_ERROR_INVALID_ADDR The provided buffers are not placed in the Data
* RAM region.
*/
nrfx_err_t nrfx_spim_xfer(nrfx_spim_t const * const p_instance,
nrfx_spim_xfer_desc_t const * p_xfer_desc,
uint32_t flags);
#if NRFX_CHECK(NRFX_SPIM_EXTENDED_ENABLED) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for starting the SPIM data transfer with DCX control.
*
* See @ref nrfx_spim_xfer for description of additional options of transfer
* provided by the @c flags parameter.
*
* @note Peripherals that use EasyDMA (including SPIM) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met,
* this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
*
* @param p_instance Pointer to the driver instance structure.
* @param p_xfer_desc Pointer to the transfer descriptor.
* @param flags Transfer options (0 for default settings).
* @param cmd_length Length of the command bytes preceding the data
* bytes. The DCX line will be low during transmission
* of command bytes and high during transmission of data bytes.
* Maximum value available for dividing the transmitted bytes
* into command bytes and data bytes is @ref NRF_SPIM_DCX_CNT_ALL_CMD - 1.
* The @ref NRF_SPIM_DCX_CNT_ALL_CMD value passed as the
* @c cmd_length parameter causes all transmitted bytes
* to be marked as command bytes.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_NOT_SUPPORTED The provided parameters are not supported.
* @retval NRFX_ERROR_INVALID_ADDR The provided buffers are not placed in the Data
* RAM region.
*/
nrfx_err_t nrfx_spim_xfer_dcx(nrfx_spim_t const * const p_instance,
nrfx_spim_xfer_desc_t const * p_xfer_desc,
uint32_t flags,
uint8_t cmd_length);
#endif
/**
* @brief Function for returning the address of a SPIM start task.
*
* This function is to be used if @ref nrfx_spim_xfer was called with the flag @ref NRFX_SPIM_FLAG_HOLD_XFER.
* In that case, the transfer is not started by the driver, but it must be started externally by PPI.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return Start task address.
*/
uint32_t nrfx_spim_start_task_get(nrfx_spim_t const * p_instance);
/**
* @brief Function for returning the address of a END SPIM event.
*
* The END event can be used to detect the end of a transfer
* if the @ref NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER option is used.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return END event address.
*/
uint32_t nrfx_spim_end_event_get(nrfx_spim_t const * p_instance);
/**
* @brief Function for aborting ongoing transfer.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_spim_abort(nrfx_spim_t const * p_instance);
/** @} */
void nrfx_spim_0_irq_handler(void);
void nrfx_spim_1_irq_handler(void);
void nrfx_spim_2_irq_handler(void);
void nrfx_spim_3_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_SPIM_H__
+409
View File
@@ -0,0 +1,409 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_TIMER_H__
#define NRFX_TIMER_H__
#include <nrfx.h>
#include <hal/nrf_timer.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_timer Timer driver
* @{
* @ingroup nrf_timer
* @brief TIMER peripheral driver.
*/
/**
* @brief Timer driver instance data structure.
*/
typedef struct
{
NRF_TIMER_Type * p_reg; ///< Pointer to the structure with TIMER peripheral instance registers.
uint8_t instance_id; ///< Index of the driver instance. For internal use only.
uint8_t cc_channel_count; ///< Number of capture/compare channels.
} nrfx_timer_t;
/** @brief Macro for creating a timer driver instance. */
#define NRFX_TIMER_INSTANCE(id) \
{ \
.p_reg = NRFX_CONCAT_2(NRF_TIMER, id), \
.instance_id = NRFX_CONCAT_3(NRFX_TIMER, id, _INST_IDX), \
.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(id), \
}
#ifndef __NRFX_DOXYGEN__
enum {
#if NRFX_CHECK(NRFX_TIMER0_ENABLED)
NRFX_TIMER0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_TIMER1_ENABLED)
NRFX_TIMER1_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_TIMER2_ENABLED)
NRFX_TIMER2_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_TIMER3_ENABLED)
NRFX_TIMER3_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_TIMER4_ENABLED)
NRFX_TIMER4_INST_IDX,
#endif
NRFX_TIMER_ENABLED_COUNT
};
#endif
/** @brief The configuration structure of the timer driver instance. */
typedef struct
{
nrf_timer_frequency_t frequency; ///< Frequency.
nrf_timer_mode_t mode; ///< Mode of operation.
nrf_timer_bit_width_t bit_width; ///< Bit width.
uint8_t interrupt_priority; ///< Interrupt priority.
void * p_context; ///< Context passed to interrupt handler.
} nrfx_timer_config_t;
/** @brief Timer driver instance default configuration. */
#define NRFX_TIMER_DEFAULT_CONFIG \
{ \
.frequency = (nrf_timer_frequency_t)NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY,\
.mode = (nrf_timer_mode_t)NRFX_TIMER_DEFAULT_CONFIG_MODE, \
.bit_width = (nrf_timer_bit_width_t)NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH,\
.interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, \
.p_context = NULL \
}
/**
* @brief Timer driver event handler type.
*
* @param[in] event_type Timer event.
* @param[in] p_context General purpose parameter set during initialization of
* the timer. This parameter can be used to pass
* additional information to the handler function, for
* example, the timer ID.
*/
typedef void (* nrfx_timer_event_handler_t)(nrf_timer_event_t event_type,
void * p_context);
/**
* @brief Function for initializing the timer.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] timer_event_handler Event handler provided by the user.
* Must not be NULL.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The instance is already initialized.
*/
nrfx_err_t nrfx_timer_init(nrfx_timer_t const * const p_instance,
nrfx_timer_config_t const * p_config,
nrfx_timer_event_handler_t timer_event_handler);
/**
* @brief Function for uninitializing the timer.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_timer_uninit(nrfx_timer_t const * const p_instance);
/**
* @brief Function for turning on the timer.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_timer_enable(nrfx_timer_t const * const p_instance);
/**
* @brief Function for turning off the timer.
*
* The timer will allow to enter the lowest possible SYSTEM_ON state
* only after this function is called.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_timer_disable(nrfx_timer_t const * const p_instance);
/**
* @brief Function for checking the timer state.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @retval true Timer is enabled.
* @retval false Timer is not enabled.
*/
bool nrfx_timer_is_enabled(nrfx_timer_t const * const p_instance);
/**
* @brief Function for pausing the timer.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_timer_pause(nrfx_timer_t const * const p_instance);
/**
* @brief Function for resuming the timer.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_timer_resume(nrfx_timer_t const * const p_instance);
/**
* @brief Function for clearing the timer.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_timer_clear(nrfx_timer_t const * const p_instance);
/**
* @brief Function for incrementing the timer.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_timer_increment(nrfx_timer_t const * const p_instance);
/**
* @brief Function for returning the address of the specified timer task.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] timer_task Timer task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_timer_task_address_get(nrfx_timer_t const * const p_instance,
nrf_timer_task_t timer_task);
/**
* @brief Function for returning the address of the specified timer capture task.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] channel Capture channel number.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_timer_capture_task_address_get(nrfx_timer_t const * const p_instance,
uint32_t channel);
/**
* @brief Function for returning the address of the specified timer event.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] timer_event Timer event.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_timer_event_address_get(nrfx_timer_t const * const p_instance,
nrf_timer_event_t timer_event);
/**
* @brief Function for returning the address of the specified timer compare event.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] channel Compare channel number.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_timer_compare_event_address_get(nrfx_timer_t const * const p_instance,
uint32_t channel);
/**
* @brief Function for capturing the timer value.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] cc_channel Capture channel number.
*
* @return Captured value.
*/
uint32_t nrfx_timer_capture(nrfx_timer_t const * const p_instance,
nrf_timer_cc_channel_t cc_channel);
/**
* @brief Function for returning the capture value from the specified channel.
*
* Use this function to read channel values when PPI is used for capturing.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] cc_channel Capture channel number.
*
* @return Captured value.
*/
__STATIC_INLINE uint32_t nrfx_timer_capture_get(nrfx_timer_t const * const p_instance,
nrf_timer_cc_channel_t cc_channel);
/**
* @brief Function for setting the timer channel in compare mode.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] cc_channel Compare channel number.
* @param[in] cc_value Compare value.
* @param[in] enable_int Enable or disable the interrupt for the compare channel.
*/
void nrfx_timer_compare(nrfx_timer_t const * const p_instance,
nrf_timer_cc_channel_t cc_channel,
uint32_t cc_value,
bool enable_int);
/**
* @brief Function for setting the timer channel in the extended compare mode.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] cc_channel Compare channel number.
* @param[in] cc_value Compare value.
* @param[in] timer_short_mask Shortcut between the compare event on the channel
* and the timer task (STOP or CLEAR).
* @param[in] enable_int Enable or disable the interrupt for the compare channel.
*/
void nrfx_timer_extended_compare(nrfx_timer_t const * const p_instance,
nrf_timer_cc_channel_t cc_channel,
uint32_t cc_value,
nrf_timer_short_mask_t timer_short_mask,
bool enable_int);
/**
* @brief Function for converting time in microseconds to timer ticks.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] time_us Time in microseconds.
*
* @return Number of ticks.
*/
__STATIC_INLINE uint32_t nrfx_timer_us_to_ticks(nrfx_timer_t const * const p_instance,
uint32_t time_us);
/**
* @brief Function for converting time in milliseconds to timer ticks.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] time_ms Time in milliseconds.
*
* @return Number of ticks.
*/
__STATIC_INLINE uint32_t nrfx_timer_ms_to_ticks(nrfx_timer_t const * const p_instance,
uint32_t time_ms);
/**
* @brief Function for enabling timer compare interrupt.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] channel Compare channel.
*/
void nrfx_timer_compare_int_enable(nrfx_timer_t const * const p_instance,
uint32_t channel);
/**
* @brief Function for disabling timer compare interrupt.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] channel Compare channel.
*/
void nrfx_timer_compare_int_disable(nrfx_timer_t const * const p_instance,
uint32_t channel);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t nrfx_timer_task_address_get(nrfx_timer_t const * const p_instance,
nrf_timer_task_t timer_task)
{
return (uint32_t)nrf_timer_task_address_get(p_instance->p_reg, timer_task);
}
__STATIC_INLINE uint32_t nrfx_timer_capture_task_address_get(nrfx_timer_t const * const p_instance,
uint32_t channel)
{
NRFX_ASSERT(channel < p_instance->cc_channel_count);
return (uint32_t)nrf_timer_task_address_get(p_instance->p_reg,
nrf_timer_capture_task_get(channel));
}
__STATIC_INLINE uint32_t nrfx_timer_event_address_get(nrfx_timer_t const * const p_instance,
nrf_timer_event_t timer_event)
{
return (uint32_t)nrf_timer_event_address_get(p_instance->p_reg, timer_event);
}
__STATIC_INLINE uint32_t nrfx_timer_compare_event_address_get(nrfx_timer_t const * const p_instance,
uint32_t channel)
{
NRFX_ASSERT(channel < p_instance->cc_channel_count);
return (uint32_t)nrf_timer_event_address_get(p_instance->p_reg,
nrf_timer_compare_event_get(channel));
}
__STATIC_INLINE uint32_t nrfx_timer_capture_get(nrfx_timer_t const * const p_instance,
nrf_timer_cc_channel_t cc_channel)
{
return nrf_timer_cc_read(p_instance->p_reg, cc_channel);
}
__STATIC_INLINE uint32_t nrfx_timer_us_to_ticks(nrfx_timer_t const * const p_instance,
uint32_t timer_us)
{
return nrf_timer_us_to_ticks(timer_us, nrf_timer_frequency_get(p_instance->p_reg));
}
__STATIC_INLINE uint32_t nrfx_timer_ms_to_ticks(nrfx_timer_t const * const p_instance,
uint32_t timer_ms)
{
return nrf_timer_ms_to_ticks(timer_ms, nrf_timer_frequency_get(p_instance->p_reg));
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
void nrfx_timer_0_irq_handler(void);
void nrfx_timer_1_irq_handler(void);
void nrfx_timer_2_irq_handler(void);
void nrfx_timer_3_irq_handler(void);
void nrfx_timer_4_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_TIMER_H__
+407
View File
@@ -0,0 +1,407 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_TWI_H__
#define NRFX_TWI_H__
#include <nrfx.h>
#include <nrfx_twi_twim.h>
#include <hal/nrf_twi.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_twi TWI driver
* @{
* @ingroup nrf_twi
* @brief Two Wire Interface master (TWI) peripheral driver.
*/
/**
* @brief Structure for the TWI master driver instance.
*/
typedef struct
{
NRF_TWI_Type * p_twi; ///< Pointer to a structure with TWI registers.
uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
} nrfx_twi_t;
/** @brief Macro for creating a TWI master driver instance. */
#define NRFX_TWI_INSTANCE(id) \
{ \
.p_twi = NRFX_CONCAT_2(NRF_TWI, id), \
.drv_inst_idx = NRFX_CONCAT_3(NRFX_TWI, id, _INST_IDX), \
}
#ifndef __NRFX_DOXYGEN__
enum {
#if NRFX_CHECK(NRFX_TWI0_ENABLED)
NRFX_TWI0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_TWI1_ENABLED)
NRFX_TWI1_INST_IDX,
#endif
NRFX_TWI_ENABLED_COUNT
};
#endif
/** @brief Structure for the configuration of the TWI master driver instance. */
typedef struct
{
uint32_t scl; ///< SCL pin number.
uint32_t sda; ///< SDA pin number.
nrf_twi_frequency_t frequency; ///< TWI frequency.
uint8_t interrupt_priority; ///< Interrupt priority.
bool hold_bus_uninit; ///< Hold pull up state on GPIO pins after uninit.
} nrfx_twi_config_t;
/** @brief The default configuration of the TWI master driver instance. */
#define NRFX_TWI_DEFAULT_CONFIG \
{ \
.frequency = (nrf_twi_frequency_t)NRFX_TWI_DEFAULT_CONFIG_FREQUENCY, \
.scl = 31, \
.sda = 31, \
.interrupt_priority = NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY, \
.hold_bus_uninit = NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT, \
}
/** @brief Flag indicating that the interrupt after each transfer will be suppressed, and the event handler will not be called. */
#define NRFX_TWI_FLAG_NO_XFER_EVT_HANDLER (1UL << 2)
/** @brief Flag indicating that the TX transfer will not end with a stop condition. */
#define NRFX_TWI_FLAG_TX_NO_STOP (1UL << 5)
/** @brief Flag indicating that the transfer will be suspended. */
#define NRFX_TWI_FLAG_SUSPEND (1UL << 6)
/** @brief TWI master driver event types. */
typedef enum
{
NRFX_TWI_EVT_DONE, ///< Transfer completed event.
NRFX_TWI_EVT_ADDRESS_NACK, ///< Error event: NACK received after sending the address.
NRFX_TWI_EVT_DATA_NACK, ///< Error event: NACK received after sending a data byte.
NRFX_TWI_EVT_OVERRUN, ///< Error event: The unread data is replaced by new data.
NRFX_TWI_EVT_BUS_ERROR ///< Error event: An unexpected transition occurred on the bus.
} nrfx_twi_evt_type_t;
/** @brief TWI master driver transfer types. */
typedef enum
{
NRFX_TWI_XFER_TX, ///< TX transfer.
NRFX_TWI_XFER_RX, ///< RX transfer.
NRFX_TWI_XFER_TXRX, ///< TX transfer followed by RX transfer with repeated start.
NRFX_TWI_XFER_TXTX ///< TX transfer followed by TX transfer with repeated start.
} nrfx_twi_xfer_type_t;
/** @brief Structure for a TWI transfer descriptor. */
typedef struct
{
nrfx_twi_xfer_type_t type; ///< Type of transfer.
uint8_t address; ///< Slave address.
size_t primary_length; ///< Number of bytes transferred.
size_t secondary_length; ///< Number of bytes transferred.
uint8_t * p_primary_buf; ///< Pointer to transferred data.
uint8_t * p_secondary_buf; ///< Pointer to transferred data.
} nrfx_twi_xfer_desc_t;
/** @brief Macro for setting the TX transfer descriptor. */
#define NRFX_TWI_XFER_DESC_TX(addr, p_data, length) \
{ \
.type = NRFX_TWI_XFER_TX, \
.address = (addr), \
.primary_length = (length), \
.secondary_length = 0, \
.p_primary_buf = (p_data), \
.p_secondary_buf = NULL, \
}
/** @brief Macro for setting the RX transfer descriptor. */
#define NRFX_TWI_XFER_DESC_RX(addr, p_data, length) \
{ \
.type = NRFX_TWI_XFER_RX, \
.address = (addr), \
.primary_length = (length), \
.secondary_length = 0, \
.p_primary_buf = (p_data), \
.p_secondary_buf = NULL, \
}
/** @brief Macro for setting the TX-RX transfer descriptor. */
#define NRFX_TWI_XFER_DESC_TXRX(addr, p_tx, tx_len, p_rx, rx_len) \
{ \
.type = NRFX_TWI_XFER_TXRX, \
.address = (addr), \
.primary_length = (tx_len), \
.secondary_length = (rx_len), \
.p_primary_buf = (p_tx), \
.p_secondary_buf = (p_rx), \
}
/** @brief Macro for setting the TX-TX transfer descriptor. */
#define NRFX_TWI_XFER_DESC_TXTX(addr, p_tx, tx_len, p_tx2, tx_len2) \
{ \
.type = NRFX_TWI_XFER_TXTX, \
.address = (addr), \
.primary_length = (tx_len), \
.secondary_length = (tx_len2), \
.p_primary_buf = (p_tx), \
.p_secondary_buf = (p_tx2), \
}
/** @brief Structure for a TWI event. */
typedef struct
{
nrfx_twi_evt_type_t type; ///< Event type.
nrfx_twi_xfer_desc_t xfer_desc; ///< Transfer details.
} nrfx_twi_evt_t;
/** @brief TWI event handler prototype. */
typedef void (* nrfx_twi_evt_handler_t)(nrfx_twi_evt_t const * p_event,
void * p_context);
/**
* @brief Function for initializing the TWI driver instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] event_handler Event handler provided by the user. If NULL, blocking mode is enabled.
* @param[in] p_context Context passed to event handler.
*
* @retval NRFX_SUCCESS Initialization is successful.
* @retval NRFX_ERROR_INVALID_STATE The driver is in invalid state.
* @retval NRFX_ERROR_BUSY Some other peripheral with the same
* instance ID is already in use. This is
* possible only if @ref nrfx_prs module
* is enabled.
*/
nrfx_err_t nrfx_twi_init(nrfx_twi_t const * p_instance,
nrfx_twi_config_t const * p_config,
nrfx_twi_evt_handler_t event_handler,
void * p_context);
/**
* @brief Function for uninitializing the TWI instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_twi_uninit(nrfx_twi_t const * p_instance);
/**
* @brief Function for enabling the TWI instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_twi_enable(nrfx_twi_t const * p_instance);
/**
* @brief Function for disabling the TWI instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_twi_disable(nrfx_twi_t const * p_instance);
/**
* @brief Function for sending data to a TWI slave.
*
* The transmission will be stopped when an error occurs. If a transfer is ongoing,
* the function returns the error code @ref NRFX_ERROR_BUSY.
*
* @note This function is deprecated. Use @ref nrfx_twi_xfer instead.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] address Address of a specific slave device (only 7 LSB).
* @param[in] p_data Pointer to a transmit buffer.
* @param[in] length Number of bytes to send.
* @param[in] no_stop If set, the stop condition is not generated on the bus
* after the transfer has completed successfully (allowing
* for a repeated start in the next transfer).
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_INTERNAL An error is detected by hardware.
* @retval NRFX_ERROR_INVALID_STATE RX transaction is suspended on bus.
* @retval NRFX_ERROR_DRV_TWI_ERR_ANACK Negative acknowledgement (NACK) is received after sending
* the address in polling mode.
* @retval NRFX_ERROR_DRV_TWI_ERR_DNACK Negative acknowledgement (NACK) is received after sending
* a data byte in polling mode.
*/
nrfx_err_t nrfx_twi_tx(nrfx_twi_t const * p_instance,
uint8_t address,
uint8_t const * p_data,
size_t length,
bool no_stop);
/**
* @brief Function for reading data from a TWI slave.
*
* The transmission will be stopped when an error occurs. If a transfer is ongoing,
* the function returns the error code @ref NRFX_ERROR_BUSY.
*
* @note This function is deprecated. Use @ref nrfx_twi_xfer instead.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] address Address of a specific slave device (only 7 LSB).
* @param[in] p_data Pointer to a receive buffer.
* @param[in] length Number of bytes to be received.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_INTERNAL An error is detected by hardware.
* @retval NRFX_ERROR_INVALID_STATE TX transaction is suspended on bus.
* @retval NRFX_ERROR_DRV_TWI_ERR_OVERRUN The unread data is replaced by new data.
* @retval NRFX_ERROR_DRV_TWI_ERR_ANACK Negative acknowledgement (NACK) is received after sending
* the address in polling mode.
* @retval NRFX_ERROR_DRV_TWI_ERR_DNACK Negative acknowledgement (NACK) is received after sending
* a data byte in polling mode.
*/
nrfx_err_t nrfx_twi_rx(nrfx_twi_t const * p_instance,
uint8_t address,
uint8_t * p_data,
size_t length);
/**
* @brief Function for performing a TWI transfer.
*
* The following transfer types can be configured (@ref nrfx_twi_xfer_desc_t::type):
* - @ref NRFX_TWI_XFER_TXRX - Write operation followed by a read operation (without STOP condition in between).
* - @ref NRFX_TWI_XFER_TXTX - Write operation followed by a write operation (without STOP condition in between).
* - @ref NRFX_TWI_XFER_TX - Write operation (with or without STOP condition).
* - @ref NRFX_TWI_XFER_RX - Read operation (with STOP condition).
*
* @note TX-RX and TX-TX transfers are supported only in non-blocking mode.
*
* Additional options are provided using the flags parameter:
* - @ref NRFX_TWI_FLAG_NO_XFER_EVT_HANDLER - No user event handler after transfer completion. In most cases, this also means no interrupt at the end of the transfer.
* - @ref NRFX_TWI_FLAG_TX_NO_STOP - No stop condition after TX transfer.
* - @ref NRFX_TWI_FLAG_SUSPEND - Transfer will be suspended. This allows for combining multiple transfers into one transaction.
* Only transactions with the same direction can be combined. To finish the transaction, call the function without this flag.
*
* @note
* Some flag combinations are invalid:
* - @ref NRFX_TWI_FLAG_TX_NO_STOP with @ref nrfx_twi_xfer_desc_t::type different than @ref NRFX_TWI_XFER_TX
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_xfer_desc Pointer to the transfer descriptor.
* @param[in] flags Transfer options (0 for default settings).
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_NOT_SUPPORTED The provided parameters are not supported.
* @retval NRFX_ERROR_INTERNAL An unexpected transition occurred on the bus.
* @retval NRFX_ERROR_INVALID_STATE Other direction of transaction is suspended on the bus.
* @retval NRFX_ERROR_DRV_TWI_ERR_OVERRUN The unread data is replaced by new data (TXRX and RX)
* @retval NRFX_ERROR_DRV_TWI_ERR_ANACK Negative acknowledgement (NACK) is received after sending
* the address in polling mode.
* @retval NRFX_ERROR_DRV_TWI_ERR_DNACK Negative acknowledgement (NACK) is received after sending
* a data byte in polling mode.
*/
nrfx_err_t nrfx_twi_xfer(nrfx_twi_t const * p_instance,
nrfx_twi_xfer_desc_t const * p_xfer_desc,
uint32_t flags);
/**
* @brief Function for checking the TWI driver state.
*
* @param[in] p_instance TWI instance.
*
* @retval true The TWI driver is currently busy performing a transfer.
* @retval false The TWI driver is ready for a new transfer.
*/
bool nrfx_twi_is_busy(nrfx_twi_t const * p_instance);
/**
* @brief Function for getting the transferred data count.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return Data count.
*/
size_t nrfx_twi_data_count_get(nrfx_twi_t const * const p_instance);
/**
* @brief Function for returning the address of a STOPPED TWI event.
*
* A STOPPED event can be used to detect the end of a transfer if the @ref NRFX_TWI_FLAG_NO_XFER_EVT_HANDLER
* option is used.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return STOPPED event address.
*/
uint32_t nrfx_twi_stopped_event_get(nrfx_twi_t const * p_instance);
/**
* @brief Function for recovering the bus.
*
* This function checks if the bus is not stuck because of a slave holding the SDA line in the low state,
* and if needed it performs required number of pulses on the SCL line to make the slave release the SDA line.
* Finally, the function generates a STOP condition on the bus to put it into a known state.
*
* @note This function can be used only if the TWI driver is uninitialized.
*
* @param[in] scl_pin SCL pin number.
* @param[in] sda_pin SDA pin number.
*
* @retval NRFX_SUCCESS Bus recovery was successful.
* @retval NRFX_ERROR_INTERNAL Bus recovery failed.
*/
__STATIC_INLINE nrfx_err_t nrfx_twi_bus_recover(uint32_t scl_pin, uint32_t sda_pin);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE nrfx_err_t nrfx_twi_bus_recover(uint32_t scl_pin, uint32_t sda_pin)
{
return nrfx_twi_twim_bus_recover(scl_pin, sda_pin);
}
#endif
/** @} */
void nrfx_twi_0_irq_handler(void);
void nrfx_twi_1_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_TWI_H__
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2019 - 2021, 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 NRFX_TWI_TWIM_H
#define NRFX_TWI_TWIM_H
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
nrfx_err_t nrfx_twi_twim_bus_recover(uint32_t scl_pin, uint32_t sda_pin);
#ifdef __cplusplus
}
#endif
#endif // NRFX_TWI_TWIM_H
+448
View File
@@ -0,0 +1,448 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_TWIM_H__
#define NRFX_TWIM_H__
#include <nrfx.h>
#include <nrfx_twi_twim.h>
#include <hal/nrf_twim.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_twim TWIM driver
* @{
* @ingroup nrf_twim
* @brief Two Wire Interface Master with EasyDMA (TWIM) peripheral driver.
*/
/** @brief Structure for the TWI master driver instance. */
typedef struct
{
NRF_TWIM_Type * p_twim; ///< Pointer to a structure with TWIM registers.
uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
} nrfx_twim_t;
/** @brief Macro for creating a TWI master driver instance. */
#define NRFX_TWIM_INSTANCE(id) \
{ \
.p_twim = NRFX_CONCAT_2(NRF_TWIM, id), \
.drv_inst_idx = NRFX_CONCAT_3(NRFX_TWIM, id, _INST_IDX), \
}
#ifndef __NRFX_DOXYGEN__
enum {
#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
NRFX_TWIM0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_TWIM1_ENABLED)
NRFX_TWIM1_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_TWIM2_ENABLED)
NRFX_TWIM2_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_TWIM3_ENABLED)
NRFX_TWIM3_INST_IDX,
#endif
NRFX_TWIM_ENABLED_COUNT
};
#endif
/** @brief Structure for the TWI master driver instance configuration. */
typedef struct
{
uint32_t scl; ///< SCL pin number.
uint32_t sda; ///< SDA pin number.
nrf_twim_frequency_t frequency; ///< TWIM frequency.
uint8_t interrupt_priority; ///< Interrupt priority.
bool hold_bus_uninit; ///< Hold pull up state on GPIO pins after uninit.
} nrfx_twim_config_t;
/** @brief TWI master driver instance default configuration. */
#define NRFX_TWIM_DEFAULT_CONFIG \
{ \
.scl = 31, \
.sda = 31, \
.frequency = (nrf_twim_frequency_t)NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY, \
.interrupt_priority = NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY, \
.hold_bus_uninit = NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT, \
}
/** @brief Flag indicating that TX buffer address will be incremented after the transfer. */
#define NRFX_TWIM_FLAG_TX_POSTINC (1UL << 0)
/** @brief Flag indicating that RX buffer address will be incremented after the transfer. */
#define NRFX_TWIM_FLAG_RX_POSTINC (1UL << 1)
/** @brief Flag indicating that the interrupt after each transfer will be suppressed, and the event handler will not be called. */
#define NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER (1UL << 2)
/** @brief Flag indicating that the transfer will be set up, but not started. */
#define NRFX_TWIM_FLAG_HOLD_XFER (1UL << 3)
/** @brief Flag indicating that the transfer will be executed multiple times. */
#define NRFX_TWIM_FLAG_REPEATED_XFER (1UL << 4)
/** @brief Flag indicating that the TX transfer will not end with a stop condition. */
#define NRFX_TWIM_FLAG_TX_NO_STOP (1UL << 5)
/** @brief Flag indicating that checks for spurious STOP condition will not be performed. */
#define NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK (1UL << 6)
/** @brief TWI master driver event types. */
typedef enum
{
NRFX_TWIM_EVT_DONE, ///< Transfer completed event.
NRFX_TWIM_EVT_ADDRESS_NACK, ///< Error event: NACK received after sending the address.
NRFX_TWIM_EVT_DATA_NACK, ///< Error event: NACK received after sending a data byte.
NRFX_TWIM_EVT_OVERRUN, ///< Error event: The unread data is replaced by new data.
NRFX_TWIM_EVT_BUS_ERROR ///< Error event: An unexpected transition occurred on the bus.
} nrfx_twim_evt_type_t;
/** @brief TWI master driver transfer types. */
typedef enum
{
NRFX_TWIM_XFER_TX, ///< TX transfer.
NRFX_TWIM_XFER_RX, ///< RX transfer.
NRFX_TWIM_XFER_TXRX, ///< TX transfer followed by RX transfer with repeated start.
NRFX_TWIM_XFER_TXTX ///< TX transfer followed by TX transfer with repeated start.
} nrfx_twim_xfer_type_t;
/** @brief Structure for a TWI transfer descriptor. */
typedef struct
{
nrfx_twim_xfer_type_t type; ///< Type of transfer.
uint8_t address; ///< Slave address.
size_t primary_length; ///< Number of bytes transferred.
size_t secondary_length; ///< Number of bytes transferred.
uint8_t * p_primary_buf; ///< Pointer to transferred data.
uint8_t * p_secondary_buf; ///< Pointer to transferred data.
} nrfx_twim_xfer_desc_t;
/** @brief Macro for setting the TX transfer descriptor. */
#define NRFX_TWIM_XFER_DESC_TX(addr, p_data, length) \
{ \
.type = NRFX_TWIM_XFER_TX, \
.address = (addr), \
.primary_length = (length), \
.secondary_length = 0, \
.p_primary_buf = (p_data), \
.p_secondary_buf = NULL, \
}
/** @brief Macro for setting the RX transfer descriptor. */
#define NRFX_TWIM_XFER_DESC_RX(addr, p_data, length) \
{ \
.type = NRFX_TWIM_XFER_RX, \
.address = (addr), \
.primary_length = (length), \
.secondary_length = 0, \
.p_primary_buf = (p_data), \
.p_secondary_buf = NULL, \
}
/** @brief Macro for setting the TX-RX transfer descriptor. */
#define NRFX_TWIM_XFER_DESC_TXRX(addr, p_tx, tx_len, p_rx, rx_len) \
{ \
.type = NRFX_TWIM_XFER_TXRX, \
.address = (addr), \
.primary_length = (tx_len), \
.secondary_length = (rx_len), \
.p_primary_buf = (p_tx), \
.p_secondary_buf = (p_rx), \
}
/** @brief Macro for setting the TX-TX transfer descriptor. */
#define NRFX_TWIM_XFER_DESC_TXTX(addr, p_tx, tx_len, p_tx2, tx_len2) \
{ \
.type = NRFX_TWIM_XFER_TXTX, \
.address = (addr), \
.primary_length = (tx_len), \
.secondary_length = (tx_len2), \
.p_primary_buf = (p_tx), \
.p_secondary_buf = (p_tx2), \
}
/** @brief Structure for a TWI event. */
typedef struct
{
nrfx_twim_evt_type_t type; ///< Event type.
nrfx_twim_xfer_desc_t xfer_desc; ///< Transfer details.
} nrfx_twim_evt_t;
/** @brief TWI event handler prototype. */
typedef void (* nrfx_twim_evt_handler_t)(nrfx_twim_evt_t const * p_event,
void * p_context);
/**
* @brief Function for initializing the TWI driver instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] event_handler Event handler provided by the user. If NULL, blocking mode is enabled.
* @param[in] p_context Context passed to event handler.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE The driver is in invalid state.
* @retval NRFX_ERROR_BUSY Some other peripheral with the same
* instance ID is already in use. This is
* possible only if @ref nrfx_prs module
* is enabled.
*/
nrfx_err_t nrfx_twim_init(nrfx_twim_t const * p_instance,
nrfx_twim_config_t const * p_config,
nrfx_twim_evt_handler_t event_handler,
void * p_context);
/**
* @brief Function for uninitializing the TWI instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_twim_uninit(nrfx_twim_t const * p_instance);
/**
* @brief Function for enabling the TWI instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_twim_enable(nrfx_twim_t const * p_instance);
/**
* @brief Function for disabling the TWI instance.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_twim_disable(nrfx_twim_t const * p_instance);
/**
* @brief Function for sending data to a TWI slave.
*
* The transmission will be stopped when an error occurs. If a transfer is ongoing,
* the function returns the error code @ref NRFX_ERROR_BUSY.
*
* @note This function is deprecated. Use @ref nrfx_twim_xfer instead.
*
* @note Peripherals using EasyDMA (including TWIM) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met,
* this function fails with the error code NRFX_ERROR_INVALID_ADDR.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] address Address of a specific slave device (only 7 LSB).
* @param[in] p_data Pointer to a transmit buffer.
* @param[in] length Number of bytes to send. Maximum possible length is
* dependent on the used SoC (see the MAXCNT register
* description in the Product Specification). The driver
* checks it with assertion.
* @param[in] no_stop If set, the stop condition is not generated on the bus
* after the transfer has completed successfully (allowing
* for a repeated start in the next transfer).
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_INTERNAL An unexpected transition occurred on the bus.
* @retval NRFX_ERROR_INVALID_ADDR The provided buffer is not placed in the Data RAM region.
* @retval NRFX_ERROR_DRV_TWI_ERR_ANACK NACK is received after sending the address in polling mode.
* @retval NRFX_ERROR_DRV_TWI_ERR_DNACK NACK is received after sending a data byte in polling mode.
*/
nrfx_err_t nrfx_twim_tx(nrfx_twim_t const * p_instance,
uint8_t address,
uint8_t const * p_data,
size_t length,
bool no_stop);
/**
* @brief Function for reading data from a TWI slave.
*
* The transmission will be stopped when an error occurs. If a transfer is ongoing,
* the function returns the error code @ref NRFX_ERROR_BUSY.
*
* @note This function is deprecated. Use @ref nrfx_twim_xfer instead.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] address Address of a specific slave device (only 7 LSB).
* @param[in] p_data Pointer to a receive buffer.
* @param[in] length Number of bytes to be received. Maximum possible length
* is dependent on the used SoC (see the MAXCNT register
* description in the Product Specification). The driver
* checks it with assertion.
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_INTERNAL An unexpected transition occurred on the bus.
* @retval NRFX_ERROR_DRV_TWI_ERR_OVERRUN The unread data is replaced by new data.
* @retval NRFX_ERROR_DRV_TWI_ERR_ANACK NACK is received after sending the address in polling mode.
* @retval NRFX_ERROR_DRV_TWI_ERR_DNACK NACK is received after sending a data byte in polling mode.
*/
nrfx_err_t nrfx_twim_rx(nrfx_twim_t const * p_instance,
uint8_t address,
uint8_t * p_data,
size_t length);
/**
* @brief Function for performing a TWI transfer.
*
* The following transfer types can be configured (@ref nrfx_twim_xfer_desc_t::type):
* - @ref NRFX_TWIM_XFER_TXRX - Write operation followed by a read operation (without STOP condition in between).
* - @ref NRFX_TWIM_XFER_TXTX - Write operation followed by a write operation (without STOP condition in between).
* - @ref NRFX_TWIM_XFER_TX - Write operation (with or without STOP condition).
* - @ref NRFX_TWIM_XFER_RX - Read operation (with STOP condition).
*
* @note TX-RX and TX-TX transfers are supported only in non-blocking mode.
*
* Additional options are provided using the flags parameter:
* - @ref NRFX_TWIM_FLAG_TX_POSTINC and @ref NRFX_TWIM_FLAG_RX_POSTINC - Post-incrementation of buffer addresses.
* - @ref NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER - No user event handler after the transfer completion. In most cases, this also means no interrupt at the end of the transfer.
* - @ref NRFX_TWIM_FLAG_HOLD_XFER - Driver is not starting the transfer. Use this flag if the transfer is triggered externally by PPI.
* Use @ref nrfx_twim_start_task_get to get the address of the start task.
* - @ref NRFX_TWIM_FLAG_REPEATED_XFER - Prepare for repeated transfers. You can set up a number of transfers that will be triggered externally (for example by PPI).
* An example is a TXRX transfer with the options @ref NRFX_TWIM_FLAG_RX_POSTINC, @ref NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER, and @ref NRFX_TWIM_FLAG_REPEATED_XFER.
* After the transfer is set up, a set of transfers can be triggered by PPI that will read, for example, the same register of an
* external component and put it into a RAM buffer without any interrupts. @ref nrfx_twim_stopped_event_get can be used to get the
* address of the STOPPED event, which can be used to count the number of transfers. If @ref NRFX_TWIM_FLAG_REPEATED_XFER is used,
* the driver does not set the driver instance into busy state, so you must ensure that the next transfers are set up
* when TWIM is not active.
* - @ref NRFX_TWIM_FLAG_TX_NO_STOP - No stop condition after the TX transfer.
* - @ref NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK - Checks for spurious STOP conditions are disabled.
* Used together with @ref NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER can result in lower power consumption
* when transfers are triggered externally and CPU is sleeping.
* Use only with I2C standard-compliant slave devices.
*
* @note
* Some flag combinations are invalid:
* - @ref NRFX_TWIM_FLAG_TX_NO_STOP with @ref nrfx_twim_xfer_desc_t::type different than @ref NRFX_TWIM_XFER_TX
* - @ref NRFX_TWIM_FLAG_REPEATED_XFER with @ref nrfx_twim_xfer_desc_t::type set to @ref NRFX_TWIM_XFER_TXTX
*
* If @ref nrfx_twim_xfer_desc_t::type is set to @ref NRFX_TWIM_XFER_TX and the @ref NRFX_TWIM_FLAG_TX_NO_STOP and @ref NRFX_TWIM_FLAG_REPEATED_XFER
* flags are set, two tasks must be used to trigger a transfer: TASKS_RESUME followed by TASKS_STARTTX. If no stop condition is generated,
* TWIM is in SUSPENDED state. Therefore, it must be resumed before the transfer can be started.
*
* @note Peripherals using EasyDMA (including TWIM) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met,
* this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_xfer_desc Pointer to the transfer descriptor.
* @param[in] flags Transfer options (0 for default settings).
*
* @retval NRFX_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
* @retval NRFX_ERROR_NOT_SUPPORTED The provided parameters are not supported.
* @retval NRFX_ERROR_INTERNAL An unexpected transition occurred on the bus.
* @retval NRFX_ERROR_INVALID_ADDR The provided buffers are not placed in the Data RAM region.
* @retval NRFX_ERROR_DRV_TWI_ERR_OVERRUN The unread data is replaced by new data.
* @retval NRFX_ERROR_DRV_TWI_ERR_ANACK NACK is received after sending the address.
* @retval NRFX_ERROR_DRV_TWI_ERR_DNACK NACK is received after sending a data byte.
*/
nrfx_err_t nrfx_twim_xfer(nrfx_twim_t const * p_instance,
nrfx_twim_xfer_desc_t const * p_xfer_desc,
uint32_t flags);
/**
* @brief Function for checking the TWI driver state.
*
* @param[in] p_instance TWI instance.
*
* @retval true The TWI driver is currently busy performing a transfer.
* @retval false The TWI driver is ready for a new transfer.
*/
bool nrfx_twim_is_busy(nrfx_twim_t const * p_instance);
/**
* @brief Function for returning the address of a TWIM start task.
*
* This function is to be used if @ref nrfx_twim_xfer was called with the flag @ref NRFX_TWIM_FLAG_HOLD_XFER.
* In that case, the transfer is not started by the driver, but it must be started externally by PPI.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] xfer_type Transfer type used in the last call of the @ref nrfx_twim_xfer function.
*
* @return Start task address (TX or RX) depending on the value of xfer_type.
*/
uint32_t nrfx_twim_start_task_get(nrfx_twim_t const * p_instance, nrfx_twim_xfer_type_t xfer_type);
/**
* @brief Function for returning the address of a STOPPED TWIM event.
*
* A STOPPED event can be used to detect the end of a transfer if the @ref NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER
* option is used.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return STOPPED event address.
*/
uint32_t nrfx_twim_stopped_event_get(nrfx_twim_t const * p_instance);
/**
* @brief Function for recovering the bus.
*
* This function checks if the bus is not stuck because of a slave holding the SDA line in the low state,
* and if needed it performs required number of pulses on the SCL line to make the slave release the SDA line.
* Finally, the function generates a STOP condition on the bus to put it into a known state.
*
* @note This function can be used only if the TWIM driver is uninitialized.
*
* @param[in] scl_pin SCL pin number.
* @param[in] sda_pin SDA pin number.
*
* @retval NRFX_SUCCESS Bus recovery was successful.
* @retval NRFX_ERROR_INTERNAL Bus recovery failed.
*/
__STATIC_INLINE nrfx_err_t nrfx_twim_bus_recover(uint32_t scl_pin, uint32_t sda_pin);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE nrfx_err_t nrfx_twim_bus_recover(uint32_t scl_pin, uint32_t sda_pin)
{
return nrfx_twi_twim_bus_recover(scl_pin, sda_pin);
}
#endif
/** @} */
void nrfx_twim_0_irq_handler(void);
void nrfx_twim_1_irq_handler(void);
void nrfx_twim_2_irq_handler(void);
void nrfx_twim_3_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_TWIM_H__
+360
View File
@@ -0,0 +1,360 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_UART_H__
#define NRFX_UART_H__
#include <nrfx.h>
#include <hal/nrf_uart.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_uart UART driver
* @{
* @ingroup nrf_uart
* @brief UART peripheral driver.
*/
/** @brief Data structure of the UART driver instance. */
typedef struct
{
NRF_UART_Type * p_reg; ///< Pointer to a structure with UART registers.
uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
} nrfx_uart_t;
#ifndef __NRFX_DOXYGEN__
enum {
#if NRFX_CHECK(NRFX_UART0_ENABLED)
NRFX_UART0_INST_IDX,
#endif
NRFX_UART_ENABLED_COUNT
};
#endif
/** @brief Macro for creating a UART driver instance. */
#define NRFX_UART_INSTANCE(id) \
{ \
.p_reg = NRFX_CONCAT_2(NRF_UART, id), \
.drv_inst_idx = NRFX_CONCAT_3(NRFX_UART, id, _INST_IDX), \
}
/** @brief Types of UART driver events. */
typedef enum
{
NRFX_UART_EVT_TX_DONE, ///< Requested TX transfer completed.
NRFX_UART_EVT_RX_DONE, ///< Requested RX transfer completed.
NRFX_UART_EVT_ERROR, ///< Error reported by UART peripheral.
} nrfx_uart_evt_type_t;
/** @brief Structure for the UART configuration. */
typedef struct
{
uint32_t pseltxd; ///< TXD pin number.
uint32_t pselrxd; ///< RXD pin number.
uint32_t pselcts; ///< CTS pin number.
uint32_t pselrts; ///< RTS pin number.
void * p_context; ///< Context passed to interrupt handler.
nrf_uart_hwfc_t hwfc; ///< Flow control configuration.
nrf_uart_parity_t parity; ///< Parity configuration.
nrf_uart_baudrate_t baudrate; ///< Baud rate.
uint8_t interrupt_priority; ///< Interrupt priority.
} nrfx_uart_config_t;
/** @brief UART default configuration. */
#define NRFX_UART_DEFAULT_CONFIG \
{ \
.pseltxd = NRF_UART_PSEL_DISCONNECTED, \
.pselrxd = NRF_UART_PSEL_DISCONNECTED, \
.pselcts = NRF_UART_PSEL_DISCONNECTED, \
.pselrts = NRF_UART_PSEL_DISCONNECTED, \
.p_context = NULL, \
.hwfc = (nrf_uart_hwfc_t)NRFX_UART_DEFAULT_CONFIG_HWFC, \
.parity = (nrf_uart_parity_t)NRFX_UART_DEFAULT_CONFIG_PARITY, \
.baudrate = (nrf_uart_baudrate_t)NRFX_UART_DEFAULT_CONFIG_BAUDRATE, \
.interrupt_priority = NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY, \
}
/** @brief Structure for the UART transfer completion event. */
typedef struct
{
uint8_t * p_data; ///< Pointer to memory used for transfer.
uint32_t bytes; ///< Number of bytes transfered.
} nrfx_uart_xfer_evt_t;
/** @brief Structure for the UART error event. */
typedef struct
{
nrfx_uart_xfer_evt_t rxtx; ///< Transfer details, including number of bytes transferred.
uint32_t error_mask; ///< Mask of error flags that generated the event.
} nrfx_uart_error_evt_t;
/** @brief Structure for the UART event. */
typedef struct
{
nrfx_uart_evt_type_t type; ///< Event type.
union
{
nrfx_uart_xfer_evt_t rxtx; ///< Data provided for transfer completion events.
nrfx_uart_error_evt_t error; ///< Data provided for error event.
} data; ///< Union to store event data.
} nrfx_uart_event_t;
/**
* @brief UART interrupt event handler.
*
* @param[in] p_event Pointer to event structure. Event is allocated on the stack so it is available
* only within the context of the event handler.
* @param[in] p_context Context passed to the interrupt handler, set on initialization.
*/
typedef void (*nrfx_uart_event_handler_t)(nrfx_uart_event_t const * p_event,
void * p_context);
/**
* @brief Function for initializing the UART driver.
*
* This function configures and enables UART. After this function GPIO pins are controlled by UART.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] event_handler Event handler provided by the user. If not provided, the driver works in
* blocking mode.
*
* @retval NRFX_SUCCESS Initialization is successful.
* @retval NRFX_ERROR_INVALID_STATE The driver is already initialized.
* @retval NRFX_ERROR_BUSY Some other peripheral with the same
* instance ID is already in use. This is
* possible only if @ref nrfx_prs module
* is enabled.
*/
nrfx_err_t nrfx_uart_init(nrfx_uart_t const * p_instance,
nrfx_uart_config_t const * p_config,
nrfx_uart_event_handler_t event_handler);
/**
* @brief Function for uninitializing the UART driver.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_uart_uninit(nrfx_uart_t const * p_instance);
/**
* @brief Function for getting the address of the specified UART task.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] task Task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_uart_task_address_get(nrfx_uart_t const * p_instance,
nrf_uart_task_t task);
/**
* @brief Function for getting the address of the specified UART event.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] event Event.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_uart_event_address_get(nrfx_uart_t const * p_instance,
nrf_uart_event_t event);
/**
* @brief Function for sending data over UART.
*
* If an event handler was provided in nrfx_uart_init() call, this function
* returns immediately and the handler is called when the transfer is done.
* Otherwise, the transfer is performed in blocking mode, that is this function
* returns when the transfer is finished. Blocking mode is not using interrupt
* so there is no context switching inside the function.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_data Pointer to data.
* @param[in] length Number of bytes to send.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_BUSY Driver is already transferring.
* @retval NRFX_ERROR_FORBIDDEN The transfer was aborted from a different context
* (blocking mode only).
*/
nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance,
uint8_t const * p_data,
size_t length);
/**
* @brief Function for checking if UART is currently transmitting.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @retval true The UART is transmitting.
* @retval false The UART is not transmitting.
*/
bool nrfx_uart_tx_in_progress(nrfx_uart_t const * p_instance);
/**
* @brief Function for aborting any ongoing transmission.
* @note @ref NRFX_UART_EVT_TX_DONE event will be generated in non-blocking mode.
* It will contain number of bytes sent until the abort was called. The event
* handler will be called from the function context.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_uart_tx_abort(nrfx_uart_t const * p_instance);
/**
* @brief Function for receiving data over UART.
*
* If an event handler is provided in the nrfx_uart_init() call, this function
* returns immediately and the handler is called when the transfer is done.
* Otherwise, the transfer is performed in blocking mode, that is this function
* returns when the transfer is finished. Blocking mode is not using interrupt so
* there is no context switching inside the function.
* The receive buffer pointer is double-buffered in non-blocking mode. The secondary
* buffer can be set immediately after starting the transfer and will be filled
* when the primary buffer is full. The double-buffering feature allows
* receiving data continuously.
*
* If this function is used without a previous call to @ref nrfx_uart_rx_enable, the reception
* will be stopped on error or when the supplied buffer fills up. In both cases,
* RX FIFO gets disabled. This means that, in case of error, the bytes that follow are lost.
* If this nrfx_uart_rx() function is used with the previous call to @ref nrfx_uart_rx_enable,
* the reception is stopped in case of error, but FIFO is still ongoing. The receiver is still
* working, so after handling the error, an immediate repeated call to this nrfx_uart_rx()
* function with fresh data buffer will re-establish reception. To disable the receiver,
* you must call @ref nrfx_uart_rx_disable explicitly.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_data Pointer to data.
* @param[in] length Number of bytes to receive.
*
* @retval NRFX_SUCCESS Reception is complete (in case of blocking mode) or it is
* successfully started (in case of non-blocking mode).
* @retval NRFX_ERROR_BUSY The driver is already receiving
* (and the secondary buffer has already been set
* in non-blocking mode).
* @retval NRFX_ERROR_FORBIDDEN The transfer was aborted from a different context
* (blocking mode only, also see @ref nrfx_uart_rx_disable).
* @retval NRFX_ERROR_INTERNAL The UART peripheral reported an error.
*/
nrfx_err_t nrfx_uart_rx(nrfx_uart_t const * p_instance,
uint8_t * p_data,
size_t length);
/**
* @brief Function for testing the receiver state in blocking mode.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @retval true The receiver has at least one byte of data to get.
* @retval false The receiver is empty.
*/
bool nrfx_uart_rx_ready(nrfx_uart_t const * p_instance);
/**
* @brief Function for enabling the receiver.
*
* UART has a 6-byte-long RX FIFO and it is used to store incoming data. If a user does not call the
* UART receive function before the FIFO is filled, an overrun error will appear. The receiver must be
* explicitly closed by the user @sa nrfx_uart_rx_disable.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_uart_rx_enable(nrfx_uart_t const * p_instance);
/**
* @brief Function for disabling the receiver.
*
* This function must be called to close the receiver after it has been explicitly enabled by
* @sa nrfx_uart_rx_enable.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_uart_rx_disable(nrfx_uart_t const * p_instance);
/**
* @brief Function for aborting any ongoing reception.
* @note @ref NRFX_UART_EVT_TX_DONE event will be generated in non-blocking mode.
* It will contain number of bytes received until the abort was called. The event
* handler will be called from the UART interrupt context.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_uart_rx_abort(nrfx_uart_t const * p_instance);
/**
* @brief Function for reading error source mask. Mask contains values from @ref nrf_uart_error_mask_t.
* @note Function must be used in blocking mode only. In case of non-blocking mode, an error event is
* generated. Function clears error sources after reading.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return Mask of reported errors.
*/
uint32_t nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t nrfx_uart_task_address_get(nrfx_uart_t const * p_instance,
nrf_uart_task_t task)
{
return nrf_uart_task_address_get(p_instance->p_reg, task);
}
__STATIC_INLINE uint32_t nrfx_uart_event_address_get(nrfx_uart_t const * p_instance,
nrf_uart_event_t event)
{
return nrf_uart_event_address_get(p_instance->p_reg, event);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
void nrfx_uart_0_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_UART_H__
+359
View File
@@ -0,0 +1,359 @@
/**
* Copyright (c) 2015 - 2021, 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 NRFX_UARTE_H__
#define NRFX_UARTE_H__
#include <nrfx.h>
#include <hal/nrf_uarte.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_uarte UARTE driver
* @{
* @ingroup nrf_uarte
* @brief UARTE peripheral driver.
*/
/** @brief Structure for the UARTE driver instance. */
typedef struct
{
NRF_UARTE_Type * p_reg; ///< Pointer to a structure with UARTE registers.
uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
} nrfx_uarte_t;
#ifndef __NRFX_DOXYGEN__
enum {
#if NRFX_CHECK(NRFX_UARTE0_ENABLED)
NRFX_UARTE0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_UARTE1_ENABLED)
NRFX_UARTE1_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_UARTE2_ENABLED)
NRFX_UARTE2_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_UARTE3_ENABLED)
NRFX_UARTE3_INST_IDX,
#endif
NRFX_UARTE_ENABLED_COUNT
};
#endif
/** @brief Macro for creating a UARTE driver instance. */
#define NRFX_UARTE_INSTANCE(id) \
{ \
.p_reg = NRFX_CONCAT_2(NRF_UARTE, id), \
.drv_inst_idx = NRFX_CONCAT_3(NRFX_UARTE, id, _INST_IDX), \
}
/** @brief Types of UARTE driver events. */
typedef enum
{
NRFX_UARTE_EVT_TX_DONE, ///< Requested TX transfer completed.
NRFX_UARTE_EVT_RX_DONE, ///< Requested RX transfer completed.
NRFX_UARTE_EVT_ERROR, ///< Error reported by UART peripheral.
} nrfx_uarte_evt_type_t;
/** @brief Structure for the UARTE configuration. */
typedef struct
{
uint32_t pseltxd; ///< TXD pin number.
uint32_t pselrxd; ///< RXD pin number.
uint32_t pselcts; ///< CTS pin number.
uint32_t pselrts; ///< RTS pin number.
void * p_context; ///< Context passed to interrupt handler.
nrf_uarte_hwfc_t hwfc; ///< Flow control configuration.
nrf_uarte_parity_t parity; ///< Parity configuration.
nrf_uarte_baudrate_t baudrate; ///< Baud rate.
uint8_t interrupt_priority; ///< Interrupt priority.
} nrfx_uarte_config_t;
/** @brief UARTE default configuration. */
#define NRFX_UARTE_DEFAULT_CONFIG \
{ \
.pseltxd = NRF_UARTE_PSEL_DISCONNECTED, \
.pselrxd = NRF_UARTE_PSEL_DISCONNECTED, \
.pselcts = NRF_UARTE_PSEL_DISCONNECTED, \
.pselrts = NRF_UARTE_PSEL_DISCONNECTED, \
.p_context = NULL, \
.hwfc = (nrf_uarte_hwfc_t)NRFX_UARTE_DEFAULT_CONFIG_HWFC, \
.parity = (nrf_uarte_parity_t)NRFX_UARTE_DEFAULT_CONFIG_PARITY, \
.baudrate = (nrf_uarte_baudrate_t)NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE, \
.interrupt_priority = NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY, \
}
/** @brief Structure for the UARTE transfer completion event. */
typedef struct
{
uint8_t * p_data; ///< Pointer to memory used for transfer.
size_t bytes; ///< Number of bytes transfered.
} nrfx_uarte_xfer_evt_t;
/** @brief Structure for UARTE error event. */
typedef struct
{
nrfx_uarte_xfer_evt_t rxtx; ///< Transfer details, including number of bytes transferred.
uint32_t error_mask; ///< Mask of error flags that generated the event.
} nrfx_uarte_error_evt_t;
/** @brief Structure for UARTE event. */
typedef struct
{
nrfx_uarte_evt_type_t type; ///< Event type.
union
{
nrfx_uarte_xfer_evt_t rxtx; ///< Data provided for transfer completion events.
nrfx_uarte_error_evt_t error; ///< Data provided for error event.
} data; ///< Union to store event data.
} nrfx_uarte_event_t;
/**
* @brief UARTE interrupt event handler.
*
* @param[in] p_event Pointer to event structure. Event is allocated on the stack so it is available
* only within the context of the event handler.
* @param[in] p_context Context passed to the interrupt handler, set on initialization.
*/
typedef void (*nrfx_uarte_event_handler_t)(nrfx_uarte_event_t const * p_event,
void * p_context);
/**
* @brief Function for initializing the UARTE driver.
*
* This function configures and enables UARTE. After this function GPIO pins are controlled by UARTE.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] event_handler Event handler provided by the user. If not provided driver works in
* blocking mode.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE Driver is already initialized.
* @retval NRFX_ERROR_BUSY Some other peripheral with the same
* instance ID is already in use. This is
* possible only if @ref nrfx_prs module
* is enabled.
*/
nrfx_err_t nrfx_uarte_init(nrfx_uarte_t const * p_instance,
nrfx_uarte_config_t const * p_config,
nrfx_uarte_event_handler_t event_handler);
/**
* @brief Function for uninitializing the UARTE driver.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance);
/**
* @brief Function for getting the address of the specified UARTE task.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] task Task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_uarte_task_address_get(nrfx_uarte_t const * p_instance,
nrf_uarte_task_t task);
/**
* @brief Function for getting the address of the specified UARTE event.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] event Event.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_uarte_event_address_get(nrfx_uarte_t const * p_instance,
nrf_uarte_event_t event);
/**
* @brief Function for sending data over UARTE.
*
* If an event handler is provided in nrfx_uarte_init() call, this function
* returns immediately and the handler is called when the transfer is done.
* Otherwise, the transfer is performed in blocking mode, that is this function
* returns when the transfer is finished. Blocking mode is not using interrupt
* so there is no context switching inside the function.
*
* @note Peripherals using EasyDMA (including UARTE) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met,
* this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_data Pointer to data.
* @param[in] length Number of bytes to send. Maximum possible length is
* dependent on the used SoC (see the MAXCNT register
* description in the Product Specification). The driver
* checks it with assertion.
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_BUSY Driver is already transferring.
* @retval NRFX_ERROR_FORBIDDEN The transfer was aborted from a different context
* (blocking mode only).
* @retval NRFX_ERROR_INVALID_ADDR p_data does not point to RAM buffer.
*/
nrfx_err_t nrfx_uarte_tx(nrfx_uarte_t const * p_instance,
uint8_t const * p_data,
size_t length);
/**
* @brief Function for checking if UARTE is currently transmitting.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @retval true The UARTE is transmitting.
* @retval false The UARTE is not transmitting.
*/
bool nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance);
/**
* @brief Function for aborting any ongoing transmission.
* @note @ref NRFX_UARTE_EVT_TX_DONE event will be generated in non-blocking mode.
* It will contain number of bytes sent until the abort was called. The event
* handler will be called from the UARTE interrupt context.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance);
/**
* @brief Function for receiving data over UARTE.
*
* If an event handler is provided in the nrfx_uarte_init() call, this function
* returns immediately and the handler is called when the transfer is done.
* Otherwise, the transfer is performed in blocking mode, that is this function
* returns when the transfer is finished. Blocking mode is not using interrupt so
* there is no context switching inside the function.
* The receive buffer pointer is double-buffered in non-blocking mode. The secondary
* buffer can be set immediately after starting the transfer and will be filled
* when the primary buffer is full. The double-buffering feature allows
* receiving data continuously.
*
* @note Peripherals using EasyDMA (including UARTE) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met,
* this function fails with the error code NRFX_ERROR_INVALID_ADDR.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_data Pointer to data.
* @param[in] length Number of bytes to receive. Maximum possible length is
* dependent on the used SoC (see the MAXCNT register
* description in the Product Specification). The driver
* checks it with assertion.
*
* @retval NRFX_SUCCESS Initialization is successful.
* @retval NRFX_ERROR_BUSY The driver is already receiving
* (and the secondary buffer has already been set
* in non-blocking mode).
* @retval NRFX_ERROR_FORBIDDEN The transfer is aborted from a different context
* (blocking mode only).
* @retval NRFX_ERROR_INTERNAL The UARTE peripheral reports an error.
* @retval NRFX_ERROR_INVALID_ADDR p_data does not point to RAM buffer.
*/
nrfx_err_t nrfx_uarte_rx(nrfx_uarte_t const * p_instance,
uint8_t * p_data,
size_t length);
/**
* @brief Function for testing the receiver state in blocking mode.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @retval true The receiver has at least one byte of data to get.
* @retval false The receiver is empty.
*/
bool nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance);
/**
* @brief Function for aborting any ongoing reception.
* @note @ref NRFX_UARTE_EVT_RX_DONE event will be generated in non-blocking mode.
* It will contain number of bytes received until the abort was called. The event
* handler will be called from the UARTE interrupt context.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance);
/**
* @brief Function for reading error source mask. Mask contains values from @ref nrf_uarte_error_mask_t.
* @note Function must be used in the blocking mode only. In case of non-blocking mode, an error event is
* generated. Function clears error sources after reading.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @return Mask of reported errors.
*/
uint32_t nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t nrfx_uarte_task_address_get(nrfx_uarte_t const * p_instance,
nrf_uarte_task_t task)
{
return nrf_uarte_task_address_get(p_instance->p_reg, task);
}
__STATIC_INLINE uint32_t nrfx_uarte_event_address_get(nrfx_uarte_t const * p_instance,
nrf_uarte_event_t event)
{
return nrf_uarte_event_address_get(p_instance->p_reg, event);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
void nrfx_uarte_0_irq_handler(void);
void nrfx_uarte_1_irq_handler(void);
void nrfx_uarte_2_irq_handler(void);
void nrfx_uarte_3_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_UARTE_H__
+168
View File
@@ -0,0 +1,168 @@
/**
* Copyright (c) 2014 - 2021, 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 NRFX_WDT_H__
#define NRFX_WDT_H__
#include <nrfx.h>
#include <hal/nrf_wdt.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_wdt WDT driver
* @{
* @ingroup nrf_wdt
* @brief Watchdog Timer (WDT) peripheral driver.
*/
#if !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ) || defined(__NRFX_DOXYGEN__)
/** @brief WDT instance interrupt priority configuration. */
#define NRFX_WDT_IRQ_CONFIG .interrupt_priority = NRFX_WDT_CONFIG_IRQ_PRIORITY
#else
#define NRFX_WDT_IRQ_CONFIG
#endif
/**@brief Struct for WDT initialization. */
typedef struct
{
nrf_wdt_behaviour_t behaviour; /**< WDT behaviour when CPU in sleep/halt mode. */
uint32_t reload_value; /**< WDT reload value in ms. */
#if !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ) || defined(__NRFX_DOXYGEN__)
uint8_t interrupt_priority; /**< WDT interrupt priority */
#endif
} nrfx_wdt_config_t;
/** @brief WDT event handler function type. */
typedef void (*nrfx_wdt_event_handler_t)(void);
/** @brief WDT channel ID type. */
typedef nrf_wdt_rr_register_t nrfx_wdt_channel_id;
/** @brief WDT driver default configuration. */
#define NRFX_WDT_DEAFULT_CONFIG \
{ \
.behaviour = (nrf_wdt_behaviour_t)NRFX_WDT_CONFIG_BEHAVIOUR, \
.reload_value = NRFX_WDT_CONFIG_RELOAD_VALUE, \
NRFX_WDT_IRQ_CONFIG \
}
/**
* @brief This function initializes the watchdog.
*
* @param[in] p_config Pointer to the structure with the initial configuration.
* @param[in] wdt_event_handler Event handler provided by the user. Ignored when
* @ref NRFX_WDT_CONFIG_NO_IRQ option is enabled.
*
* @return NRFX_SUCCESS on success, otherwise an error code.
*/
nrfx_err_t nrfx_wdt_init(nrfx_wdt_config_t const * p_config,
nrfx_wdt_event_handler_t wdt_event_handler);
/**
* @brief Function for allocating a watchdog channel.
*
* @note This function can not be called after nrfx_wdt_start(void).
*
* @param[out] p_channel_id ID of granted channel.
*
* @return NRFX_SUCCESS on success, otherwise an error code.
*/
nrfx_err_t nrfx_wdt_channel_alloc(nrfx_wdt_channel_id * p_channel_id);
/**
* @brief Function for starting the watchdog.
*
* @note After calling this function the watchdog is started, so the user needs to feed all allocated
* watchdog channels to avoid reset. At least one watchdog channel must be allocated.
*/
void nrfx_wdt_enable(void);
/**
* @brief Function for feeding the watchdog.
*
* @details Function feeds all allocated watchdog channels.
*/
void nrfx_wdt_feed(void);
/**
* @brief Function for feeding an invidual watchdog channel.
*
* @param[in] channel_id ID of watchdog channel.
*/
void nrfx_wdt_channel_feed(nrfx_wdt_channel_id channel_id);
/**
* @brief Function for returning a requested task address for the WDT driver module.
*
* @param[in] task One of the peripheral tasks.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_wdt_ppi_task_addr(nrf_wdt_task_t task)
{
return nrf_wdt_task_address_get(task);
}
/**
* @brief Function for returning a requested event address for the wdt driver module.
*
* @param[in] event One of the peripheral events.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_wdt_ppi_event_addr(nrf_wdt_event_t event)
{
return nrf_wdt_event_address_get(event);
}
/** @} */
void nrfx_wdt_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif