Compare commits

...

2 commits

Author SHA1 Message Date
Scott Shawcroft
66628bc1b7
Merge pull request #6 from adafruit/merge-v2.1.0
merge v2.1.0 from upstream, preserving idempotent uninint()'s
2020-02-05 08:02:29 -08:00
Dan Halbert
e90319fd43 merge v2.1.0 from upstream, preserving idempotent uninint()'s 2020-02-05 09:22:33 -05:00
242 changed files with 19679 additions and 28352 deletions

View file

@ -1,6 +1,39 @@
# Changelog
All notable changes to this project are documented in this file.
## [2.1.0] - 2020-01-24
### Added
- Added HALs for DCNF, OSCILLATORS, USBREG, and VREQCTRL.
- Added support for 1-MHz clock frequency in TWIM.
- Introduced the NRFX_I2S_STATUS_TRANSFER_STOPPED flag in the I2S driver.
- Introduced the nrfx_power_compat layer that allows use of the nrfx_power API with new SoC.
- Added encryption support in the QSPI driver.
- Added support for USBD in nRF5340.
- Expanded HALs to cover new functions in nRF5340: GPIO, I2S, PDM, POWER, QSPI, and REGULATORS.
- Introduced new clock management system in the CLOCK driver.
- Introduced new audio clock configuration settings in the I2S and PDM drivers for nRF5340.
- Implemented workaround for nRF5340 anomaly 4 in the CLOCK driver.
- Implemented workaround for nRF5340 anomaly 10 in the CCM HAL.
- Implemented workaround for nRF9160 anomaly 21 and nRF5340 anomaly 6 in the NVMC HAL.
- Implemented workaround for nRF9160 anomaly 23 and nRF5340 anomaly 44 in the UARTE driver.
- Introduced the NRFX_TWIM_NO_SPURIOUS_STOP_CHECK flag in the TWIM driver.
- Added functions for getting shortcut configuration in the TWIM HAL.
### Changed
- Updated MDK to 8.30.2.
- Reorganized templates of nrfx_config header files for different SoCs. Now they are included through one common file according to the selected SoC.
- Improved the UARTE driver to consume less current after the driver uninitialization. Now all clocks are disabled properly after uninitialization.
- Improved the GPIOTE driver robustness by setting the LATCH functionality to be used by default.
- Changed names of the frequency divider symbols in the QSPI HAL to reflect the new frequencies in nRF5340. Old API names were preserved and are still supported.
- Improved spurious STOP condition handling in the TWIM driver.
- Improved sampling procedure in the advanced blocking mode in the SAADC driver.
- Improved calibration procedure in the SAADC driver for nRF5340 and nRF9160.
### Fixed
- Fixed address assertions in NVMC driver for the nRF5340 network core.
- Fixed an issue in the TWI driver that would make the driver stuck when a premature STOP condition was generated by a slave device. The driver now handles this situation properly and signals that a bus error occurred.
- Fixed the stopping procedure in the PWM driver. Previously in very specific circumstances the PWM output might be not stopped at all or might be immediately restarted.
## [2.0.0] - 2019-11-06
### Added
- Added support for nRF5340.

View file

@ -1,4 +1,4 @@
Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
All rights reserved.
Redistribution and use in source and binary forms, with or without

View file

@ -14,6 +14,7 @@ Driver | nRF51 Series | nRF52810/nRF52811 | nRF52832 | nRF52833
@ref nrf_clock |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |
@ref nrf_comp |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross |
@ref nrf_systick |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |
@ref nrf_dcnf |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagGreenTick |@tagRedCross |
@ref nrf_dppi |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagGreenTick |@tagGreenTick |
@ref nrf_ecb |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross |
@ref nrf_egu |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |
@ -52,7 +53,7 @@ Driver | nRF51 Series | nRF52810/nRF52811 | nRF52832 | nRF52833
@ref nrf_twis |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |
@ref nrf_uart |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross |@tagRedCross |
@ref nrf_uarte |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |
@ref nrf_usbd |@tagRedCross |@tagRedCross |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagRedCross |@tagRedCross |
@ref nrf_usbd |@tagRedCross |@tagRedCross |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross |
@ref nrf_vmc |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagGreenTick |@tagGreenTick |
@ref nrf_wdt |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |

View file

@ -72,8 +72,8 @@ in a file named:
This file, similarly to the integration files mentioned above, can be placed
in any suitable location within the host environment.
The <a href="../../templates/">templates</a> subfolder contains templates of
configuration files for all currently supported Nordic SoCs placed in respective
subfolders.
configuration files for all currently supported Nordic SoCs. These files are
included through a common nrfx_config.h file, according to the selected SoC.
Refer to the "driver configuration" section in the API reference for a given
driver for more information regarding configuration options available for it.

View file

@ -16,6 +16,8 @@
@ref nrf_systick
@ref nrf_dcnf
@ref nrf_dppi
@ref nrf_ecb
@ -78,6 +80,8 @@
@ref nrf_uarte
@ref nrf_usbd
@ref nrf_vmc
@ref nrf_wdt

View file

@ -40,7 +40,7 @@ PROJECT_NAME = "nrfx"
### EDIT THIS ###
PROJECT_NUMBER = "2.0"
PROJECT_NUMBER = "2.1"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@ -236,8 +236,7 @@ TAB_SIZE = 4
# alias to insert a newline as if a physical newline was in the original file.
ALIASES = "tagGreenTick=@htmlonly<CENTER><font color= green>✔</font></CENTER>@endhtmlonly" \
"tagRedCross=@htmlonly<CENTER><font color= red>✖</font></CENTER>@endhtmlonly" \
"linkProductSpecification52=[nRF52840 Product Specification](http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52/dita/nrf52/chips/nrf52840_ps.html) or [nRF52832 Product Specification](http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52/dita/nrf52/chips/nrf52832_ps.html)"
"tagRedCross=@htmlonly<CENTER><font color= red>✖</font></CENTER>@endhtmlonly"
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"

View file

@ -21,6 +21,8 @@
@defgroup nrf_systick Cortex-M Systick
@defgroup nrf_dcnf DCNF
@defgroup nrf_dppi DPPI
@defgroup nrf_ecb ECB

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -50,10 +50,12 @@ extern "C" {
/** @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_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_HFCLKAUDIO_STARTED, ///< HFCLKAUDIO has been started.
NRFX_CLOCK_EVT_HFCLK192M_STARTED, ///< HFCLK192M has been started.
} nrfx_clock_evt_type_t;
/**
@ -85,34 +87,137 @@ 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 starting the specified clock domain.
*
* @param[in] domain Clock domain.
*/
void nrfx_clock_start(nrf_clock_domain_t domain);
/** @brief Function for stopping the LFCLK. */
void nrfx_clock_lfclk_stop(void);
/**
* @brief Function for stopping the specified clock domain.
*
* @param[in] domain Clock domain.
*/
void nrfx_clock_stop(nrf_clock_domain_t domain);
/**
* @brief Function for checking the specified clock domain state.
*
* XTAL source is assumed for domains with multiple sources.
*
* @param[in] domain Clock domain.
* @param[out] clk_src Clock source that is running. Set to NULL if not needed.
* Ignored for HFCLKAUDIO domain. Typecast it to @ref nrf_clock_lfclk_t for
* LFCLK and @ref nrf_clock_hfclk_t for HFCLK and HFCLK192M.
*
* @retval true The clock domain is running.
* @retval false The clock domain is not running.
*/
NRFX_STATIC_INLINE bool nrfx_clock_is_running(nrf_clock_domain_t domain, void * clk_src);
#if NRF_CLOCK_HAS_HFCLK_DIV || NRF_CLOCK_HAS_HFCLK_192M
/**
* @brief Function for setting the specified clock domain divider.
*
* @param[in] domain Clock domain.
* @param[in] div New divider for the clock domain.
*
* @retval NRFX_SUCCESS Divider successfully set.
* @retval NRFX_ERROR_NOT_SUPPORTED Domain does not support setting the divider.
* @retval NRFX_ERROR_INVALID_PARAM Divider not supported by the specified domain.
*/
nrfx_err_t nrfx_clock_divider_set(nrf_clock_domain_t domain,
nrf_clock_hfclk_div_t div);
/**
* @brief Function for getting the specified clock domain divider.
*
* @param[in] domain Clock domain.
*
* @return Current divider for the specified clock domain.
*/
NRFX_STATIC_INLINE nrf_clock_hfclk_div_t nrfx_clock_divider_get(nrf_clock_domain_t domain);
#endif
/**
* @brief Function for starting the LFCLK.
*
* @note This function is deprecated. Use @ref nrfx_clock_start instead.
*/
NRFX_STATIC_INLINE void nrfx_clock_lfclk_start(void);
/**
* @brief Function for stopping the LFCLK.
*
* @note This function is deprecated. Use @ref nrfx_clock_stop instead.
*/
NRFX_STATIC_INLINE void nrfx_clock_lfclk_stop(void);
/**
* @brief Function for checking the LFCLK state.
*
* @note This function is deprecated. Use @ref nrfx_clock_is_running instead.
*
* @retval true The LFCLK is running.
* @retval false The LFCLK is not running.
*/
NRFX_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 starting the high-accuracy source HFCLK.
*
* @note This function is deprecated. Use @ref nrfx_clock_start instead.
*/
NRFX_STATIC_INLINE 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 stopping the external high-accuracy source HFCLK.
*
* @note This function is deprecated. Use @ref nrfx_clock_stop instead.
*/
NRFX_STATIC_INLINE void nrfx_clock_hfclk_stop(void);
/**
* @brief Function for checking the HFCLK state.
*
* @note This function is deprecated. Use @ref nrfx_clock_is_running instead.
*
* @retval true The HFCLK is running (XTAL source).
* @retval false The HFCLK is not running.
*/
NRFX_STATIC_INLINE bool nrfx_clock_hfclk_is_running(void);
#if NRF_CLOCK_HAS_HFCLKAUDIO
/**
* @brief Function for setting the HFCLKAUDIO configuration.
*
* The frequency of HFCLKAUDIO ranges from 10.666 MHz to 13.333 MHz in 40.7 Hz steps.
* To calculate @p freq_value corresponding to the chosen frequency, use the following equation:
* FREQ_VALUE = 2^16 * ((12 * f_out / 32M) - 4)
*
* @warning Chosen frequency must fit in 11.176 MHz - 11.402 MHz or 12.165 MHz - 12.411 MHz
* frequency bands.
*
* @param[in] freq_value New FREQ_VALUE for HFCLKAUDIO.
*/
NRFX_STATIC_INLINE void nrfx_clock_hfclkaudio_config_set(uint16_t freq_value);
/**
* @brief Function for getting the HFCLKAUDIO configuration.
*
* The frequency of HFCLKAUDIO ranges from 10.666 MHz to 13.333 MHz in 40.7 Hz steps.
* To calculate frequency corresponding to the returned FREQ_VALUE, use the following equation:
* f_out = 32M * (4 + FREQ_VALUE * 2^(-16))/12
*
* @return Current value of FREQ_VALUE for HFCLKAUDIO.
*/
NRFX_STATIC_INLINE uint16_t nrfx_clock_hfclkaudio_config_get(void);
#endif
/**
* @brief Function for starting the calibration of internal LFCLK.
*
@ -161,8 +266,48 @@ NRFX_STATIC_INLINE uint32_t nrfx_clock_ppi_task_addr(nrf_clock_task_t task);
*/
NRFX_STATIC_INLINE uint32_t nrfx_clock_ppi_event_addr(nrf_clock_event_t event);
#ifndef NRFX_DECLARE_ONLY
#if NRF_CLOCK_HAS_HFCLK_DIV || NRF_CLOCK_HAS_HFCLK_192M
NRFX_STATIC_INLINE nrf_clock_hfclk_div_t nrfx_clock_divider_get(nrf_clock_domain_t domain)
{
switch (domain)
{
#if NRF_CLOCK_HAS_HFCLK_DIV
case NRF_CLOCK_DOMAIN_HFCLK:
return nrf_clock_hfclk_div_get(NRF_CLOCK);
#endif
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
return nrf_clock_hfclk192m_div_get(NRF_CLOCK);
#endif
default:
NRFX_ASSERT(0);
return 0;
}
}
#endif // NRF_CLOCK_HAS_HFCLK_DIV || NRF_CLOCK_HAS_HFCLK_192M
NRFX_STATIC_INLINE void nrfx_clock_lfclk_start(void)
{
nrfx_clock_start(NRF_CLOCK_DOMAIN_LFCLK);
}
NRFX_STATIC_INLINE void nrfx_clock_lfclk_stop(void)
{
nrfx_clock_stop(NRF_CLOCK_DOMAIN_LFCLK);
}
NRFX_STATIC_INLINE void nrfx_clock_hfclk_start(void)
{
nrfx_clock_start(NRF_CLOCK_DOMAIN_HFCLK);
}
NRFX_STATIC_INLINE void nrfx_clock_hfclk_stop(void)
{
nrfx_clock_stop(NRF_CLOCK_DOMAIN_HFCLK);
}
NRFX_STATIC_INLINE uint32_t nrfx_clock_ppi_task_addr(nrf_clock_task_t task)
{
return nrf_clock_task_address_get(NRF_CLOCK, task);
@ -173,15 +318,37 @@ NRFX_STATIC_INLINE uint32_t nrfx_clock_ppi_event_addr(nrf_clock_event_t event)
return nrf_clock_event_address_get(NRF_CLOCK, event);
}
NRFX_STATIC_INLINE bool nrfx_clock_is_running(nrf_clock_domain_t domain, void * clk_src)
{
return nrf_clock_is_running(NRF_CLOCK, domain, clk_src);
}
NRFX_STATIC_INLINE bool nrfx_clock_hfclk_is_running(void)
{
return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY);
nrf_clock_hfclk_t clk_src;
bool ret = nrfx_clock_is_running(NRF_CLOCK_DOMAIN_HFCLK, &clk_src);
return (ret && (clk_src == NRF_CLOCK_HFCLK_HIGH_ACCURACY));
}
NRFX_STATIC_INLINE bool nrfx_clock_lfclk_is_running(void)
{
return nrf_clock_lf_is_running(NRF_CLOCK);
return nrfx_clock_is_running(NRF_CLOCK_DOMAIN_LFCLK, NULL);
}
#if NRF_CLOCK_HAS_HFCLKAUDIO
NRFX_STATIC_INLINE void nrfx_clock_hfclkaudio_config_set(uint16_t freq_value)
{
nrf_clock_hfclkaudio_config_set(NRF_CLOCK, freq_value);
}
NRFX_STATIC_INLINE uint16_t nrfx_clock_hfclkaudio_config_get(void)
{
return nrf_clock_hfclkaudio_config_get(NRF_CLOCK);
}
#endif
#endif // NRFX_DECLARE_ONLY
/** @} */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -69,13 +69,17 @@ typedef struct
* if this signal is not needed. */
uint8_t irq_priority; ///< Interrupt priority.
nrf_i2s_mode_t mode; ///< Mode of operation.
nrf_i2s_format_t format; ///< Frame format.
nrf_i2s_align_t alignment; ///< Alignment of sample within a frame.
nrf_i2s_swidth_t sample_width; ///< Sample width.
nrf_i2s_channels_t channels; ///< Enabled channels.
nrf_i2s_mck_t mck_setup; ///< Master clock setup.
nrf_i2s_ratio_t ratio; ///< MCK/LRCK ratio.
nrf_i2s_mode_t mode; ///< Mode of operation.
nrf_i2s_format_t format; ///< Frame format.
nrf_i2s_align_t alignment; ///< Alignment of sample within a frame.
nrf_i2s_swidth_t sample_width; ///< Sample width.
nrf_i2s_channels_t channels; ///< Enabled channels.
nrf_i2s_mck_t mck_setup; ///< Master clock setup.
nrf_i2s_ratio_t ratio; ///< MCK/LRCK ratio.
#if NRF_I2S_HAS_CLKCONFIG
nrf_i2s_clksrc_t clksrc; ///< Clock source selection.
bool enable_bypass; ///< Bypass clock generator. MCK will be equal to source input.
#endif
} nrfx_i2s_config_t;
/** @brief I2S driver buffers structure. */
@ -85,6 +89,14 @@ typedef struct
uint32_t const * p_tx_buffer; ///< Pointer to the buffer with data to be sent.
} nrfx_i2s_buffers_t;
#if NRF_I2S_HAS_CLKCONFIG || defined(__NRFX_DOXYGEN__)
/** @brief I2S additional clock source configuration. */
#define NRF_I2S_DEFAULT_EXTENDED_CLKSRC_CONFIG \
.clksrc = NRF_I2S_CLKSRC_PCLK32M, \
.enable_bypass = false,
#else
#define NRF_I2S_DEFAULT_EXTENDED_CLKSRC_CONFIG
#endif
/**
* @brief I2S driver default configuration.
*
@ -118,15 +130,20 @@ typedef struct
.channels = NRF_I2S_CHANNELS_LEFT, \
.mck_setup = NRF_I2S_MCK_32MDIV8, \
.ratio = NRF_I2S_RATIO_32X, \
NRF_I2S_DEFAULT_EXTENDED_CLKSRC_CONFIG \
}
#define NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED (1UL << 0)
#define NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED (1UL << 0)
/**< The application must provide buffers that are to be used in the next
* part of the transfer. A call to @ref nrfx_i2s_next_buffers_set must
* be done before the currently used buffers are completely processed
* (that is, the time remaining for supplying the next buffers depends on
* the used size of the buffers). */
#define NRFX_I2S_STATUS_TRANSFER_STOPPED (1UL << 1)
/**< The I2S peripheral has been stopped and all buffers that were passed
* to the driver have been released. */
/**
* @brief I2S driver data handler type.
*
@ -155,14 +172,22 @@ typedef struct
* Both pointers in this structure are NULL when the
* handler is called for the first time after a transfer
* is started, because no data has been transferred yet
* at this point. In all successive calls the pointers
* at this point. In all successive calls, the pointers
* specify what has been sent (TX) and what has been
* received (RX) in the part of transfer that has just
* been completed (provided that a given direction is
* enabled, see @ref nrfx_i2s_start).
* received (RX) in the part of the transfer that has
* just been completed (provided that a given direction
* is enabled, see @ref nrfx_i2s_start).
* @note Since the peripheral is stopped asynchronously,
* buffers that are released after the call to
* @ref nrfx_i2s_stop are not used entirely.
* In this case, only a part (if any) of the TX
* buffer has been actually transmitted and only
* a part (if any) of the RX buffer is filled with
* received data.
* @param[in] status Bit field describing the current status of the transfer.
* It can be 0 or a combination of the following flags:
* - @ref NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED
* - @ref NRFX_I2S_STATUS_TRANSFER_STOPPED
*/
typedef void (* nrfx_i2s_data_handler_t)(nrfx_i2s_buffers_t const * p_released,
uint32_t status);
@ -198,7 +223,7 @@ void nrfx_i2s_uninit(void);
* word can either contain four 8-bit samples, two 16-bit samples, or one
* right-aligned 24-bit sample sign-extended to a 32-bit value.
* For a detailed memory mapping for different supported configurations,
* see the @linkProductSpecification52.
* see the Product Specification.
*
* @note Peripherals using EasyDMA (including I2S) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -70,7 +70,7 @@ typedef struct
*
* @param[in] _input Comparator input pin.
*/
#ifdef NRF52_SERIES
#if defined(LPCOMP_FEATURE_HYST_PRESENT)
#define NRFX_LPCOMP_DEFAULT_CONFIG(_input) \
{ \
.hal = { NRF_LPCOMP_REF_SUPPLY_4_8, \

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -67,16 +67,39 @@ typedef struct
/** @brief PDM interface driver configuration structure. */
typedef struct
{
nrf_pdm_mode_t mode; ///< Interface operation mode.
nrf_pdm_edge_t edge; ///< Sampling mode.
uint8_t pin_clk; ///< CLK pin.
uint8_t pin_din; ///< DIN pin.
nrf_pdm_freq_t clock_freq; ///< Clock frequency.
nrf_pdm_gain_t gain_l; ///< Left channel gain.
nrf_pdm_gain_t gain_r; ///< Right channel gain.
uint8_t interrupt_priority; ///< Interrupt priority.
nrf_pdm_mode_t mode; ///< Interface operation mode.
nrf_pdm_edge_t edge; ///< Sampling mode.
uint8_t pin_clk; ///< CLK pin.
uint8_t pin_din; ///< DIN pin.
nrf_pdm_freq_t clock_freq; ///< Clock frequency.
nrf_pdm_gain_t gain_l; ///< Left channel gain.
nrf_pdm_gain_t gain_r; ///< Right channel gain.
uint8_t interrupt_priority; ///< Interrupt priority.
#if NRF_PDM_HAS_RATIO_CONFIG
nrf_pdm_ratio_t ratio; ///< Ratio between PDM_CLK and output sample rate.
#endif
#if NRF_PDM_HAS_MCLKCONFIG
nrf_pdm_mclksrc_t mclksrc; ///< Master clock source selection.
#endif
} nrfx_pdm_config_t;
#if NRF_PDM_HAS_RATIO_CONFIG || defined(__NRFX_DOXYGEN__)
/** @brief PDM additional ratio configuration. */
#define NRFX_PDM_DEFAULT_EXTENDED_RATIO_CONFIG \
.ratio = NRF_PDM_RATIO_64X,
#else
#define NRFX_PDM_DEFAULT_EXTENDED_RATIO_CONFIG
#endif
#if NRF_PDM_HAS_MCLKCONFIG || defined(__NRFX_DOXYGEN__)
/** @brief PDM additional master clock source configuration. */
#define NRFX_PDM_DEFAULT_EXTENDED_MCLKSRC_CONFIG \
.mclksrc = NRF_PDM_MCLKSRC_PCLK32M,
#else
#define NRFX_PDM_DEFAULT_EXTENDED_MCLKSRC_CONFIG
#endif
/**
* @brief PDM driver default configuration.
*
@ -98,7 +121,9 @@ typedef struct
.clock_freq = NRF_PDM_FREQ_1032K, \
.gain_l = NRF_PDM_GAIN_DEFAULT, \
.gain_r = NRF_PDM_GAIN_DEFAULT, \
.interrupt_priority = NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY \
.interrupt_priority = NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY, \
NRFX_PDM_DEFAULT_EXTENDED_RATIO_CONFIG \
NRFX_PDM_DEFAULT_EXTENDED_MCLKSRC_CONFIG \
}
/**
@ -187,12 +212,12 @@ nrfx_err_t nrfx_pdm_buffer_set(int16_t * buffer, uint16_t buffer_length);
#ifndef NRFX_DECLARE_ONLY
NRFX_STATIC_INLINE uint32_t nrfx_pdm_task_address_get(nrf_pdm_task_t task)
{
return nrf_pdm_task_address_get(NRF_PDM, task);
return nrf_pdm_task_address_get(NRF_PDM0, task);
}
NRFX_STATIC_INLINE bool nrfx_pdm_enable_check(void)
{
return nrf_pdm_enable_check(NRF_PDM);
return nrf_pdm_enable_check(NRF_PDM0);
}
#endif // NRFX_DECLARE_ONLY

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -35,6 +35,7 @@
#include <nrfx.h>
#include <hal/nrf_power.h>
#include <nrfx_power_clock.h>
#include "nrfx_power_compat.h"
#ifdef __cplusplus
extern "C" {
@ -47,6 +48,29 @@ extern "C" {
* @brief POWER peripheral driver.
*/
#if NRF_POWER_HAS_POFCON || NRFX_CHECK(NRF_REGULATORS_HAS_POFCON) || defined(__NRFX_DOXYGEN__)
/** @brief Symbol indicating whether the power failure comparator is supported. */
#define NRFX_POWER_SUPPORTS_POFCON 1
#else
#define NRFX_POWER_SUPPORTS_POFCON 0
#endif
#if NRF_POWER_HAS_POFCON_VDDH || NRFX_CHECK(NRF_REGULATORS_HAS_POFCON_VDDH) || \
defined(__NRFX_DOXYGEN__)
/** @brief Symbol indicating whether the power failure comparator for VDDH is supported. */
#define NRFX_POWER_SUPPORTS_POFCON_VDDH 1
#else
#define NRFX_POWER_SUPPORTS_POFCON_VDDH 0
#endif
#if NRF_POWER_HAS_DCDCEN_VDDH || NRFX_CHECK(NRF_REGULATORS_HAS_DCDCEN_VDDH) || \
defined(__NRFX_DOXYGEN__)
/** @brief Symbol indicating whether the VDDH regulator is supported. */
#define NRFX_POWER_SUPPORTS_DCDCEN_VDDH 1
#else
#define NRFX_POWER_SUPPORTS_DCDCEN_VDDH 0
#endif
/**
* @brief Power mode possible configurations
*/
@ -96,7 +120,7 @@ typedef enum
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 */
#endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @name Callback types
@ -145,7 +169,7 @@ typedef struct
*/
bool dcdcen:1;
#if NRF_POWER_HAS_VDDH || defined(__NRFX_DOXYGEN__)
#if NRFX_POWER_SUPPORTS_DCDCEN_VDDH
/**
* @brief Enable HV DCDC regulator.
*
@ -166,10 +190,10 @@ typedef struct
typedef struct
{
nrfx_power_pofwarn_event_handler_t handler; //!< Event handler.
#if NRF_POWER_HAS_POFCON || defined(__NRFX_DOXYGEN__)
#if NRFX_POWER_SUPPORTS_POFCON
nrf_power_pof_thr_t thr; //!< Threshold for power failure detection
#endif
#if NRF_POWER_HAS_VDDH || defined(__NRFX_DOXYGEN__)
#if NRFX_POWER_SUPPORTS_POFCON_VDDH
nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on the VDDH pin.
#endif
}nrfx_power_pofwarn_config_t;
@ -198,7 +222,7 @@ typedef struct
{
nrfx_power_usb_event_handler_t handler; //!< Event processing.
}nrfx_power_usbevt_config_t;
#endif /* NRF_POWER_HAS_USBREG */
#endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the handler of the power failure comparator.
@ -212,7 +236,7 @@ nrfx_power_pofwarn_event_handler_t nrfx_power_pof_handler_get(void);
* @return Handler of the USB power.
*/
nrfx_power_usb_event_handler_t nrfx_power_usb_handler_get(void);
#endif
#endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for initializing the power module driver.
@ -235,7 +259,7 @@ nrfx_err_t nrfx_power_init(nrfx_power_config_t const * p_config);
*/
void nrfx_power_uninit(void);
#if NRF_POWER_HAS_POFCON || defined(__NRFX_DOXYGEN__)
#if NRFX_POWER_SUPPORTS_POFCON
/**
* @brief Function for initializing the power failure comparator.
*
@ -271,7 +295,7 @@ void nrfx_power_pof_disable(void);
* Clears the settings of the power failure comparator.
*/
void nrfx_power_pof_uninit(void);
#endif // NRF_POWER_HAS_POFCON || defined(__NRFX_DOXYGEN__)
#endif // NRFX_POWER_SUPPORTS_POFCON
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
@ -336,7 +360,7 @@ void nrfx_power_usbevt_uninit(void);
*/
NRFX_STATIC_INLINE nrfx_power_usb_state_t nrfx_power_usbstatus_get(void);
#endif /* NRF_POWER_HAS_USBREG */
#endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
#ifndef NRFX_DECLARE_ONLY
#if NRF_POWER_HAS_USBREG
@ -353,8 +377,8 @@ NRFX_STATIC_INLINE nrfx_power_usb_state_t nrfx_power_usbstatus_get(void)
}
return NRFX_POWER_USB_STATE_READY;
}
#endif /* NRF_POWER_HAS_USBREG */
#endif /* NRFX_DECLARE_ONLY */
#endif // NRF_POWER_HAS_USBREG
#endif // NRFX_DECLARE_ONLY
/** @} */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NRFX_POWER_COMPAT_H__
#define NRFX_POWER_COMPAT_H__
/**
* POWER compatibility layer.
*
* The following definitions allow using of common code involving the POWER peripheral
* driver for different SoCs, regardless of whether certain regulator registers
* are located in the POWER peripheral or in separate peripherals like USBREG and REGULATORS.
*/
#if defined(REGULATORS_PRESENT)
#include <hal/nrf_regulators.h>
#endif
#if NRF_REGULATORS_HAS_POFCON
typedef nrf_regulators_pof_thr_t nrf_power_pof_thr_t;
#define NRF_POWER_POFTHR_V19 NRF_REGULATORS_POFTHR_V19
#define NRF_POWER_POFTHR_V20 NRF_REGULATORS_POFTHR_V20
#define NRF_POWER_POFTHR_V21 NRF_REGULATORS_POFTHR_V21
#define NRF_POWER_POFTHR_V22 NRF_REGULATORS_POFTHR_V22
#define NRF_POWER_POFTHR_V23 NRF_REGULATORS_POFTHR_V23
#define NRF_POWER_POFTHR_V24 NRF_REGULATORS_POFTHR_V24
#define NRF_POWER_POFTHR_V25 NRF_REGULATORS_POFTHR_V25
#define NRF_POWER_POFTHR_V26 NRF_REGULATORS_POFTHR_V26
#define NRF_POWER_POFTHR_V27 NRF_REGULATORS_POFTHR_V27
#define NRF_POWER_POFTHR_V28 NRF_REGULATORS_POFTHR_V28
typedef nrf_regulators_pof_thrvddh_t nrf_power_pof_thrvddh_t;
#define NRF_POWER_POFTHRVDDH_V27 NRF_REGULATORS_POFTHRVDDH_V27
#define NRF_POWER_POFTHRVDDH_V28 NRF_REGULATORS_POFTHRVDDH_V28
#define NRF_POWER_POFTHRVDDH_V29 NRF_REGULATORS_POFTHRVDDH_V29
#define NRF_POWER_POFTHRVDDH_V30 NRF_REGULATORS_POFTHRVDDH_V30
#define NRF_POWER_POFTHRVDDH_V31 NRF_REGULATORS_POFTHRVDDH_V31
#define NRF_POWER_POFTHRVDDH_V32 NRF_REGULATORS_POFTHRVDDH_V32
#define NRF_POWER_POFTHRVDDH_V33 NRF_REGULATORS_POFTHRVDDH_V33
#define NRF_POWER_POFTHRVDDH_V34 NRF_REGULATORS_POFTHRVDDH_V34
#define NRF_POWER_POFTHRVDDH_V35 NRF_REGULATORS_POFTHRVDDH_V35
#define NRF_POWER_POFTHRVDDH_V36 NRF_REGULATORS_POFTHRVDDH_V36
#define NRF_POWER_POFTHRVDDH_V37 NRF_REGULATORS_POFTHRVDDH_V37
#define NRF_POWER_POFTHRVDDH_V38 NRF_REGULATORS_POFTHRVDDH_V38
#define NRF_POWER_POFTHRVDDH_V39 NRF_REGULATORS_POFTHRVDDH_V39
#define NRF_POWER_POFTHRVDDH_V40 NRF_REGULATORS_POFTHRVDDH_V40
#define NRF_POWER_POFTHRVDDH_V41 NRF_REGULATORS_POFTHRVDDH_V41
#define NRF_POWER_POFTHRVDDH_V42 NRF_REGULATORS_POFTHRVDDH_V42
#endif // NRF_REGULATORS_HAS_POFCON
#if defined(USBREG_PRESENT)
#include "nrfx_usbreg.h"
typedef nrfx_usbreg_event_handler_t nrfx_power_usb_event_handler_t;
typedef nrfx_usbreg_config_t nrfx_power_usbevt_config_t;
typedef nrfx_usbreg_evt_t nrfx_power_usb_evt_t;
#define NRFX_POWER_USB_EVT_DETECTED NRFX_USBREG_EVT_DETECTED
#define NRFX_POWER_USB_EVT_REMOVED NRFX_USBREG_EVT_REMOVED
#define NRFX_POWER_USB_EVT_READY NRFX_USBREG_EVT_READY
typedef nrfx_usbreg_state_t nrfx_power_usb_state_t;
#define NRFX_POWER_USB_STATE_DISCONNECTED NRFX_USBREG_STATE_DISCONNECTED
#define NRFX_POWER_USB_STATE_CONNECTED NRFX_USBREG_STATE_CONNECTED
#define NRFX_POWER_USB_STATE_READY NRFX_USBREG_STATE_READY
#define nrfx_power_usb_handler_get nrfx_usbreg_handler_get
#define nrfx_power_usbevt_init nrfx_usbreg_init
#define nrfx_power_usbevt_enable nrfx_usbreg_enable
#define nrfx_power_usbevt_disable nrfx_usbreg_disable
#define nrfx_power_usbevt_uninit nrfx_usbreg_uninit
#define nrfx_power_usbstatus_get nrfx_usbreg_usbstatus_get
#endif // defined(USBREG_PRESENT)
#endif // NRFX_POWER_COMPAT_H__

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -100,6 +100,10 @@ typedef struct
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.
bool skip_gpio_cfg; ///< Skip the GPIO configuration
/**< When this flag is set, the user is responsible for
* providing the proper configuration of the output pins,
* as the driver does not touch it at all. */
} nrfx_pwm_config_t;
/**
@ -117,19 +121,20 @@ typedef struct
* @param[in] _out_2 PWM output 2 pin.
* @param[in] _out_3 PWM output 3 pin.
*/
#define NRFX_PWM_DEFAULT_CONFIG(_out_0, _out_1, _out_2, _out_3) \
{ \
.output_pins = { _out_0, \
_out_1, \
_out_2, \
_out_3 \
}, \
.irq_priority = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY, \
.base_clock = NRF_PWM_CLK_1MHz, \
.count_mode = NRF_PWM_MODE_UP, \
.top_value = 1000, \
.load_mode = NRF_PWM_LOAD_COMMON, \
.step_mode = NRF_PWM_STEP_AUTO, \
#define NRFX_PWM_DEFAULT_CONFIG(_out_0, _out_1, _out_2, _out_3) \
{ \
.output_pins = { _out_0, \
_out_1, \
_out_2, \
_out_3 \
}, \
.irq_priority = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY, \
.base_clock = NRF_PWM_CLK_1MHz, \
.count_mode = NRF_PWM_MODE_UP, \
.top_value = 1000, \
.load_mode = NRF_PWM_LOAD_COMMON, \
.step_mode = NRF_PWM_STEP_AUTO, \
.skip_gpio_cfg = false \
}
/** @brief PWM flags providing additional playback options. */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -66,7 +66,7 @@ typedef struct
* - PP opcode for writing
* - 24 bit addressing mode
* - Deep Power-down disabled
* - clock frequency 2 MHz
* - clock frequency: 2 MHz for nRF52 Series, 6 MHz for nRF53 Series
* - SCK delay 5 clock ticks
* - mode 0 (data captured on the clock rising edge and transmitted on a falling edge. Clock base level is '0')
*
@ -99,7 +99,7 @@ typedef struct
.sck_delay = 0x05, \
.dpmen = false, \
.spi_mode = NRF_QSPI_MODE_0, \
.sck_freq = NRF_QSPI_FREQ_32MDIV16, \
.sck_freq = NRF_QSPI_FREQ_DIV16, \
}, \
.irq_priority = (uint8_t)NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY, \
}
@ -329,6 +329,32 @@ nrfx_err_t nrfx_qspi_lfm_xfer(void const * p_tx_buffer,
size_t transfer_length,
bool finalize);
#if NRF_QSPI_HAS_XIP_ENC
/**
* @brief Function for setting the XIP encryption.
*
* @param[in] p_config XIP encryption configuration structure.
* To disable encryption, pass NULL pointer as argument.
*
* @retval NRFX_SUCCESS Operation was successful.
* @retval NRFX_ERROR_BUSY Driver currently handles other operation.
*/
nrfx_err_t nrfx_qspi_xip_encrypt(nrf_qspi_encryption_t const * p_config);
#endif
#if NRF_QSPI_HAS_DMA_ENC
/**
* @brief Function for setting the EasyDMA encryption.
*
* @param[in] p_config DMA encryption configuration structure.
* To disable encryption, pass NULL pointer as argument.
*
* @retval NRFX_SUCCESS Operation was successful.
* @retval NRFX_ERROR_BUSY Driver currently handles other operation.
*/
nrfx_err_t nrfx_qspi_dma_encrypt(nrf_qspi_encryption_t const * p_config);
#endif
/** @} */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -116,6 +116,7 @@ typedef struct
* - clock frequency 4 MHz
* - mode 0 enabled (SCK active high, sample on leading edge of clock)
* - MSB shifted out first
* - MISO pull-up disabled
*
* @param[in] _pin_sck SCK pin.
* @param[in] _pin_mosi MOSI pin.
@ -133,6 +134,7 @@ typedef struct
.frequency = NRF_SPI_FREQ_4M, \
.mode = NRF_SPI_MODE_0, \
.bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST, \
.miso_pull = NRF_GPIO_PIN_NOPULL, \
}
/** @brief Single transfer descriptor structure. */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -67,6 +67,9 @@ enum {
#endif
#if NRFX_CHECK(NRFX_SPIM3_ENABLED)
NRFX_SPIM3_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_SPIM4_ENABLED)
NRFX_SPIM4_INST_IDX,
#endif
NRFX_SPIM_ENABLED_COUNT
};
@ -391,6 +394,7 @@ 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);
void nrfx_spim_4_irq_handler(void);
#ifdef __cplusplus

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -117,7 +117,8 @@ 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_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. */
@ -265,7 +266,7 @@ void nrfx_twi_disable(nrfx_twi_t const * p_instance);
* @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 error is detected by hardware.
* @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

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -109,17 +109,19 @@ typedef struct
}
/** @brief Flag indicating that TX buffer address will be incremented after the transfer. */
#define NRFX_TWIM_FLAG_TX_POSTINC (1UL << 0)
#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)
#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)
#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)
#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)
#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)
#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
@ -272,6 +274,10 @@ void nrfx_twim_disable(nrfx_twim_t const * p_instance);
* 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:

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -0,0 +1,151 @@
/*
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NRFX_USBREG_H__
#define NRFX_USBREG_H__
#include <nrfx.h>
#include <hal/nrf_usbreg.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_usbreg USBREG driver
* @{
* @ingroup nrf_usbd
* @ingroup nrf_power
* @brief USB regulators (USBREG) peripheral driver.
*/
/** @brief Events from USB power system */
typedef enum {
NRFX_USBREG_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */
NRFX_USBREG_EVT_REMOVED, /**< USB power removed from the connector. */
NRFX_USBREG_EVT_READY /**< USB power regulator ready. */
} nrfx_usbreg_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_USBREG_STATE_DISCONNECTED, /**< No power on USB lines detected. */
NRFX_USBREG_STATE_CONNECTED, /**< The USB power is detected, but USB power regulator is not ready. */
NRFX_USBREG_STATE_READY /**< From the power viewpoint, USB is ready for working. */
} nrfx_usbreg_state_t;
/**
* @brief Event handler for the USB-related power events.
*
* @param event Event type
*/
typedef void (*nrfx_usbreg_event_handler_t)(nrfx_usbreg_evt_t event);
/**
* @brief The configuration of the USB-related power events.
*
* Configuration used to enable and configure USB power event handling.
*/
typedef struct
{
nrfx_usbreg_event_handler_t handler; //!< Event processing.
uint8_t irq_priority; //!< Priority of the USBREG interrupt.
} nrfx_usbreg_config_t;
/**
* @brief Function for getting the USBREG handler.
*
* @return Handler of the USB power.
*/
nrfx_usbreg_event_handler_t nrfx_usbreg_handler_get(void);
/**
* @brief Function for initializing the processing of USBREG events.
*
* Configures and sets up the USB power event processing.
*
* @param[in] p_config Configuration structure. Must not be NULL.
*
* @sa nrfx_usbreg_uninit
*/
void nrfx_usbreg_init(nrfx_usbreg_config_t const *p_config);
/** @brief Function for enabling the processing of USBREG events. */
void nrfx_usbreg_enable(void);
/** @brief Function for disabling the processing of USBREG events. */
void nrfx_usbreg_disable(void);
/**
* @brief Function for uninitalizing the processing of USBREG events.
*
* @sa nrfx_usbreg_init
*/
void nrfx_usbreg_uninit(void);
/**
* @brief Function for getting the status of USBREG.
*
* @return Current USB power status.
*/
NRFX_STATIC_INLINE nrfx_usbreg_state_t nrfx_usbreg_usbstatus_get(void);
#ifndef NRFX_DECLARE_ONLY
NRFX_STATIC_INLINE nrfx_usbreg_state_t nrfx_usbreg_usbstatus_get(void)
{
uint32_t status = nrf_usbreg_status_get(NRF_USBREGULATOR);
if (0 == (status & NRF_USBREG_STATUS_VBUSDETECT_MASK))
{
return NRFX_USBREG_STATE_DISCONNECTED;
}
if (0 == (status & NRF_USBREG_STATUS_OUTPUTRDY_MASK))
{
return NRFX_USBREG_STATE_CONNECTED;
}
return NRFX_USBREG_STATE_READY;
}
#endif // NRFX_DECLARE_ONLY
/** @} */
void nrfx_usbreg_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_USBREG_H__

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -39,10 +39,6 @@
extern "C" {
#endif
#ifndef NRF_WDT0
#define NRF_WDT0 NRF_WDT
#endif
/**
* @defgroup nrfx_wdt WDT driver
* @{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,6 +34,7 @@
#if NRFX_CHECK(NRFX_CLOCK_ENABLED)
#include <nrfx_clock.h>
#include <nrf_erratas.h>
#define NRFX_LOG_MODULE CLOCK
#include <nrfx_log.h>
@ -42,13 +43,6 @@
extern bool nrfx_power_irq_enabled;
#endif
#define EVT_TO_STR(event) \
(event == NRF_CLOCK_EVENT_HFCLKSTARTED ? "NRF_CLOCK_EVENT_HFCLKSTARTED" : \
(event == NRF_CLOCK_EVENT_LFCLKSTARTED ? "NRF_CLOCK_EVENT_LFCLKSTARTED" : \
(event == NRF_CLOCK_EVENT_DONE ? "NRF_CLOCK_EVENT_DONE" : \
(event == NRF_CLOCK_EVENT_CTTO ? "NRF_CLOCK_EVENT_CTTO" : \
"UNKNOWN EVENT"))))
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
#if (NRF_CLOCK_HAS_CALIBRATION == 0)
#error "Calibration is not available in the SoC that is used."
@ -180,7 +174,12 @@ void nrfx_clock_enable(void)
NRFX_ASSERT(m_clock_cb.module_initialized);
nrfx_power_clock_irq_init();
nrf_clock_lf_src_set(NRF_CLOCK, (nrf_clock_lfclk_t)NRFX_CLOCK_CONFIG_LF_SRC);
#if NRF_CLOCK_HAS_HFCLKSRC
nrf_clock_hf_src_set(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY);
#endif
#if NRF_CLOCK_HAS_HFCLK192M
nrf_clock_hfclk192m_src_set(NRF_CLOCK, (nrf_clock_hfclk_t)NRFX_CLOCK_CONFIG_HFCLK192M_SRC);
#endif
#if NRFX_CHECK(NRFX_POWER_ENABLED)
nrfx_clock_irq_enabled = true;
#endif
@ -202,8 +201,10 @@ void nrfx_clock_disable(void)
CLOCK_INTENSET_LFCLKSTARTED_Msk |
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
CLOCK_INTENSET_DONE_Msk |
#if NRF_HAS_CALIBRATION_TIMER
CLOCK_INTENSET_CTTO_Msk |
#endif
#endif // NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
0);
#if NRFX_CHECK(NRFX_POWER_ENABLED)
nrfx_clock_irq_enabled = false;
@ -217,49 +218,97 @@ void nrfx_clock_uninit(void)
{
return;
}
nrfx_clock_lfclk_stop();
nrfx_clock_hfclk_stop();
nrfx_clock_stop(NRF_CLOCK_DOMAIN_LFCLK);
nrfx_clock_stop(NRF_CLOCK_DOMAIN_HFCLK);
#if NRF_CLOCK_HAS_HFCLK192M
nrfx_clock_stop(NRF_CLOCK_DOMAIN_HFCLK192M);
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
nrfx_clock_stop(NRF_CLOCK_DOMAIN_HFCLKAUDIO);
#endif
m_clock_cb.module_initialized = false;
NRFX_LOG_INFO("Uninitialized.");
}
void nrfx_clock_lfclk_start(void)
void nrfx_clock_start(nrf_clock_domain_t domain)
{
NRFX_ASSERT(m_clock_cb.module_initialized);
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_LFCLKSTARTED);
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_LF_STARTED_MASK);
switch (domain)
{
case NRF_CLOCK_DOMAIN_LFCLK:
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_LFCLKSTARTED);
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_LF_STARTED_MASK);
#if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_132)
nrfx_clock_anomaly_132();
nrfx_clock_anomaly_132();
#endif
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART);
break;
case NRF_CLOCK_DOMAIN_HFCLK:
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED);
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_HF_STARTED_MASK);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART);
break;
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLK192MSTARTED);
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_HF192M_STARTED_MASK);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLK192MSTART);
break;
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
case NRF_CLOCK_DOMAIN_HFCLKAUDIO:
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKAUDIOSTARTED);
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_HFAUDIO_STARTED_MASK);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKAUDIOSTART);
break;
#endif
default:
NRFX_ASSERT(0);
break;
}
}
void nrfx_clock_lfclk_stop(void)
void nrfx_clock_stop(nrf_clock_domain_t domain)
{
NRFX_ASSERT(m_clock_cb.module_initialized);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP);
while (nrf_clock_lf_is_running(NRF_CLOCK))
{}
}
void nrfx_clock_hfclk_start(void)
{
NRFX_ASSERT(m_clock_cb.module_initialized);
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED);
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_HF_STARTED_MASK);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART);
}
void nrfx_clock_hfclk_stop(void)
{
NRFX_ASSERT(m_clock_cb.module_initialized);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP);
while (nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY))
{}
switch (domain)
{
case NRF_CLOCK_DOMAIN_LFCLK:
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP);
break;
case NRF_CLOCK_DOMAIN_HFCLK:
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP);
break;
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLK192MSTOP);
break;
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
case NRF_CLOCK_DOMAIN_HFCLKAUDIO:
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKAUDIOSTOP);
break;
#endif
default:
NRFX_ASSERT(0);
return;
}
if (domain == NRF_CLOCK_DOMAIN_HFCLK)
{
nrf_clock_hfclk_t clk_src = NRF_CLOCK_HFCLK_HIGH_ACCURACY;
while (nrfx_clock_is_running(domain, &clk_src) && (clk_src == NRF_CLOCK_HFCLK_HIGH_ACCURACY))
{}
}
else
{
while (nrfx_clock_is_running(domain, NULL))
{}
}
#if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_201)
m_clock_cb.hfclk_started = false;
if (domain == NRF_CLOCK_DOMAIN_HFCLK)
{
m_clock_cb.hfclk_started = false;
}
#endif
}
@ -268,12 +317,18 @@ nrfx_err_t nrfx_clock_calibration_start(void)
nrfx_err_t err_code = NRFX_SUCCESS;
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
if (nrfx_clock_hfclk_is_running() == false)
nrf_clock_hfclk_t clk_src;
if (!nrfx_clock_is_running(NRF_CLOCK_DOMAIN_HFCLK, &clk_src))
{
return NRFX_ERROR_INVALID_STATE;
}
if (nrfx_clock_lfclk_is_running() == false)
if (clk_src != NRF_CLOCK_HFCLK_HIGH_ACCURACY)
{
return NRFX_ERROR_INVALID_STATE;
}
if (!nrfx_clock_is_running(NRF_CLOCK_DOMAIN_LFCLK, NULL))
{
return NRFX_ERROR_INVALID_STATE;
}
@ -313,7 +368,7 @@ nrfx_err_t nrfx_clock_is_calibrating(void)
void nrfx_clock_calibration_timer_start(uint8_t interval)
{
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED) && NRF_CLOCK_HAS_CALIBRATION_TIMER
nrf_clock_cal_timer_timeout_set(NRF_CLOCK, interval);
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_CTTO);
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_CTTO_MASK);
@ -323,18 +378,80 @@ void nrfx_clock_calibration_timer_start(uint8_t interval)
void nrfx_clock_calibration_timer_stop(void)
{
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED) && NRF_CLOCK_HAS_CALIBRATION_TIMER
nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_CTTO_MASK);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_CTSTOP);
#endif
}
#if NRF_CLOCK_HAS_HFCLK_DIV || NRF_CLOCK_HAS_HFCLK192M
nrfx_err_t nrfx_clock_divider_set(nrf_clock_domain_t domain,
nrf_clock_hfclk_div_t div)
{
switch(domain)
{
#if NRF_CLOCK_HAS_HFCLK_DIV
case NRF_CLOCK_DOMAIN_HFCLK:
switch (div)
{
case NRF_CLOCK_HFCLK_DIV_2:
NRFX_CRITICAL_SECTION_ENTER();
if (nrf53_errata_4())
{
__DSB();
}
nrf_clock_hfclk_div_set(NRF_CLOCK, div);
if (nrf53_errata_4())
{
*(volatile uint32_t *)0x5084450C = 0x0;
*(volatile uint32_t *)0x50026548 = 0x0;
*(volatile uint32_t *)0x50081EE4 = 0x0D;
}
NRFX_CRITICAL_SECTION_EXIT();
break;
case NRF_CLOCK_HFCLK_DIV_1:
NRFX_CRITICAL_SECTION_ENTER();
if (nrf53_errata_4())
{
__DSB();
*(volatile uint32_t *)0x5084450C = 0x4040;
*(volatile uint32_t *)0x50026548 = 0x40;
*(volatile uint32_t *)0x50081EE4 = 0x4D;
}
nrf_clock_hfclk_div_set(NRF_CLOCK, div);
NRFX_CRITICAL_SECTION_EXIT();
break;
default:
return NRFX_ERROR_INVALID_PARAM;
}
SystemCoreClockUpdate();
return NRFX_SUCCESS;
#endif
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
if (div > NRF_CLOCK_HFCLK_DIV_4)
{
return NRFX_ERROR_INVALID_PARAM;
}
else
{
nrf_clock_hfclk192m_div_set(NRF_CLOCK, div);
}
return NRFX_SUCCESS;
#endif
default:
NRFX_ASSERT(0);
return NRFX_ERROR_NOT_SUPPORTED;
}
}
#endif
void nrfx_clock_irq_handler(void)
{
if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED))
{
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED);
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_HFCLKSTARTED));
NRFX_LOG_DEBUG("Event: NRF_CLOCK_EVENT_HFCLKSTARTED");
nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_HF_STARTED_MASK);
#if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_201)
@ -350,21 +467,23 @@ void nrfx_clock_irq_handler(void)
if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_LFCLKSTARTED))
{
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_LFCLKSTARTED);
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_LFCLKSTARTED));
NRFX_LOG_DEBUG("Event: NRF_CLOCK_EVENT_LFCLKSTARTED");
nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_LF_STARTED_MASK);
m_clock_cb.event_handler(NRFX_CLOCK_EVT_LFCLK_STARTED);
}
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
#if NRF_CLOCK_HAS_CALIBRATION_TIMER
if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_CTTO))
{
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_CTTO);
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_CTTO));
NRFX_LOG_DEBUG("Event: NRF_CLOCK_EVENT_CTTO");
nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_CTTO_MASK);
m_clock_cb.event_handler(NRFX_CLOCK_EVT_CTTO);
}
#endif // NRF_CLOCK_HAS_CALIBRATION_TIMER
if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_DONE))
{
@ -372,12 +491,34 @@ void nrfx_clock_irq_handler(void)
*(volatile uint32_t *)0x40000C34 = 0x00000000;
#endif
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_DONE);
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_DONE));
NRFX_LOG_DEBUG("Event: NRF_CLOCK_EVENT_DONE");
nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_DONE_MASK);
m_clock_cb.cal_state = CAL_STATE_IDLE;
m_clock_cb.event_handler(NRFX_CLOCK_EVT_CAL_DONE);
}
#endif // NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
#endif // NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
#if NRF_CLOCK_HAS_HFCLKAUDIO
if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKAUDIOSTARTED))
{
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKAUDIOSTARTED);
NRFX_LOG_DEBUG("Event: NRF_CLOCK_EVENT_HFCLKAUDIOSTARTED");
nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_HFAUDIO_STARTED_MASK);
m_clock_cb.event_handler(NRFX_CLOCK_EVT_HFCLKAUDIO_STARTED);
}
#endif
#if NRF_CLOCK_HAS_HFCLK192M
if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLK192MSTARTED))
{
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLK192MSTARTED);
NRFX_LOG_DEBUG("Event: NRF_CLOCK_EVENT_HFCLK192MSTARTED");
nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_HF192M_STARTED_MASK);
m_clock_cb.event_handler(NRFX_CLOCK_EVT_HFCLK192M_STARTED);
}
#endif
}
#endif // NRFX_CHECK(NRFX_CLOCK_ENABLED)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -44,11 +44,11 @@
#define PIN_NOT_USED (-1)
#define PIN_USED (-2)
#define NO_CHANNELS (-1)
#define SENSE_FIELD_POS (6)
#define SENSE_FIELD_MASK (0xC0)
#define POLARITY_FIELD_POS (6)
#define POLARITY_FIELD_MASK (0xC0)
/* Check if every pin can be encoded on provided number of bits. */
NRFX_STATIC_ASSERT(NUMBER_OF_PINS <= (1 << SENSE_FIELD_POS));
NRFX_STATIC_ASSERT(NUMBER_OF_PINS <= (1 << POLARITY_FIELD_POS));
/*lint -save -e571*/ /* Suppress "Warning 571: Suspicious cast" */
typedef struct
@ -145,6 +145,17 @@ static nrfx_gpiote_evt_handler_t channel_handler_get(uint32_t channel)
return m_cb.handlers[channel];
}
static nrfx_gpiote_pin_t port_handler_pin_get(uint32_t handler_idx)
{
uint8_t pin_and_polarity = (uint8_t)m_cb.port_handlers_pins[handler_idx];
return (nrfx_gpiote_pin_t)(pin_and_polarity & ~POLARITY_FIELD_MASK);
}
static nrf_gpiote_polarity_t port_handler_polarity_get(uint32_t handler_idx)
{
uint8_t pin_and_polarity = (uint8_t)m_cb.port_handlers_pins[handler_idx];
return (nrf_gpiote_polarity_t)((pin_and_polarity & POLARITY_FIELD_MASK) >> POLARITY_FIELD_POS);
}
static int8_t channel_port_alloc(uint32_t pin, nrfx_gpiote_evt_handler_t handler, bool channel)
{
@ -525,7 +536,7 @@ nrfx_err_t nrfx_gpiote_in_init(nrfx_gpiote_pin_t pin,
else
{
m_cb.port_handlers_pins[channel - GPIOTE_CH_NUM] |= (p_config->sense) <<
SENSE_FIELD_POS;
POLARITY_FIELD_POS;
}
}
else
@ -544,10 +555,8 @@ void nrfx_gpiote_in_event_enable(nrfx_gpiote_pin_t pin, bool int_enable)
NRFX_ASSERT(pin_in_use_by_gpiote(pin));
if (pin_in_use_by_port(pin))
{
uint8_t pin_and_sense = (uint8_t)
m_cb.port_handlers_pins[channel_port_get(pin) - GPIOTE_CH_NUM];
nrf_gpiote_polarity_t polarity =
(nrf_gpiote_polarity_t)(pin_and_sense >> SENSE_FIELD_POS);
port_handler_polarity_get(channel_port_get(pin) - GPIOTE_CH_NUM);
nrf_gpio_pin_sense_t sense;
if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
{
@ -646,6 +655,159 @@ uint32_t nrfx_gpiote_in_event_addr_get(nrfx_gpiote_pin_t pin)
return nrf_gpiote_event_address_get(NRF_GPIOTE, event);
}
#if defined(NRF_GPIO_LATCH_PRESENT)
static bool latch_pending_read_and_check(uint32_t * latch)
{
nrf_gpio_latches_read_and_clear(0, GPIO_COUNT, latch);
for (uint32_t port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
{
if (latch[port_idx])
{
/* If any of the latch bits is still set, it means another edge has been captured
* before or during the interrupt processing. Therefore event-processing loop
* should be executed again. */
return true;
}
}
return false;
}
static void port_event_handle(uint32_t * latch)
{
do {
for (uint32_t i = 0; i < NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++)
{
if (m_cb.port_handlers_pins[i] == PIN_NOT_USED)
{
continue;
}
/* Process pin further only if LATCH bit associated with this pin was set. */
nrfx_gpiote_pin_t pin = port_handler_pin_get(i);
if (nrf_bitmask_bit_is_set(pin, latch))
{
nrf_gpiote_polarity_t polarity = port_handler_polarity_get(i);
nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
NRFX_LOG_DEBUG("PORT event for pin: %d, polarity: %d.", pin, polarity);
/* Reconfigure sense to the opposite level, so the internal PINx.DETECT signal
* can be deasserted. Therefore PORT event generated again,
* unless some other PINx.DETECT signal is still active. */
nrf_gpio_pin_sense_t next_sense =
(sense == NRF_GPIO_PIN_SENSE_HIGH) ? NRF_GPIO_PIN_SENSE_LOW :
NRF_GPIO_PIN_SENSE_HIGH;
nrf_gpio_cfg_sense_set(pin, next_sense);
/* Try to clear LATCH bit corresponding to currently processed pin.
* This may not succeed if the pin's state changed during the interrupt processing
* and now it matches the new sense configuration. In such case,
* the pin will be processed again in another iteration of the outer loop. */
nrf_gpio_pin_latch_clear(pin);
/* Invoke user handler only if the sensed pin level
* matches its polarity configuration. */
nrfx_gpiote_evt_handler_t handler =
channel_handler_get((uint32_t)channel_port_get(pin));
if (handler &&
((polarity == NRF_GPIOTE_POLARITY_TOGGLE) ||
(sense == NRF_GPIO_PIN_SENSE_HIGH && polarity == NRF_GPIOTE_POLARITY_LOTOHI) ||
(sense == NRF_GPIO_PIN_SENSE_LOW && polarity == NRF_GPIOTE_POLARITY_HITOLO)))
{
handler(pin, polarity);
}
}
}
} while (latch_pending_read_and_check(latch));
}
#else
static bool input_read_and_check(uint32_t * input, uint32_t * pins_to_check)
{
bool process_inputs_again;
uint32_t new_input[GPIO_COUNT];
nrf_gpio_ports_read(0, GPIO_COUNT, new_input);
process_inputs_again = false;
for (uint32_t port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
{
/* Execute XOR to find out which inputs have changed. */
uint32_t input_diff = input[port_idx] ^ new_input[port_idx];
input[port_idx] = new_input[port_idx];
if (input_diff)
{
/* If any differences among inputs were found, mark those pins
* to be processed again. */
pins_to_check[port_idx] = input_diff;
process_inputs_again = true;
}
else
{
pins_to_check[port_idx] = 0;
}
}
return process_inputs_again;
}
static void port_event_handle(uint32_t * input)
{
uint32_t pins_to_check[GPIO_COUNT];
for (uint32_t port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
{
pins_to_check[port_idx] = 0xFFFFFFFF;
}
do {
for (uint32_t i = 0; i < NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++)
{
if (m_cb.port_handlers_pins[i] == PIN_NOT_USED)
{
continue;
}
nrfx_gpiote_pin_t pin = port_handler_pin_get(i);
if (nrf_bitmask_bit_is_set(pin, pins_to_check))
{
nrf_gpiote_polarity_t polarity = port_handler_polarity_get(i);
nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
bool pin_state = nrf_bitmask_bit_is_set(pin, input);
/* Process pin further only if its state matches its sense level. */
if ((pin_state && (sense == NRF_GPIO_PIN_SENSE_HIGH)) ||
(!pin_state && (sense == NRF_GPIO_PIN_SENSE_LOW)) )
{
/* Reconfigure sense to the opposite level, so the internal PINx.DETECT signal
* can be deasserted. Therefore PORT event can be generated again,
* unless some other PINx.DETECT signal is still active. */
NRFX_LOG_DEBUG("PORT event for pin: %d, polarity: %d.", pin, polarity);
nrf_gpio_pin_sense_t next_sense =
(sense == NRF_GPIO_PIN_SENSE_HIGH) ? NRF_GPIO_PIN_SENSE_LOW :
NRF_GPIO_PIN_SENSE_HIGH;
nrf_gpio_cfg_sense_set(pin, next_sense);
/* Invoke user handler only if the sensed pin level
* matches its polarity configuration. */
nrfx_gpiote_evt_handler_t handler =
channel_handler_get((uint32_t)channel_port_get(pin));
if (handler &&
((polarity == NRF_GPIOTE_POLARITY_TOGGLE) ||
(sense == NRF_GPIO_PIN_SENSE_HIGH &&
polarity == NRF_GPIOTE_POLARITY_LOTOHI) ||
(sense == NRF_GPIO_PIN_SENSE_LOW &&
polarity == NRF_GPIOTE_POLARITY_HITOLO)))
{
handler(pin, polarity);
}
}
}
}
} while (input_read_and_check(input, pins_to_check));
}
#endif // defined(NRF_GPIO_LATCH_PRESENT)
void nrfx_gpiote_irq_handler(void)
{
@ -677,7 +839,11 @@ void nrfx_gpiote_irq_handler(void)
{
nrf_gpiote_event_clear(NRF_GPIOTE, NRF_GPIOTE_EVENT_PORT);
status |= (uint32_t)NRF_GPIOTE_INT_PORT_MASK;
#if defined(NRF_GPIO_LATCH_PRESENT)
nrf_gpio_latches_read_and_clear(0, GPIO_COUNT, input);
#else
nrf_gpio_ports_read(0, GPIO_COUNT, input);
#endif
}
/* Process pin events. */
@ -703,107 +869,10 @@ void nrfx_gpiote_irq_handler(void)
}
}
/* Process PORT event. */
if (status & (uint32_t)NRF_GPIOTE_INT_PORT_MASK)
{
/* Process port event. */
uint32_t port_idx;
uint8_t repeat = 0;
uint32_t toggle_mask[GPIO_COUNT] = {0};
uint32_t pins_to_check[GPIO_COUNT];
// Faster way of doing memset because in interrupt context.
for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
{
pins_to_check[port_idx] = 0xFFFFFFFF;
}
do
{
repeat = 0;
for (i = 0; i < NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++)
{
uint8_t pin_and_sense = (uint8_t)m_cb.port_handlers_pins[i];
nrfx_gpiote_pin_t pin = (pin_and_sense & ~SENSE_FIELD_MASK);
if ((m_cb.port_handlers_pins[i] != PIN_NOT_USED)
&& nrf_bitmask_bit_is_set(pin, pins_to_check))
{
nrf_gpiote_polarity_t polarity =
(nrf_gpiote_polarity_t)((pin_and_sense &
SENSE_FIELD_MASK) >> SENSE_FIELD_POS);
nrfx_gpiote_evt_handler_t handler =
channel_handler_get((uint32_t)channel_port_get(pin));
if (handler || (polarity == NRF_GPIOTE_POLARITY_TOGGLE))
{
if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
{
nrf_bitmask_bit_set(pin, toggle_mask);
}
nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
uint32_t pin_state = nrf_bitmask_bit_is_set(pin, input);
if ((pin_state && (sense == NRF_GPIO_PIN_SENSE_HIGH)) ||
(!pin_state && (sense == NRF_GPIO_PIN_SENSE_LOW)) )
{
NRFX_LOG_DEBUG("PORT event for pin: %d, polarity: %d.", pin, polarity);
if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
{
nrf_gpio_pin_sense_t next_sense =
(sense == NRF_GPIO_PIN_SENSE_HIGH) ?
NRF_GPIO_PIN_SENSE_LOW :
NRF_GPIO_PIN_SENSE_HIGH;
nrf_gpio_cfg_sense_set(pin, next_sense);
++repeat;
}
if (handler)
{
handler(pin, polarity);
}
}
}
}
}
if (repeat)
{
// When one of the pins in low-accuracy and toggle mode becomes active,
// it's sense mode is inverted to clear the internal SENSE signal.
// State of any other enabled low-accuracy input in toggle mode must be checked
// explicitly, because it does not trigger the interrput when SENSE signal is active.
// For more information about SENSE functionality, refer to Product Specification.
uint32_t new_input[GPIO_COUNT];
bool input_unchanged = true;
nrf_gpio_ports_read(0, GPIO_COUNT, new_input);
// Faster way of doing memcmp because in interrupt context.
for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
{
if (new_input[port_idx] != input[port_idx])
{
input_unchanged = false;
break;
}
}
if (input_unchanged)
{
// No change.
repeat = 0;
}
else
{
// Faster way of doing memcpy because in interrupt context.
for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
{
input[port_idx] = new_input[port_idx];
pins_to_check[port_idx] = toggle_mask[port_idx];
}
}
}
}
while (repeat);
port_event_handle(input);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -167,6 +167,10 @@ nrfx_err_t nrfx_i2s_init(nrfx_i2s_config_t const * p_config,
NRFX_LOG_ERROR_STRING_GET(err_code));
return err_code;
}
#if NRF_I2S_HAS_CLKCONFIG
nrf_i2s_clk_configure(NRF_I2S, p_config->clksrc, p_config->enable_bypass);
#endif
configure_pins(p_config);
m_cb.handler = handler;
@ -380,12 +384,18 @@ void nrfx_i2s_irq_handler(void)
nrf_i2s_disable(NRF_I2S);
// When stopped, release all buffers, including these scheduled for
// the next transfer.
m_cb.handler(&m_cb.current_buffers, 0);
m_cb.handler(&m_cb.next_buffers, 0);
// the next part of the transfer, and signal that the transfer has
// finished.
m_cb.handler(&m_cb.current_buffers, 0);
// Change the state of the driver before calling the handler with
// the flag signaling that the transfer has finished, so that it is
// possible to start a new transfer directly from the handler function.
m_cb.state = NRFX_DRV_STATE_INITIALIZED;
NRFX_LOG_INFO("Stopped.");
m_cb.handler(&m_cb.next_buffers, NRFX_I2S_STATUS_TRANSFER_STOPPED);
}
else
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -43,6 +43,13 @@
*/
#define NVMC_BYTES_IN_WORD 4
/** Value representing non-volatile memory (NVM) base address. */
#if defined(NRF5340_XXAA_NETWORK)
#define NVMC_FLASH_BASE_ADDRESS 0x01000000uL
#else
#define NVMC_FLASH_BASE_ADDRESS 0
#endif
/**
* Value representing non-volatile memory (NVM) page count.
*
@ -211,7 +218,7 @@ static void nvmc_words_write(uint32_t addr, void const * src, uint32_t num_words
nrfx_err_t nrfx_nvmc_page_erase(uint32_t addr)
{
NRFX_ASSERT(addr < flash_total_size_get());
NRFX_ASSERT((addr - NVMC_FLASH_BASE_ADDRESS) < flash_total_size_get());
if (!is_page_aligned_check(addr))
{
@ -253,7 +260,7 @@ void nrfx_nvmc_all_erase(void)
#if defined(NRF_NVMC_PARTIAL_ERASE_PRESENT)
nrfx_err_t nrfx_nvmc_page_partial_erase_init(uint32_t addr, uint32_t duration_ms)
{
NRFX_ASSERT(addr < flash_total_size_get());
NRFX_ASSERT((addr - NVMC_FLASH_BASE_ADDRESS) < flash_total_size_get());
if (!is_page_aligned_check(addr))
{
@ -299,7 +306,7 @@ bool nrfx_nvmc_page_partial_erase_continue(void)
bool nrfx_nvmc_byte_writable_check(uint32_t addr, uint8_t val_to_check)
{
NRFX_ASSERT(addr < flash_total_size_get());
NRFX_ASSERT((addr - NVMC_FLASH_BASE_ADDRESS) < flash_total_size_get());
uint8_t val_on_addr = *(uint8_t const *)addr;
return (val_to_check & val_on_addr) == val_to_check;
@ -307,7 +314,7 @@ bool nrfx_nvmc_byte_writable_check(uint32_t addr, uint8_t val_to_check)
bool nrfx_nvmc_word_writable_check(uint32_t addr, uint32_t val_to_check)
{
NRFX_ASSERT(addr < flash_total_size_get());
NRFX_ASSERT((addr - NVMC_FLASH_BASE_ADDRESS) < flash_total_size_get());
NRFX_ASSERT(nrfx_is_word_aligned((void const *)addr));
uint32_t val_on_addr = *(uint32_t const *)addr;
@ -323,7 +330,7 @@ void nrfx_nvmc_byte_write(uint32_t addr, uint8_t value)
void nrfx_nvmc_word_write(uint32_t addr, uint32_t value)
{
NRFX_ASSERT(addr < flash_total_size_get());
NRFX_ASSERT((addr - NVMC_FLASH_BASE_ADDRESS) < flash_total_size_get());
NRFX_ASSERT(nrfx_is_word_aligned((void const *)addr));
nvmc_write_mode_set();
@ -335,7 +342,7 @@ void nrfx_nvmc_word_write(uint32_t addr, uint32_t value)
void nrfx_nvmc_bytes_write(uint32_t addr, void const * src, uint32_t num_bytes)
{
NRFX_ASSERT(addr < flash_total_size_get());
NRFX_ASSERT((addr - NVMC_FLASH_BASE_ADDRESS) < flash_total_size_get());
nvmc_write_mode_set();
@ -397,7 +404,7 @@ void nrfx_nvmc_bytes_write(uint32_t addr, void const * src, uint32_t num_bytes)
void nrfx_nvmc_words_write(uint32_t addr, void const * src, uint32_t num_words)
{
NRFX_ASSERT(addr < flash_total_size_get());
NRFX_ASSERT((addr - NVMC_FLASH_BASE_ADDRESS) < flash_total_size_get());
NRFX_ASSERT(nrfx_is_word_aligned((void const *)addr));
NRFX_ASSERT(nrfx_is_word_aligned(src));

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -73,9 +73,9 @@ static nrfx_pdm_cb_t m_cb;
void nrfx_pdm_irq_handler(void)
{
if (nrf_pdm_event_check(NRF_PDM, NRF_PDM_EVENT_STARTED))
if (nrf_pdm_event_check(NRF_PDM0, NRF_PDM_EVENT_STARTED))
{
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_STARTED);
nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_STARTED);
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_PDM_EVENT_STARTED));
uint8_t finished_buffer = m_cb.active_buffer;
@ -125,11 +125,11 @@ void nrfx_pdm_irq_handler(void)
m_cb.op_state = NRFX_PDM_STATE_RUNNING;
}
}
else if (nrf_pdm_event_check(NRF_PDM, NRF_PDM_EVENT_STOPPED))
else if (nrf_pdm_event_check(NRF_PDM0, NRF_PDM_EVENT_STOPPED))
{
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_STOPPED);
nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_STOPPED);
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_PDM_EVENT_STOPPED));
nrf_pdm_disable(NRF_PDM);
nrf_pdm_disable(NRF_PDM0);
m_cb.op_state = NRFX_PDM_STATE_IDLE;
// Release the buffers.
@ -200,21 +200,28 @@ nrfx_err_t nrfx_pdm_init(nrfx_pdm_config_t const * p_config,
m_cb.event_handler = event_handler;
m_cb.op_state = NRFX_PDM_STATE_IDLE;
nrf_pdm_clock_set(NRF_PDM, p_config->clock_freq);
nrf_pdm_mode_set(NRF_PDM, p_config->mode, p_config->edge);
nrf_pdm_gain_set(NRF_PDM, p_config->gain_l, p_config->gain_r);
#if NRF_PDM_HAS_RATIO_CONFIG
nrf_pdm_ratio_set(NRF_PDM0, p_config->ratio);
#endif
#if NRF_PDM_HAS_MCLKCONFIG
nrf_pdm_mclksrc_configure(NRF_PDM0, p_config->mclksrc);
#endif
nrf_pdm_clock_set(NRF_PDM0, p_config->clock_freq);
nrf_pdm_mode_set(NRF_PDM0, p_config->mode, p_config->edge);
nrf_pdm_gain_set(NRF_PDM0, p_config->gain_l, p_config->gain_r);
nrf_gpio_cfg_output(p_config->pin_clk);
nrf_gpio_pin_clear(p_config->pin_clk);
nrf_gpio_cfg_input(p_config->pin_din, NRF_GPIO_PIN_NOPULL);
nrf_pdm_psel_connect(NRF_PDM, p_config->pin_clk, p_config->pin_din);
nrf_pdm_psel_connect(NRF_PDM0, p_config->pin_clk, p_config->pin_din);
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_STARTED);
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_END);
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_STOPPED);
nrf_pdm_int_enable(NRF_PDM, NRF_PDM_INT_STARTED | NRF_PDM_INT_STOPPED);
NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_PDM), p_config->interrupt_priority);
NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_PDM));
nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_STARTED);
nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_END);
nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_STOPPED);
nrf_pdm_int_enable(NRF_PDM0, NRF_PDM_INT_STARTED | NRF_PDM_INT_STOPPED);
NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_PDM0), p_config->interrupt_priority);
NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_PDM0));
m_cb.drv_state = NRFX_DRV_STATE_INITIALIZED;
err_code = NRFX_SUCCESS;
@ -230,8 +237,8 @@ void nrfx_pdm_uninit(void)
{
return;
}
nrf_pdm_disable(NRF_PDM);
nrf_pdm_psel_disconnect(NRF_PDM);
nrf_pdm_disable(NRF_PDM0);
nrf_pdm_psel_disconnect(NRF_PDM0);
m_cb.drv_state = NRFX_DRV_STATE_UNINITIALIZED;
NRFX_LOG_INFO("Uninitialized.");
}
@ -239,15 +246,15 @@ void nrfx_pdm_uninit(void)
static void pdm_start()
{
m_cb.drv_state = NRFX_DRV_STATE_POWERED_ON;
nrf_pdm_enable(NRF_PDM);
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_STARTED);
nrf_pdm_task_trigger(NRF_PDM, NRF_PDM_TASK_START);
nrf_pdm_enable(NRF_PDM0);
nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_STARTED);
nrf_pdm_task_trigger(NRF_PDM0, NRF_PDM_TASK_START);
}
static void pdm_buf_request()
{
m_cb.irq_buff_request = 1;
NRFX_IRQ_PENDING_SET(nrfx_get_irq_number(NRF_PDM));
NRFX_IRQ_PENDING_SET(nrfx_get_irq_number(NRF_PDM0));
}
nrfx_err_t nrfx_pdm_start(void)
@ -300,7 +307,7 @@ nrfx_err_t nrfx_pdm_buffer_set(int16_t * buffer, uint16_t buffer_length)
nrfx_err_t err_code = NRFX_SUCCESS;
// Enter the PDM critical section.
NRFX_IRQ_DISABLE(nrfx_get_irq_number(NRF_PDM));
NRFX_IRQ_DISABLE(nrfx_get_irq_number(NRF_PDM0));
uint8_t next_buffer = (~m_cb.active_buffer) & 0x01;
if (m_cb.op_state == NRFX_PDM_STATE_STARTING)
@ -317,7 +324,7 @@ nrfx_err_t nrfx_pdm_buffer_set(int16_t * buffer, uint16_t buffer_length)
{
m_cb.buff_address[next_buffer] = buffer;
m_cb.buff_length[next_buffer] = buffer_length;
nrf_pdm_buffer_set(NRF_PDM, (uint32_t *)buffer, buffer_length);
nrf_pdm_buffer_set(NRF_PDM0, (uint32_t *)buffer, buffer_length);
if (m_cb.drv_state != NRFX_DRV_STATE_POWERED_ON)
{
@ -325,7 +332,7 @@ nrfx_err_t nrfx_pdm_buffer_set(int16_t * buffer, uint16_t buffer_length)
}
}
NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_PDM));
NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_PDM0));
return err_code;
}
@ -339,7 +346,7 @@ nrfx_err_t nrfx_pdm_stop(void)
if (m_cb.op_state == NRFX_PDM_STATE_IDLE ||
m_cb.op_state == NRFX_PDM_STATE_STARTING)
{
nrf_pdm_disable(NRF_PDM);
nrf_pdm_disable(NRF_PDM0);
m_cb.op_state = NRFX_PDM_STATE_IDLE;
err_code = NRFX_SUCCESS;
NRFX_LOG_INFO("Function: %s, error code: %s.",
@ -356,7 +363,7 @@ nrfx_err_t nrfx_pdm_stop(void)
m_cb.drv_state = NRFX_DRV_STATE_INITIALIZED;
m_cb.op_state = NRFX_PDM_STATE_STOPPING;
nrf_pdm_task_trigger(NRF_PDM, NRF_PDM_TASK_STOP);
nrf_pdm_task_trigger(NRF_PDM0, NRF_PDM_TASK_STOP);
err_code = NRFX_SUCCESS;
NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
return err_code;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,9 +34,6 @@
#if NRFX_CHECK(NRFX_POWER_ENABLED)
#include <nrfx_power.h>
#if defined(REGULATORS_PRESENT)
#include <hal/nrf_regulators.h>
#endif
#if NRFX_CHECK(NRFX_CLOCK_ENABLED)
extern bool nrfx_clock_irq_enabled;
@ -108,7 +105,10 @@ nrfx_err_t nrfx_power_init(nrfx_power_config_t const * p_config)
#if NRF_POWER_HAS_DCDCEN_VDDH
nrf_power_dcdcen_vddh_set(NRF_POWER, p_config->dcdcenhv);
#elif NRF_REGULATORS_HAS_DCDCEN_VDDH
nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS, p_config->dcdcenhv);
#endif
#if NRF_POWER_HAS_DCDCEN
nrf_power_dcdcen_set(NRF_POWER, p_config->dcdcen);
#elif defined(REGULATORS_PRESENT)
@ -135,19 +135,19 @@ void nrfx_power_uninit(void)
{
NRFX_IRQ_DISABLE(nrfx_get_irq_number(NRF_POWER));
}
#if NRF_POWER_HAS_POFCON
#if NRFX_POWER_SUPPORTS_POFCON
nrfx_power_pof_uninit();
#endif
#if NRF_POWER_HAS_SLEEPEVT
nrfx_power_sleepevt_uninit();
#endif
#if NRF_POWER_HAS_USBREG
#if NRF_POWER_HAS_USBREG || defined(USBREG_PRESENT)
nrfx_power_usbevt_uninit();
#endif
m_initialized = false;
}
#if NRF_POWER_HAS_POFCON
#if NRFX_POWER_SUPPORTS_POFCON
void nrfx_power_pof_init(nrfx_power_pofwarn_config_t const * p_config)
{
NRFX_ASSERT(p_config != NULL);
@ -162,10 +162,18 @@ void nrfx_power_pof_init(nrfx_power_pofwarn_config_t const * p_config)
void nrfx_power_pof_enable(nrfx_power_pofwarn_config_t const * p_config)
{
#if NRF_POWER_HAS_POFCON
nrf_power_pofcon_set(NRF_POWER, true, p_config->thr);
#if NRF_POWER_HAS_VDDH
nrf_power_pofcon_vddh_set(NRF_POWER, p_config->thrvddh);
#elif NRF_REGULATORS_HAS_POFCON
nrf_regulators_pofcon_set(NRF_REGULATORS, true, p_config->thr);
#endif
#if NRF_POWER_HAS_POFCON_VDDH
nrf_power_pofcon_vddh_set(NRF_POWER, p_config->thrvddh);
#elif NRF_REGULATORS_HAS_POFCON_VDDH
nrf_regulators_pofcon_vddh_set(NRF_REGULATORS, p_config->thrvddh);
#endif
if (m_pofwarn_handler != NULL)
{
nrf_power_int_enable(NRF_POWER, NRF_POWER_INT_POFWARN_MASK);
@ -174,7 +182,11 @@ void nrfx_power_pof_enable(nrfx_power_pofwarn_config_t const * p_config)
void nrfx_power_pof_disable(void)
{
#if NRF_POWER_HAS_POFCON
nrf_power_pofcon_set(NRF_POWER, false, NRF_POWER_POFTHR_V27);
#elif NRF_REGULATORS_HAS_POFCON
nrf_regulators_pofcon_set(NRF_REGULATORS, false, NRF_REGULATORS_POFTHR_V27);
#endif
nrf_power_int_disable(NRF_POWER, NRF_POWER_INT_POFWARN_MASK);
}
@ -182,7 +194,7 @@ void nrfx_power_pof_uninit(void)
{
m_pofwarn_handler = NULL;
}
#endif // NRF_POWER_HAS_POFCON
#endif // NRFX_POWER_SUPPORTS_POFCON
#if NRF_POWER_HAS_SLEEPEVT
void nrfx_power_sleepevt_init(nrfx_power_sleepevt_config_t const * p_config)
@ -252,8 +264,11 @@ void nrfx_power_usbevt_disable(void)
void nrfx_power_usbevt_uninit(void)
{
nrfx_power_usbevt_disable();
m_usbevt_handler = NULL;
}
#endif /* NRF_POWER_HAS_USBREG */
@ -261,7 +276,7 @@ void nrfx_power_irq_handler(void)
{
uint32_t enabled = nrf_power_int_enable_get(NRF_POWER);
#if NRF_POWER_HAS_POFCON
#if NRFX_POWER_SUPPORTS_POFCON
if ((0 != (enabled & NRF_POWER_INT_POFWARN_MASK)) &&
nrf_power_event_get_and_clear(NRF_POWER, NRF_POWER_EVENT_POFWARN))
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -92,16 +92,19 @@ static void configure_pins(nrfx_pwm_t const * p_instance,
bool inverted = output_pin & NRFX_PWM_PIN_INVERTED;
out_pins[i] = output_pin & ~NRFX_PWM_PIN_INVERTED;
if (inverted)
if (!p_config->skip_gpio_cfg)
{
nrf_gpio_pin_set(out_pins[i]);
}
else
{
nrf_gpio_pin_clear(out_pins[i]);
}
if (inverted)
{
nrf_gpio_pin_set(out_pins[i]);
}
else
{
nrf_gpio_pin_clear(out_pins[i]);
}
nrf_gpio_cfg_output(out_pins[i]);
nrf_gpio_cfg_output(out_pins[i]);
}
}
else
{
@ -368,14 +371,22 @@ bool nrfx_pwm_stop(nrfx_pwm_t const * p_instance,
bool ret_val = false;
// Deactivate shortcuts before triggering the STOP task, otherwise the PWM
// could be immediately started again if the LOOPSDONE event occurred in
// the same peripheral clock cycle as the STOP task was triggered.
nrf_pwm_shorts_set(p_instance->p_registers, 0);
// Trigger the STOP task even if the PWM appears to be already stopped.
// It won't harm, but it could help if for some strange reason the stopped
// status was not reported correctly.
nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_STOP);
if (nrfx_pwm_is_stopped(p_instance))
{
ret_val = true;
}
else
{
nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_STOP);
do {
if (nrfx_pwm_is_stopped(p_instance))
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -141,8 +141,8 @@ nrfx_err_t nrfx_qdec_init(nrfx_qdec_config_t const * p_config,
}
nrf_qdec_int_enable(NRF_QDEC, int_mask);
NRFX_IRQ_PRIORITY_SET(QDEC_IRQn, p_config->interrupt_priority);
NRFX_IRQ_ENABLE(QDEC_IRQn);
NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_QDEC), p_config->interrupt_priority);
NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_QDEC));
m_state = NRFX_DRV_STATE_INITIALIZED;
@ -158,7 +158,7 @@ void nrfx_qdec_uninit(void)
return;
}
nrfx_qdec_disable();
NRFX_IRQ_DISABLE(QDEC_IRQn);
NRFX_IRQ_DISABLE(nrfx_get_irq_number(NRF_QDEC));
m_state = NRFX_DRV_STATE_UNINITIALIZED;
NRFX_LOG_INFO("Uninitialized.");
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -397,6 +397,50 @@ nrfx_err_t nrfx_qspi_chip_erase(void)
return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_ALL, 0);
}
#if NRF_QSPI_HAS_XIP_ENC
nrfx_err_t nrfx_qspi_xip_encrypt(nrf_qspi_encryption_t const * p_config)
{
if (m_cb.is_busy)
{
return NRFX_ERROR_BUSY;
}
if (p_config)
{
nrf_qspi_xip_encryption_configure(NRF_QSPI, p_config);
nrf_qspi_xip_encryption_set(NRF_QSPI, true);
}
else
{
nrf_qspi_xip_encryption_set(NRF_QSPI, false);
}
return NRFX_SUCCESS;
}
#endif
#if NRF_QSPI_HAS_DMA_ENC
nrfx_err_t nrfx_qspi_dma_encrypt(nrf_qspi_encryption_t const * p_config)
{
if (m_cb.is_busy)
{
return NRFX_ERROR_BUSY;
}
if (p_config)
{
nrf_qspi_dma_encryption_configure(NRF_QSPI, p_config);
nrf_qspi_dma_encryption_set(NRF_QSPI, true);
}
else
{
nrf_qspi_dma_encryption_set(NRF_QSPI, false);
}
return NRFX_SUCCESS;
}
#endif
void nrfx_qspi_irq_handler(void)
{
// Catch Event ready interrupts

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,24 +36,18 @@
#define NRFX_LOG_MODULE SAADC
#include <nrfx_log.h>
#define EVT_TO_STR(event) \
(event == NRF_SAADC_EVENT_STARTED ? "NRF_SAADC_EVENT_STARTED" : \
(event == NRF_SAADC_EVENT_END ? "NRF_SAADC_EVENT_END" : \
(event == NRF_SAADC_EVENT_DONE ? "NRF_SAADC_EVENT_DONE" : \
(event == NRF_SAADC_EVENT_RESULTDONE ? "NRF_SAADC_EVENT_RESULTDONE" : \
(event == NRF_SAADC_EVENT_CALIBRATEDONE ? "NRF_SAADC_EVENT_CALIBRATEDONE" : \
(event == NRF_SAADC_EVENT_STOPPED ? "NRF_SAADC_EVENT_STOPPED" : \
"UNKNOWN EVENT"))))))
#if defined(NRF52_SERIES) && !defined(USE_WORKAROUND_FOR_ANOMALY_212)
// ANOMALY 212 - SAADC events are missing when switching from single channel
// to multi channel configuration with burst enabled.
#define USE_WORKAROUND_FOR_ANOMALY_212 1
#endif
#if defined(NRF91_SERIES) || defined(NRF53_SERIES)
#if defined(NRF53_SERIES) || defined(NRF91_SERIES)
// Make sure that SAADC is stopped before channel configuration.
#define STOP_SAADC_ON_CHANNEL_CONFIG 1
// Make sure that SAADC calibration samples do not affect next conversions.
#define INTERCEPT_SAADC_CALIBRATION_SAMPLES 1
#endif
/** @brief SAADC driver states.*/
@ -75,9 +69,12 @@ typedef struct
nrfx_saadc_event_handler_t event_handler; ///< Event handler function pointer.
nrf_saadc_value_t * p_buffer_primary; ///< Pointer to the primary result buffer.
nrf_saadc_value_t * p_buffer_secondary; ///< Pointer to the secondary result buffer.
#if NRFX_CHECK(INTERCEPT_SAADC_CALIBRATION_SAMPLES)
nrf_saadc_value_t calib_samples[6]; ///< Scratch buffer for calibration samples.
#endif
uint16_t size_primary; ///< Size of the primary result buffer.
uint16_t size_secondary; ///< Size of the secondary result buffer.
uint16_t samples_per_trigger; ///< Samples to take per one trigger in the blocking mode.
uint16_t samples_converted; ///< Number of samples present in result buffer when in the blocking mode.
nrf_saadc_input_t channels_pselp[SAADC_CH_NUM]; ///< Array holding each channel positive input.
nrf_saadc_input_t channels_pseln[SAADC_CH_NUM]; ///< Array holding each channel negative input.
nrf_saadc_state_t saadc_state; ///< State of the SAADC driver.
@ -87,6 +84,7 @@ typedef struct
uint8_t limits_low_activated; ///< Bitmask of the activated low limits.
uint8_t limits_high_activated; ///< Bitmask of the activated high limits.
bool start_on_end; ///< Flag indicating if the START task is to be triggered on the END event.
bool oversampling_without_burst; ///< Flag indicating whether oversampling without burst is configured.
} nrfx_saadc_cb_t;
static nrfx_saadc_cb_t m_cb;
@ -122,17 +120,6 @@ static void saadc_anomaly_212_workaround_apply(void)
}
#endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_212)
static void saadc_enabled_channels_sample(void)
{
for (uint32_t sample_idx = 0; sample_idx < m_cb.samples_per_trigger; sample_idx++)
{
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_DONE))
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_DONE);
}
}
static nrfx_err_t saadc_channel_count_get(uint32_t ch_to_activate_mask,
uint8_t * p_active_ch_count)
{
@ -183,11 +170,9 @@ static void saadc_generic_mode_set(uint32_t ch_to_activate_mas
#if NRFX_CHECK(STOP_SAADC_ON_CHANNEL_CONFIG)
nrf_saadc_int_disable(NRF_SAADC, NRF_SAADC_INT_STOPPED);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STOPPED))
{
}
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
#endif
@ -198,25 +183,20 @@ static void saadc_generic_mode_set(uint32_t ch_to_activate_mas
m_cb.p_buffer_secondary = NULL;
m_cb.event_handler = event_handler;
m_cb.channels_activated = ch_to_activate_mask;
m_cb.samples_converted = 0;
nrf_saadc_resolution_set(NRF_SAADC, resolution);
nrf_saadc_oversample_set(NRF_SAADC, oversampling);
if (event_handler)
{
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STARTED);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
nrf_saadc_int_enable(NRF_SAADC,
NRF_SAADC_INT_STARTED |
NRF_SAADC_INT_STOPPED |
NRF_SAADC_INT_END);
nrf_saadc_int_set(NRF_SAADC,
NRF_SAADC_INT_STARTED |
NRF_SAADC_INT_STOPPED |
NRF_SAADC_INT_END);
}
else
{
nrf_saadc_int_disable(NRF_SAADC,
NRF_SAADC_INT_STARTED |
NRF_SAADC_INT_STOPPED |
NRF_SAADC_INT_END);
nrf_saadc_int_set(NRF_SAADC, 0);
}
for (uint32_t ch_pos = 0; ch_pos < SAADC_CH_NUM; ch_pos++)
@ -243,22 +223,28 @@ static void saadc_generic_mode_set(uint32_t ch_to_activate_mas
nrfx_err_t nrfx_saadc_init(uint8_t interrupt_priority)
{
nrfx_err_t err_code;
if (m_cb.saadc_state != NRF_SAADC_STATE_UNINITIALIZED)
{
err_code = NRFX_ERROR_INVALID_STATE;
NRFX_LOG_WARNING("Function: %s, error code: %s.",
__func__,
NRFX_LOG_ERROR_STRING_GET(err_code));
return NRFX_ERROR_INVALID_STATE;
return err_code;
}
m_cb.saadc_state = NRF_SAADC_STATE_IDLE;
nrf_saadc_int_disable(NRF_SAADC, NRF_SAADC_INT_ALL);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STARTED);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
nrf_saadc_int_set(NRF_SAADC, 0);
NRFX_IRQ_ENABLE(SAADC_IRQn);
NRFX_IRQ_PRIORITY_SET(SAADC_IRQn, interrupt_priority);
err_code = NRFX_SUCCESS;
NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
return NRFX_SUCCESS;
return err_code;
}
void nrfx_saadc_uninit(void)
@ -340,6 +326,7 @@ nrfx_err_t nrfx_saadc_simple_mode_set(uint32_t channel_mask,
}
else
{
// Burst is implicitly enabled if oversampling is enabled.
burst = NRF_SAADC_BURST_ENABLED;
}
@ -349,17 +336,6 @@ nrfx_err_t nrfx_saadc_simple_mode_set(uint32_t channel_mask,
burst,
event_handler);
if (event_handler)
{
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_RESULTDONE);
nrf_saadc_int_enable(NRF_SAADC, NRF_SAADC_INT_RESULTDONE);
}
else
{
nrf_saadc_int_disable(NRF_SAADC, NRF_SAADC_INT_RESULTDONE);
}
m_cb.samples_per_trigger = active_ch_count;
m_cb.channels_activated_count = active_ch_count;
m_cb.saadc_state = NRF_SAADC_STATE_SIMPLE_MODE;
@ -391,24 +367,20 @@ nrfx_err_t nrfx_saadc_advanced_mode_set(uint32_t channel_
return NRFX_ERROR_NOT_SUPPORTED;
}
bool oversampling_without_burst = false;
if ((p_config->oversampling != NRF_SAADC_OVERSAMPLE_DISABLED) &&
(p_config->burst == NRF_SAADC_BURST_DISABLED))
{
// Oversampling without burst
if (active_ch_count > 1)
{
// Oversampling without burst is possible only on single channel.
return NRFX_ERROR_NOT_SUPPORTED;
}
else
{
m_cb.samples_per_trigger =
nrf_saadc_oversample_sample_count_get(p_config->oversampling);
oversampling_without_burst = true;
}
}
else
{
m_cb.samples_per_trigger = active_ch_count;
}
saadc_generic_mode_set(channel_mask,
resolution,
@ -427,6 +399,7 @@ nrfx_err_t nrfx_saadc_advanced_mode_set(uint32_t channel_
m_cb.channels_activated_count = active_ch_count;
m_cb.start_on_end = p_config->start_on_end;
m_cb.oversampling_without_burst = oversampling_without_burst;
m_cb.saadc_state = NRF_SAADC_STATE_ADV_MODE;
@ -461,9 +434,8 @@ nrfx_err_t nrfx_saadc_buffer_set(nrf_saadc_value_t * p_buffer, uint16_t size)
{
return NRFX_ERROR_INVALID_LENGTH;
}
m_cb.p_buffer_primary = p_buffer;
m_cb.size_primary = size;
nrf_saadc_buffer_init(NRF_SAADC, p_buffer, size);
m_cb.p_buffer_primary = p_buffer;
break;
case NRF_SAADC_STATE_ADV_MODE_SAMPLE_STARTED:
@ -476,14 +448,13 @@ nrfx_err_t nrfx_saadc_buffer_set(nrf_saadc_value_t * p_buffer, uint16_t size)
case NRF_SAADC_STATE_ADV_MODE_SAMPLE:
if (m_cb.p_buffer_primary)
{
m_cb.p_buffer_secondary = p_buffer;
m_cb.size_secondary = size;
m_cb.p_buffer_secondary = p_buffer;
}
else
{
m_cb.p_buffer_primary = p_buffer;
m_cb.size_primary = size;
nrf_saadc_buffer_init(NRF_SAADC, p_buffer, size);
m_cb.p_buffer_primary = p_buffer;
}
break;
@ -505,9 +476,14 @@ nrfx_err_t nrfx_saadc_mode_trigger(void)
}
nrfx_err_t result = NRFX_SUCCESS;
switch (m_cb.saadc_state) {
switch (m_cb.saadc_state)
{
case NRF_SAADC_STATE_SIMPLE_MODE:
nrf_saadc_enable(NRF_SAADC);
// When in simple blocking or non-blocking mode, buffer size is equal to activated channel count.
// Single SAMPLE task is enough to obtain one sample on each activated channel.
// This will result in buffer being filled with samples and therefore END event will appear.
nrf_saadc_buffer_init(NRF_SAADC, m_cb.p_buffer_primary, m_cb.size_primary);
if (m_cb.event_handler)
{
m_cb.saadc_state = NRF_SAADC_STATE_SIMPLE_MODE_SAMPLE;
@ -520,7 +496,7 @@ nrfx_err_t nrfx_saadc_mode_trigger(void)
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STARTED);
saadc_enabled_channels_sample();
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END))
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
@ -532,49 +508,64 @@ nrfx_err_t nrfx_saadc_mode_trigger(void)
nrf_saadc_enable(NRF_SAADC);
if (m_cb.event_handler)
{
// When in advanced non-blocking mode, latch whole buffer in EasyDMA.
// END event will arrive when whole buffer is filled with samples.
m_cb.saadc_state = NRF_SAADC_STATE_ADV_MODE_SAMPLE;
nrf_saadc_buffer_init(NRF_SAADC, m_cb.p_buffer_primary, m_cb.size_primary);
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
break;
}
m_cb.saadc_state = NRF_SAADC_STATE_ADV_MODE_SAMPLE_STARTED;
// When in advanced blocking mode, latch single chunk of buffer in EasyDMA.
// Each chunk consists of single sample from each activated channels.
// END event will arrive when single chunk is filled with samples.
nrf_saadc_buffer_init(NRF_SAADC,
&m_cb.p_buffer_primary[m_cb.samples_converted],
m_cb.channels_activated_count);
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STARTED))
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STARTED);
/* fall-through */
case NRF_SAADC_STATE_ADV_MODE_SAMPLE_STARTED:
if (m_cb.event_handler)
if (m_cb.oversampling_without_burst)
{
result = NRFX_ERROR_INVALID_STATE;
break;
}
// Oversampling without burst is possible only on single channel.
// In this configuration more than one SAMPLE task is needed to obtain single sample.
uint32_t samples_to_take =
nrf_saadc_oversample_sample_count_get(nrf_saadc_oversample_get(NRF_SAADC));
saadc_enabled_channels_sample();
if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END))
{
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
m_cb.saadc_state = NRF_SAADC_STATE_ADV_MODE;
m_cb.p_buffer_primary = m_cb.p_buffer_secondary;
m_cb.size_primary = m_cb.size_secondary;
m_cb.p_buffer_secondary = NULL;
if (m_cb.p_buffer_primary)
for (uint32_t sample_idx = 0; sample_idx < samples_to_take; sample_idx++)
{
nrf_saadc_buffer_init(NRF_SAADC,
m_cb.p_buffer_primary,
m_cb.size_primary);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_DONE);
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_DONE))
{}
}
else
{
nrf_saadc_disable(NRF_SAADC);
}
result = NRFX_SUCCESS;
}
else
{
// Single SAMPLE task is enough to obtain one sample on each activated channel.
// This will result in chunk being filled with samples and therefore END event will appear.
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
}
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END))
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
m_cb.samples_converted += m_cb.channels_activated_count;
if (m_cb.samples_converted < m_cb.size_primary)
{
result = NRFX_ERROR_BUSY;
}
else
{
m_cb.samples_converted = 0;
m_cb.p_buffer_primary = m_cb.p_buffer_secondary;
m_cb.size_primary = m_cb.size_secondary;
m_cb.p_buffer_secondary = NULL;
}
nrf_saadc_disable(NRF_SAADC);
break;
default:
@ -589,43 +580,19 @@ void nrfx_saadc_abort(void)
{
NRFX_ASSERT(m_cb.saadc_state != NRF_SAADC_STATE_UNINITIALIZED);
if (!saadc_busy_check())
if (!m_cb.event_handler)
{
return;
}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
if (m_cb.saadc_state == NRF_SAADC_STATE_CALIBRATION)
{
// STOPPED event does not appear when the calibration is ongoing
m_cb.saadc_state = NRF_SAADC_STATE_IDLE;
}
else if (!m_cb.event_handler)
{
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STOPPED))
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
m_cb.p_buffer_primary = NULL;
m_cb.p_buffer_secondary = NULL;
switch (m_cb.saadc_state)
m_cb.samples_converted = 0;
}
else
{
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
if (m_cb.saadc_state == NRF_SAADC_STATE_CALIBRATION)
{
case NRF_SAADC_STATE_SIMPLE_MODE_SAMPLE:
m_cb.saadc_state = NRF_SAADC_STATE_SIMPLE_MODE;
break;
case NRF_SAADC_STATE_ADV_MODE_SAMPLE:
/* fall-through */
case NRF_SAADC_STATE_ADV_MODE_SAMPLE_STARTED:
m_cb.saadc_state = NRF_SAADC_STATE_ADV_MODE;
break;
default:
break;
// STOPPED event does not appear when the calibration is ongoing
m_cb.saadc_state = NRF_SAADC_STATE_IDLE;
}
}
}
@ -692,8 +659,31 @@ nrfx_err_t nrfx_saadc_offset_calibrate(nrfx_saadc_event_handler_t event_handler)
m_cb.saadc_state = NRF_SAADC_STATE_CALIBRATION;
m_cb.event_handler = event_handler;
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE);
nrf_saadc_enable(NRF_SAADC);
#if NRFX_CHECK(INTERCEPT_SAADC_CALIBRATION_SAMPLES)
nrf_saadc_buffer_init(NRF_SAADC, m_cb.calib_samples, NRFX_ARRAY_SIZE(m_cb.calib_samples));
if (event_handler)
{
nrf_saadc_int_set(NRF_SAADC, NRF_SAADC_INT_STARTED | NRF_SAADC_INT_CALIBRATEDONE);
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
}
else
{
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STARTED))
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STARTED);
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_CALIBRATEOFFSET);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE))
{}
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE);
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
nrf_saadc_disable(NRF_SAADC);
m_cb.saadc_state = NRF_SAADC_STATE_IDLE;
}
#else
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_CALIBRATEOFFSET);
if (event_handler)
{
@ -707,6 +697,7 @@ nrfx_err_t nrfx_saadc_offset_calibrate(nrfx_saadc_event_handler_t event_handler)
nrf_saadc_disable(NRF_SAADC);
m_cb.saadc_state = NRF_SAADC_STATE_IDLE;
}
#endif // NRFX_CHECK(INTERCEPT_SAADC_CALIBRATION_SAMPLES)
return NRFX_SUCCESS;
}
@ -737,14 +728,25 @@ static void saadc_event_started_handle(void)
/* fall-through */
case NRF_SAADC_STATE_ADV_MODE_SAMPLE_STARTED:
evt_data.type = NRFX_SAADC_EVT_BUF_REQ;
m_cb.event_handler(&evt_data);
if (!m_cb.p_buffer_secondary)
{
// Send next buffer request only if it was not provided earlier,
// before conversion start or outside of user's callback context.
evt_data.type = NRFX_SAADC_EVT_BUF_REQ;
m_cb.event_handler(&evt_data);
}
break;
case NRF_SAADC_STATE_SIMPLE_MODE_SAMPLE:
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
break;
#if NRFX_CHECK(INTERCEPT_SAADC_CALIBRATION_SAMPLES)
case NRF_SAADC_STATE_CALIBRATION:
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_CALIBRATEOFFSET);
break;
#endif
default:
break;
}
@ -819,16 +821,6 @@ void nrfx_saadc_irq_handler(void)
saadc_event_started_handle();
}
if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_RESULTDONE))
{
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_RESULTDONE);
if (m_cb.saadc_state == NRF_SAADC_STATE_SIMPLE_MODE_SAMPLE)
{
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
}
}
if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STOPPED))
{
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
@ -842,7 +834,15 @@ void nrfx_saadc_irq_handler(void)
if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END))
{
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
saadc_event_end_handle();
#if NRFX_CHECK(INTERCEPT_SAADC_CALIBRATION_SAMPLES)
// When samples are intercepted into scratch buffer during calibration,
// END event appears when the calibration finishes. This event should be ignored.
if (m_cb.saadc_state != NRF_SAADC_STATE_CALIBRATION)
#endif
{
saadc_event_end_handle();
}
}
saadc_event_limits_handle(m_cb.limits_low_activated, NRF_SAADC_LIMIT_LOW);
@ -851,6 +851,7 @@ void nrfx_saadc_irq_handler(void)
if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE))
{
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE);
nrf_saadc_disable(NRF_SAADC);
m_cb.saadc_state = NRF_SAADC_STATE_IDLE;
@ -858,8 +859,6 @@ void nrfx_saadc_irq_handler(void)
evt_data.type = NRFX_SAADC_EVT_CALIBRATEDONE;
m_cb.event_handler(&evt_data);
nrf_saadc_int_disable(NRF_SAADC, NRF_SAADC_INT_CALIBRATEDONE);
nrf_saadc_disable(NRF_SAADC);
}
}
#endif // NRFX_CHECK(NRFX_SAADC_ENABLED)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,7 +34,8 @@
#if NRFX_CHECK(NRFX_SPIM_ENABLED)
#if !(NRFX_CHECK(NRFX_SPIM0_ENABLED) || NRFX_CHECK(NRFX_SPIM1_ENABLED) || \
NRFX_CHECK(NRFX_SPIM2_ENABLED) || NRFX_CHECK(NRFX_SPIM3_ENABLED))
NRFX_CHECK(NRFX_SPIM2_ENABLED) || NRFX_CHECK(NRFX_SPIM3_ENABLED) || \
NRFX_CHECK(NRFX_SPIM4_ENABLED))
#error "No enabled SPIM instances. Check <nrfx_config.h>."
#endif
@ -121,29 +122,45 @@
#define SPIM3_SUPPORTED_FREQ_VALIDATE(...) 0
#endif
#if NRFX_CHECK(NRFX_SPIM4_ENABLED)
#define SPIM4_LENGTH_VALIDATE(...) SPIMX_LENGTH_VALIDATE(SPIM4, __VA_ARGS__)
#define SPIM4_HW_CSN_PRESENT_VALIDATE(...) SPIMX_HW_CSN_PRESENT_VALIDATE(SPIM4, __VA_ARGS__)
#define SPIM4_DCX_PRESENT_VALIDATE(...) SPIMX_DCX_PRESENT_VALIDATE(SPIM4, __VA_ARGS__)
#define SPIM4_SUPPORTED_FREQ_VALIDATE(...) SPIMX_SUPPORTED_FREQ_VALIDATE(SPIM4, __VA_ARGS__)
#else
#define SPIM4_LENGTH_VALIDATE(...) 0
#define SPIM4_HW_CSN_PRESENT_VALIDATE(...) 0
#define SPIM4_DCX_PRESENT_VALIDATE(...) 0
#define SPIM4_SUPPORTED_FREQ_VALIDATE(...) 0
#endif
#define SPIM_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) \
(SPIM0_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) || \
SPIM1_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) || \
SPIM2_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) || \
SPIM3_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len))
SPIM3_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) || \
SPIM4_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len))
#define SPIM_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) \
(SPIM0_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM1_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM2_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM3_HW_CSN_PRESENT_VALIDATE(drv_inst_idx))
SPIM3_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM4_HW_CSN_PRESENT_VALIDATE(drv_inst_idx))
#define SPIM_DCX_PRESENT_VALIDATE(drv_inst_idx) \
(SPIM0_DCX_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM1_DCX_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM2_DCX_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM3_DCX_PRESENT_VALIDATE(drv_inst_idx))
SPIM3_DCX_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM4_DCX_PRESENT_VALIDATE(drv_inst_idx))
#define SPIM_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) \
(SPIM0_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) || \
SPIM1_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) || \
SPIM2_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) || \
SPIM3_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq))
SPIM3_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) || \
SPIM4_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq))
#if defined(NRF52840_XXAA) && (NRFX_CHECK(NRFX_SPIM3_ENABLED))
// Enable workaround for nRF52840 anomaly 195 (SPIM3 continues to draw current after disable).
@ -271,6 +288,9 @@ nrfx_err_t nrfx_spim_init(nrfx_spim_t const * p_instance,
#if NRFX_CHECK(NRFX_SPIM3_ENABLED)
nrfx_spim_3_irq_handler,
#endif
#if NRFX_CHECK(NRFX_SPIM4_ENABLED)
nrfx_spim_4_irq_handler,
#endif
};
if (nrfx_prs_acquire(p_instance->p_reg,
irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
@ -757,4 +777,11 @@ void nrfx_spim_3_irq_handler(void)
}
#endif
#if NRFX_CHECK(NRFX_SPIM4_ENABLED)
void nrfx_spim_4_irq_handler(void)
{
irq_handler(NRF_SPIM4, &m_cb[NRFX_SPIM4_INST_IDX]);
}
#endif
#endif // NRFX_CHECK(NRFX_SPIM_ENABLED)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2013 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -49,7 +49,8 @@
(event == NRFX_TWI_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \
(event == NRFX_TWI_EVT_DATA_NACK ? "EVT_DATA_NACK" : \
(event == NRFX_TWI_EVT_OVERRUN ? "EVT_OVERRUN" : \
"UNKNOWN ERROR"))))
(event == NRFX_TWI_EVT_BUS_ERROR ? "EVT_BUS_ERROR" : \
"UNKNOWN ERROR")))))
#define EVT_TO_STR_TWI(event) \
(event == NRF_TWI_EVENT_STOPPED ? "NRF_TWI_EVENT_STOPPED" : \
@ -132,7 +133,25 @@ static nrfx_err_t twi_process_error(uint32_t errorsrc)
return ret;
}
static bool xfer_completeness_check(NRF_TWI_Type * p_twi, twi_control_block_t const * p_cb)
{
// If the actual number of transferred bytes is not equal to what was requested,
// but there was no error signaled by the peripheral, this means that something
// unexpected, like a premature STOP condition, was received on the bus.
// In such case the peripheral has to be disabled and re-enabled, so that its
// internal state machine is reinitialized.
if (p_cb->bytes_transferred != p_cb->curr_length)
{
nrf_twi_disable(p_twi);
nrf_twi_enable(p_twi);
return false;
}
else
{
return true;
}
}
nrfx_err_t nrfx_twi_init(nrfx_twi_t const * p_instance,
nrfx_twi_config_t const * p_config,
@ -267,7 +286,6 @@ static bool twi_send_byte(NRF_TWI_Type * p_twi,
if (p_cb->bytes_transferred < p_cb->curr_length)
{
nrf_twi_txd_set(p_twi, p_cb->p_curr_buf[p_cb->bytes_transferred]);
++(p_cb->bytes_transferred);
}
else
{
@ -321,7 +339,19 @@ static bool twi_receive_byte(NRF_TWI_Type * p_twi,
static bool twi_transfer(NRF_TWI_Type * p_twi,
twi_control_block_t * p_cb)
{
bool do_stop_check = ((p_cb->error) || ((p_cb->bytes_transferred) == p_cb->curr_length));
bool stopped = false;
if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED))
{
nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED));
// Delay handling of STOPPED event till the end of events processing procedure.
// If penultimate byte is received and function gets interrupted for long enough
// after enabling BB_STOP shortcut, RXDREADY for last byte as well as STOPPED
// may be active at the same time. Therefore RXREADY has to be processed before STOPPED to
// acquire last byte before finishing transmission by returning 'false'.
stopped = true;
}
if (p_cb->error)
{
@ -341,6 +371,7 @@ static bool twi_transfer(NRF_TWI_Type * p_twi,
if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT))
{
nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
++(p_cb->bytes_transferred);
NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_TXDSENT));
if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
{
@ -378,11 +409,13 @@ static bool twi_transfer(NRF_TWI_Type * p_twi,
}
}
if (do_stop_check && nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED))
if (stopped)
{
nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
p_cb->prev_suspend = TWI_NO_SUSPEND;
NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED));
if (!p_cb->error)
{
p_cb->error = !xfer_completeness_check(p_twi, p_cb);
}
return false;
}
@ -441,6 +474,10 @@ static nrfx_err_t twi_tx_start_transfer(NRF_TWI_Type * p_twi,
{
ret_code = twi_process_error(errorsrc);
}
else
{
ret_code = NRFX_ERROR_INTERNAL;
}
}
if (hw_timeout <= 0)
@ -510,6 +547,10 @@ static nrfx_err_t twi_rx_start_transfer(NRF_TWI_Type * p_twi,
{
ret_code = twi_process_error(errorsrc);
}
else
{
ret_code = NRFX_ERROR_INTERNAL;
}
}
if (hw_timeout <= 0)
{
@ -678,6 +719,11 @@ static void twi_irq_handler(NRF_TWI_Type * p_twi, twi_control_block_t * p_cb)
event.type = NRFX_TWI_EVT_OVERRUN;
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWI_EVT_OVERRUN));
}
else
{
event.type = NRFX_TWI_EVT_BUS_ERROR;
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWI_EVT_BUS_ERROR));
}
}
else
{
@ -687,7 +733,7 @@ static void twi_irq_handler(NRF_TWI_Type * p_twi, twi_control_block_t * p_cb)
p_cb->busy = false;
if (!(TWI_FLAG_NO_HANDLER_IN_USE(p_cb->flags)))
if (!(TWI_FLAG_NO_HANDLER_IN_USE(p_cb->flags)) || p_cb->error)
{
p_cb->handler(&event, p_cb->p_context);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -51,7 +51,9 @@
(event == NRFX_TWIM_EVT_DONE ? "EVT_DONE" : \
(event == NRFX_TWIM_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \
(event == NRFX_TWIM_EVT_DATA_NACK ? "EVT_DATA_NACK" : \
"UNKNOWN ERROR")))
(event == NRFX_TWIM_EVT_OVERRUN ? "EVT_OVERRUN" : \
(event == NRFX_TWIM_EVT_BUS_ERROR ? "EVT_BUS_ERROR" : \
"UNKNOWN ERROR")))))
#define EVT_TO_STR_TWIM(event) \
(event == NRF_TWIM_EVENT_STOPPED ? "NRF_TWIM_EVENT_STOPPED" : \
@ -157,11 +159,11 @@ static nrfx_err_t twi_process_error(uint32_t errorsrc)
return ret;
}
static bool xfer_completeness_check(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb)
static bool xfer_completeness_check(NRF_TWIM_Type * p_twim, twim_control_block_t const * p_cb)
{
// If the actual number of transferred bytes is not equal to what was requested,
// but there was no error signaled by the peripheral, this means that something
// unexpected, like a premature STOP condition, happened on the bus.
// unexpected, like a premature STOP condition, was received on the bus.
// In such case the peripheral has to be disabled and re-enabled, so that its
// internal state machine is reinitialized.
@ -169,9 +171,12 @@ static bool xfer_completeness_check(NRF_TWIM_Type * p_twim, twim_control_block_t
switch (p_cb->xfer_desc.type)
{
case NRFX_TWIM_XFER_TXTX:
if (((p_cb->int_mask == (NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK)) &&
// int_mask variable is used to determine which length should be checked
// against number of bytes latched in EasyDMA.
// NRF_TWIM_INT_SUSPENDED_MASK is configured only in first TX of TXTX transfer.
if (((p_cb->int_mask & NRF_TWIM_INT_SUSPENDED_MASK) &&
(nrf_twim_txd_amount_get(p_twim) != p_cb->xfer_desc.primary_length)) ||
((p_cb->int_mask == (NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK)) &&
(!(p_cb->int_mask & NRF_TWIM_INT_SUSPENDED_MASK) &&
(nrf_twim_txd_amount_get(p_twim) != p_cb->xfer_desc.secondary_length)))
{
transfer_complete = false;
@ -379,7 +384,6 @@ static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
{
nrfx_err_t err_code = NRFX_SUCCESS;
nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX;
nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED;
p_cb->error = false;
if (!nrfx_is_in_ram(p_xfer_desc->p_primary_buf))
@ -409,10 +413,13 @@ static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
p_cb->xfer_desc = *p_xfer_desc;
p_cb->repeated = (flags & NRFX_TWIM_FLAG_REPEATED_XFER) ? true : false;
p_cb->flags = flags;
nrf_twim_address_set(p_twim, p_xfer_desc->address);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
twim_list_enable_handle(p_twim, flags);
switch (p_xfer_desc->type)
@ -432,8 +439,6 @@ static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
@ -441,7 +446,7 @@ static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED));
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK;
break;
case NRFX_TWIM_XFER_TXRX:
nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
@ -456,7 +461,7 @@ static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK |
NRF_TWIM_SHORT_LASTRX_STOP_MASK);
p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
break;
case NRFX_TWIM_XFER_TX:
@ -464,21 +469,19 @@ static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
if (NRFX_TWIM_FLAG_TX_NO_STOP & flags)
{
nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
evt_to_wait = NRF_TWIM_EVENT_SUSPENDED;
p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK;
}
else
{
nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
}
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
break;
case NRFX_TWIM_XFER_RX:
nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK);
p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
start_task = NRF_TWIM_TASK_STARTRX;
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
break;
@ -496,35 +499,90 @@ static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
{
if (flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER)
{
p_cb->int_mask = NRF_TWIM_INT_ERROR_MASK;
p_cb->int_mask = 0;
}
if (!(flags & NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK))
{
p_cb->int_mask |= NRF_TWIM_INT_STOPPED_MASK;
}
// Interrupts for ERROR are implicitly enabled, regardless of driver configuration.
p_cb->int_mask |= NRF_TWIM_INT_ERROR_MASK;
nrf_twim_int_enable(p_twim, p_cb->int_mask);
#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
if ((flags & NRFX_TWIM_FLAG_HOLD_XFER) && ((p_xfer_desc->type == NRFX_TWIM_XFER_TX) ||
(p_xfer_desc->type == NRFX_TWIM_XFER_TXRX)))
if ((flags & NRFX_TWIM_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRFX_TWIM_XFER_RX))
{
p_cb->flags = flags;
twim_list_enable_handle(p_twim, 0);
p_twim->FREQUENCY = 0;
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
}
else
{
nrf_twim_frequency_set(p_twim, p_cb->bus_frequency);
}
#endif
}
else
{
while (!nrf_twim_event_check(p_twim, evt_to_wait))
{
bool transmission_finished = false;
do {
if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_SUSPENDED))
{
NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED));
transmission_finished = true;
}
if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
{
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED));
transmission_finished = true;
}
if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
{
NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
evt_to_wait = NRF_TWIM_EVENT_STOPPED;
NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
bool lasttx_triggered = nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_LASTTX);
uint32_t shorts_mask = nrf_twim_shorts_get(p_twim);
if (!(lasttx_triggered && (shorts_mask & NRF_TWIM_SHORT_LASTTX_STOP_MASK)))
{
// Unless LASTTX event arrived and LASTTX_STOP shortcut is active,
// triggering of STOP task in case of error has to be done manually.
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
// Mark transmission as not finished yet,
// as STOPPED event is expected to arrive.
// If LASTTX_SUSPENDED shortcut is active,
// NACK has been received on last byte sent
// and SUSPENDED event happened to be checked before ERROR,
// transmission will be marked as finished.
// In such case this flag has to be overwritten.
transmission_finished = false;
}
if (lasttx_triggered && (shorts_mask & NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK))
{
// When STOP task was triggered just before SUSPEND task has taken effect,
// SUSPENDED event may not arrive.
// However if SUSPENDED arrives it always arrives after ERROR.
// Therefore SUSPENDED has to be cleared
// so it does not cause premature termination of busy loop
// waiting for STOPPED event to arrive.
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
// Mark transmission as not finished yet,
// for same reasons as above.
transmission_finished = false;
}
}
}
} while (!transmission_finished);
uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim);
@ -536,7 +594,8 @@ static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
}
else
{
if (!xfer_completeness_check(p_twim, p_cb))
if (!(flags & NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK) &&
!xfer_completeness_check(p_twim, p_cb))
{
err_code = NRFX_ERROR_INTERNAL;
}
@ -629,8 +688,12 @@ static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb
p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
nrf_twim_int_enable(p_twim, p_cb->int_mask);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
if (!(nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_LASTTX) &&
(nrf_twim_shorts_get(p_twim) & NRF_TWIM_SHORT_LASTTX_STOP_MASK)))
{
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
}
p_cb->error = true;
return;
@ -643,19 +706,43 @@ static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb
{
NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED));
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
event.xfer_desc = p_cb->xfer_desc;
if (!p_cb->error)
if (!(p_cb->flags & NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK) && !p_cb->error)
{
p_cb->error = !xfer_completeness_check(p_twim, p_cb);
}
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX);
if (!p_cb->repeated || p_cb->error)
// Further processing of STOPPED event is valid only if NO_XFER_EVT_HANDLER
// setting is not used.
if (!(p_cb->flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER))
{
nrf_twim_shorts_set(p_twim, 0);
p_cb->int_mask = 0;
nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
event.xfer_desc = p_cb->xfer_desc;
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX);
if (!p_cb->repeated || p_cb->error)
{
nrf_twim_shorts_set(p_twim, 0);
p_cb->int_mask = 0;
nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
// At this point interrupt handler should not be invoked again for current transfer.
// If STOPPED arrived during ERROR processing,
// its pending interrupt should be ignored.
// Otherwise spurious NRFX_TWIM_EVT_DONE or NRFX_TWIM_EVT_BUS_ERROR
// would be passed to user's handler.
NRFX_IRQ_PENDING_CLEAR(nrfx_get_irq_number(p_twim));
}
}
#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
else if (p_cb->xfer_desc.type != NRFX_TWIM_XFER_RX)
{
/* Add Anomaly 109 workaround for each potential repeated transfer starting from TX. */
twim_list_enable_handle(p_twim, 0);
p_twim->FREQUENCY = 0;
nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
}
#endif
}
else
{
@ -669,6 +756,13 @@ static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb
nrf_twim_shorts_set(p_twim, 0);
p_cb->int_mask = 0;
nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
// At this point interrupt handler should not be invoked again for current transfer.
// If STOPPED arrived during SUSPENDED processing,
// its pending interrupt should be ignored.
// Otherwise spurious NRFX_TWIM_EVT_DONE or NRFX_TWIM_EVT_BUS_ERROR
// would be passed to user's handler.
NRFX_IRQ_PENDING_CLEAR(nrfx_get_irq_number(p_twim));
}
}
else
@ -696,19 +790,17 @@ static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb
}
else if (errorsrc & NRF_TWIM_ERROR_OVERRUN)
{
event.type = NRFX_TWIM_EVT_DATA_NACK;
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DATA_NACK));
event.type = NRFX_TWIM_EVT_OVERRUN;
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_OVERRUN));
}
else if (p_cb->error)
{
event.type = NRFX_TWIM_EVT_BUS_ERROR;
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_BUS_ERROR));
}
else
{
if (p_cb->error)
{
event.type = NRFX_TWIM_EVT_BUS_ERROR;
}
else
{
event.type = NRFX_TWIM_EVT_DONE;
}
event.type = NRFX_TWIM_EVT_DONE;
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DONE));
}
@ -717,7 +809,10 @@ static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb
p_cb->busy = false;
}
p_cb->handler(&event, p_cb->p_context);
if (!(p_cb->flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER) || p_cb->error)
{
p_cb->handler(&event, p_cb->p_context);
}
}
#if NRFX_CHECK(NRFX_TWIM0_ENABLED)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -191,6 +191,38 @@ static void pins_to_default(nrfx_uarte_t const * p_instance)
}
}
static void apply_workaround_for_enable_anomaly(nrfx_uarte_t const * p_instance)
{
#if defined(NRF5340_XXAA_APPLICATION) || defined(NRF5340_XXAA_NETWORK) || defined(NRF9160_XXAA)
// Apply workaround for anomalies:
// - nRF9160 - anomaly 23
// - nRF5340 - anomaly 44
volatile uint32_t const * rxenable_reg =
(volatile uint32_t *)(((uint32_t)p_instance->p_reg) + 0x564);
volatile uint32_t const * txenable_reg =
(volatile uint32_t *)(((uint32_t)p_instance->p_reg) + 0x568);
if (*txenable_reg == 1)
{
nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX);
}
if (*rxenable_reg == 1)
{
nrf_uarte_enable(p_instance->p_reg);
nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPRX);
while (*rxenable_reg)
{}
(void)nrf_uarte_errorsrc_get_and_clear(p_instance->p_reg);
nrf_uarte_disable(p_instance->p_reg);
}
#else
(void)(p_instance);
#endif // defined(NRF5340_XXAA_APPLICATION) || defined(NRF5340_XXAA_NETWORK) || defined(NRF9160_XXAA)
}
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)
@ -236,6 +268,8 @@ nrfx_err_t nrfx_uarte_init(nrfx_uarte_t const * p_instance,
apply_config(p_instance, p_config);
apply_workaround_for_enable_anomaly(p_instance);
p_cb->handler = event_handler;
p_cb->p_context = p_config->p_context;
@ -262,6 +296,7 @@ void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
{
return;
}
NRF_UARTE_Type * p_reg = p_instance->p_reg;
if (p_cb->handler)
{
@ -269,18 +304,28 @@ void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
}
// Make sure all transfers are finished before UARTE is disabled
// to achieve the lowest power consumption.
nrf_uarte_shorts_disable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPRX);
nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX);
while (!nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED))
nrf_uarte_shorts_disable(p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
// Check if there is any ongoing reception.
if (p_cb->rx_buffer_length)
{
nrf_uarte_event_clear(p_reg, NRF_UARTE_EVENT_RXTO);
nrf_uarte_task_trigger(p_reg, NRF_UARTE_TASK_STOPRX);
}
nrf_uarte_event_clear(p_reg, NRF_UARTE_EVENT_TXSTOPPED);
nrf_uarte_task_trigger(p_reg, NRF_UARTE_TASK_STOPTX);
// Wait for TXSTOPPED event and for RXTO event, provided that there was ongoing reception.
while (!nrf_uarte_event_check(p_reg, NRF_UARTE_EVENT_TXSTOPPED) ||
(p_cb->rx_buffer_length && !nrf_uarte_event_check(p_reg, NRF_UARTE_EVENT_RXTO)))
{}
nrf_uarte_disable(p_instance->p_reg);
nrf_uarte_disable(p_reg);
pins_to_default(p_instance);
#if NRFX_CHECK(NRFX_PRS_ENABLED)
nrfx_prs_release(p_instance->p_reg);
nrfx_prs_release(p_reg);
#endif
p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -809,19 +809,19 @@ static inline void usbd_ep_abort(nrfx_usbd_ep_t ep)
/* Workaround: Disarm the endpoint if there is any data buffered. */
if(ep != NRFX_USBD_EPIN0)
{
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1));
uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1));
uint8_t temp = *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
temp |= (1U << 1);
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp;
(void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) |= temp;
(void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
}
else
{
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7B4;
uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7B4;
uint8_t temp = *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
temp |= (1U << 2);
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp;
(void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) |= temp;
(void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
}
}
if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U << ep2bit(ep)))
@ -1466,7 +1466,7 @@ static void usbd_dmareq_process(void)
}
nrfx_systick_delay_us(30);
while (0 == (0x20 & *((volatile uint32_t *)(NRF_USBD_BASE + 0x474))))
while (0 == (0x20 & *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x474))))
{
nrfx_systick_delay_us(2);
}
@ -1573,54 +1573,54 @@ void nrfx_usbd_irq_handler(void)
{
uint8_t usbi, uoi, uii;
/* Testing */
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9;
uii = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7A9;
uii = (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
if (0 != uii)
{
uii &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
uii &= (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
}
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA;
uoi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AA;
uoi = (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
if (0 != uoi)
{
uoi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
uoi &= (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
}
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB;
usbi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AB;
usbi = (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
if (0 != usbi)
{
usbi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
usbi &= (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
}
/* Processing */
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AC;
uii &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AC;
uii &= (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
if (0 != uii)
{
uint8_t rb;
m_simulated_dataepstatus |= ((uint32_t)uii) << NRFX_USBD_EPIN_BITPOS_0;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uii;
rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7A9;
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = uii;
rb = (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" uii: 0x%.2x (0x%.2x)", uii, rb);
(void)rb;
}
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AD;
uoi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AD;
uoi &= (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
if (0 != uoi)
{
uint8_t rb;
m_simulated_dataepstatus |= ((uint32_t)uoi) << NRFX_USBD_EPOUT_BITPOS_0;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uoi;
rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AA;
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = uoi;
rb = (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" uoi: 0x%.2u (0x%.2x)", uoi, rb);
(void)rb;
}
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AE;
usbi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AE;
usbi &= (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
if (0 != usbi)
{
uint8_t rb;
@ -1632,9 +1632,9 @@ void nrfx_usbd_irq_handler(void)
{
active |= USBD_INTEN_USBRESET_Msk;
}
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = usbi;
rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AB;
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = usbi;
rb = (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" usbi: 0x%.2u (0x%.2x)", usbi, rb);
(void)rb;
}
@ -1791,8 +1791,8 @@ void nrfx_usbd_enable(void)
if (nrfx_usbd_errata_166())
{
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7E3;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0x40;
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7E3;
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = 0x40;
__ISB();
__DSB();
}
@ -2339,9 +2339,9 @@ void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep)
{
NRFX_CRITICAL_SECTION_ENTER();
m_ep_ready &= ~(1U << ep2bit(ep));
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + (2u * NRF_USBD_EP_NR_GET(ep));
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
(void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7C5 + (2u * NRF_USBD_EP_NR_GET(ep));
*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = 0;
(void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
NRFX_CRITICAL_SECTION_EXIT();
}
else

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,6 +33,8 @@
#define NRFX_USBD_ERRATA_H__
#include <stdbool.h>
#include <nrfx.h>
#include <nrf_erratas.h>
#ifndef NRFX_USBD_ERRATA_ENABLE
/**
@ -43,106 +45,46 @@
#define NRFX_USBD_ERRATA_ENABLE 1
#endif
static inline bool nrfx_usbd_errata_type_52840(void)
{
return (*(uint32_t const *)0x10000130UL == 0x8UL);
}
static inline bool nrfx_usbd_errata_type_52840_eng_a_or_later(void)
{
return nrfx_usbd_errata_type_52840();
}
static inline bool nrfx_usbd_errata_type_52840_eng_b_or_later(void)
{
return (nrfx_usbd_errata_type_52840() && (*(uint32_t const *)0x10000134UL >= 0x1UL));
}
static inline bool nrfx_usbd_errata_type_52840_eng_c_or_later(void)
{
return (nrfx_usbd_errata_type_52840() && (*(uint32_t const *)0x10000134UL >= 0x2UL));
}
static inline bool nrfx_usbd_errata_type_52840_eng_d_or_later(void)
{
return (nrfx_usbd_errata_type_52840() && (*(uint32_t const *)0x10000134UL >= 0x3UL));
}
static inline bool nrfx_usbd_errata_type_52833(void)
{
return (*(uint32_t const *)0x10000130UL == 0x0DUL);
}
static inline bool nrfx_usbd_errata_type_52833_eng_a_or_later(void)
{
return nrfx_usbd_errata_type_52833();
}
/* Errata: USBD: EPDATA event is not always generated.
*
* Applies to nRF52840 Engineering A.
**/
/* Errata: USBD: EPDATA event is not always generated. **/
static inline bool nrfx_usbd_errata_104(void)
{
return (NRFX_USBD_ERRATA_ENABLE && (nrfx_usbd_errata_type_52840()
&& !nrfx_usbd_errata_type_52840_eng_b_or_later()));
return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_104();
}
/* Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task.
*
* Applies to nRF52840 Engineering A.
**/
/* Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task. **/
static inline bool nrfx_usbd_errata_154(void)
{
return (NRFX_USBD_ERRATA_ENABLE && (nrfx_usbd_errata_type_52840()
&& !nrfx_usbd_errata_type_52840_eng_b_or_later()));
return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_154();
}
/* Errata: ISO double buffering not functional.
*
* Applies to nRF52840.
**/
/* Errata: ISO double buffering not functional. **/
static inline bool nrfx_usbd_errata_166(void)
{
return (NRFX_USBD_ERRATA_ENABLE && nrfx_usbd_errata_type_52840());
return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_166();
}
/* Errata: USBD might not reach its active state.
*
* Applies to nRF52840.
**/
/* Errata: USBD might not reach its active state. **/
static inline bool nrfx_usbd_errata_171(void)
{
return (NRFX_USBD_ERRATA_ENABLE && nrfx_usbd_errata_type_52840());
return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_171();
}
/* Errata: USB cannot be enabled.
*
* Applies to nRF52840 Engineering B or later and nRF52833.
**/
/* Errata: USB cannot be enabled. **/
static inline bool nrfx_usbd_errata_187(void)
{
return (NRFX_USBD_ERRATA_ENABLE && (nrfx_usbd_errata_type_52840_eng_b_or_later()
|| nrfx_usbd_errata_type_52833()));
return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_187();
}
/* Errata: USBD cannot receive tasks during DMA.
*
* Applies to nRF52840.
**/
/* Errata: USBD cannot receive tasks during DMA. **/
static inline bool nrfx_usbd_errata_199(void)
{
return (NRFX_USBD_ERRATA_ENABLE && nrfx_usbd_errata_type_52840());
return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_199();
}
/* Errata: SIZE.EPOUT not writable.
*
* Applies to nRF52840 Engineering A.
**/
/* Errata: SIZE.EPOUT not writable. **/
static inline bool nrfx_usbd_errata_200(void)
{
return (NRFX_USBD_ERRATA_ENABLE && (nrfx_usbd_errata_type_52840()
&& !nrfx_usbd_errata_type_52840_eng_b_or_later()));
return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_200();
}
#endif // NRFX_USBD_ERRATA_H__

97
drivers/src/nrfx_usbreg.c Normal file
View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <nrfx.h>
#if NRFX_CHECK(NRFX_USBREG_ENABLED)
#include <nrfx_usbreg.h>
static nrfx_usbreg_event_handler_t m_usbevt_handler;
nrfx_usbreg_event_handler_t nrfx_usbreg_handler_get(void)
{
return m_usbevt_handler;
}
void nrfx_usbreg_init(nrfx_usbreg_config_t const * p_config)
{
NRFX_ASSERT(p_config != NULL);
NRFX_ASSERT(p_config->handler != NULL);
nrfx_usbreg_uninit();
m_usbevt_handler = p_config->handler;
NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_USBREGULATOR), p_config->irq_priority);
NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_USBREGULATOR));
}
void nrfx_usbreg_enable(void)
{
nrf_usbreg_int_enable(NRF_USBREGULATOR, NRF_USBREG_INT_USBDETECTED |
NRF_USBREG_INT_USBREMOVED |
NRF_USBREG_INT_USBPWRRDY);
}
void nrfx_usbreg_disable(void)
{
nrf_usbreg_int_disable(NRF_USBREGULATOR, NRF_USBREG_INT_USBDETECTED |
NRF_USBREG_INT_USBREMOVED |
NRF_USBREG_INT_USBPWRRDY);
}
void nrfx_usbreg_uninit(void)
{
nrfx_usbreg_disable();
NRFX_IRQ_DISABLE(nrfx_get_irq_number(NRF_USBREGULATOR));
m_usbevt_handler = NULL;
}
void nrfx_usbreg_irq_handler(void)
{
if (nrf_usbreg_event_check(NRF_USBREGULATOR, NRF_USBREG_EVENT_USBDETECTED))
{
nrf_usbreg_event_clear(NRF_USBREGULATOR, NRF_USBREG_EVENT_USBDETECTED);
m_usbevt_handler(NRFX_USBREG_EVT_DETECTED);
}
if (nrf_usbreg_event_check(NRF_USBREGULATOR, NRF_USBREG_EVENT_USBREMOVED))
{
nrf_usbreg_event_clear(NRF_USBREGULATOR, NRF_USBREG_EVENT_USBREMOVED);
m_usbevt_handler(NRFX_USBREG_EVT_REMOVED);
}
if (nrf_usbreg_event_check(NRF_USBREGULATOR, NRF_USBREG_EVENT_USBPWRRDY))
{
nrf_usbreg_event_clear(NRF_USBREGULATOR, NRF_USBREG_EVENT_USBPWRRDY);
m_usbevt_handler(NRFX_USBREG_EVT_READY);
}
}
#endif // NRFX_CHECK(NRFX_USBREG_ENABLED)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -82,8 +82,12 @@ extern "C" {
#define NRFX_PRS_BOX_0_ADDR NRF_UARTE0
// SPIM1, SPIS1, TWIM1, TWIS1, UARTE1
#define NRFX_PRS_BOX_1_ADDR NRF_UARTE1
// SPIM2, SPIS2, TWIM2, TWIS2, UARTE2
#define NRFX_PRS_BOX_2_ADDR NRF_UARTE2
// SPIM3, SPIS3, TWIM3, TWIS3, UARTE3
#define NRFX_PRS_BOX_3_ADDR NRF_UARTE3
// COMP, LPCOMP
#define NRFX_PRS_BOX_2_ADDR NRF_COMP
#define NRFX_PRS_BOX_4_ADDR NRF_COMP
#elif defined(NRF5340_XXAA_NETWORK)
// SPIM0, SPIS0, TWIM0, TWIS0, UARTE0
#define NRFX_PRS_BOX_0_ADDR NRF_UARTE0

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -67,8 +67,7 @@ NRF_STATIC_INLINE void nrf_bprot_nvm_blocks_protection_enable(NRF_BPROT_Type * p
* NVM protection is disabled by default while debugging.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable True if NVM protection during debug is to be enabled.
* False if otherwise.
* @param[in] enable True if NVM protection during debug is to be enabled, false otherwise.
*/
NRF_STATIC_INLINE void nrf_bprot_nvm_protection_in_debug_set(NRF_BPROT_Type * p_reg,
bool enable);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -101,8 +101,7 @@ NRF_STATIC_INLINE void nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg);
* @brief Function for setting the cache profiling.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable True if cache profiling is to be enabled.
* False if otherwise.
* @param[in] enable True if cache profiling is to be enabled, false otherwise.
*/
NRF_STATIC_INLINE void nrf_cache_profiling_set(NRF_CACHE_Type * p_reg, bool enable);
@ -184,8 +183,7 @@ NRF_STATIC_INLINE uint32_t nrf_cache_data_miss_counter_get(NRF_CACHE_Type const
* @note -Disabling the RAM mode causes the cache to be invalidated.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable True if the cache RAM mode is to be enabled.
* False if otherwise.
* @param[in] enable True if the cache RAM mode is to be enabled, false otherwise.
*/
NRF_STATIC_INLINE void nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg, bool enable);
@ -210,8 +208,7 @@ NRF_STATIC_INLINE void nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg);
* @note Blocking is ignored in the RAM mode.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable True if cache content update lock is to be enabled.
* False if otherwise.
* @param[in] enable True if cache content update lock is to be enabled, false otherwise.
*/
NRF_STATIC_INLINE void nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg, bool enable);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -421,7 +421,12 @@ NRF_STATIC_INLINE void nrf_ccm_cnfptr_set(NRF_CCM_Type * p_reg,
NRF_STATIC_INLINE uint32_t * nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg)
{
#if defined(NRF5340_XXAA_NETWORK)
// Apply workaround for anomaly 10.
return (uint32_t *)(p_reg->CNFPTR | 0x01000000);
#else
return (uint32_t *)(p_reg->CNFPTR);
#endif
}
NRF_STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type * p_reg,
@ -432,7 +437,12 @@ NRF_STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type * p_reg,
NRF_STATIC_INLINE uint32_t * nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg)
{
#if defined(NRF5340_XXAA_NETWORK)
// Apply workaround for anomaly 10.
return (uint32_t *)(p_reg->INPTR | 0x01000000);
#else
return (uint32_t *)(p_reg->INPTR);
#endif
}
NRF_STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type * p_reg,
@ -443,7 +453,12 @@ NRF_STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type * p_reg,
NRF_STATIC_INLINE uint32_t * nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg)
{
#if defined(NRF5340_XXAA_NETWORK)
// Apply workaround for anomaly 10.
return (uint32_t *)(p_reg->OUTPTR | 0x01000000);
#else
return (uint32_t *)(p_reg->OUTPTR);
#endif
}
NRF_STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg,
@ -454,7 +469,12 @@ NRF_STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg,
NRF_STATIC_INLINE uint32_t * nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg)
{
#if defined(NRF5340_XXAA_NETWORK)
// Apply workaround for anomaly 10.
return (uint32_t *)(p_reg->SCRATCHPTR | 0x01000000);
#else
return (uint32_t *)(p_reg->SCRATCHPTR);
#endif
}
#if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -44,8 +44,9 @@ extern "C" {
* @ingroup nrf_clock
* @brief Hardware access layer for managing the CLOCK peripheral.
*
* This code can be used to managing low-frequency clock (LFCLK) and the high-frequency clock
* (HFCLK) settings.
* This code can be used to manage low-frequency clock (LFCLK), high-frequency clock (HFCLK),
* high-frequency 192 MHz clock (HFCLK192M) and high-frequency audio clock (HFCLKAUDIO)
* settings.
*/
#if defined(CLOCK_LFCLKSRC_BYPASS_Msk) && defined(CLOCK_LFCLKSRC_EXTERNAL_Msk)
@ -53,16 +54,57 @@ extern "C" {
#define NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES
#endif
#if defined(CLOCK_CTIV_CTIV_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Presence of the Low Frequency Clock calibration.
*
* In some MCUs there is possibility to use LFCLK calibration.
*/
#if defined(CLOCK_INTENSET_DONE_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Presence of the Low Frequency Clock calibration. */
#define NRF_CLOCK_HAS_CALIBRATION 1
#else
#define NRF_CLOCK_HAS_CALIBRATION 0
#endif // defined(CLOCK_CTIV_CTIV_Msk) || defined(__NRFX_DOXYGEN__)
#endif
#if defined(CLOCK_CTIV_CTIV_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Presence of the Low Frequency Clock calibration timer. */
#define NRF_CLOCK_HAS_CALIBRATION_TIMER 1
#else
#define NRF_CLOCK_HAS_CALIBRATION_TIMER 0
#endif
#if (defined(CLOCK_INTENSET_HFCLK192MSTARTED_Msk) && !defined(NRF5340_XXAA_NETWORK)) \
|| defined(__NRFX_DOXYGEN__)
/** @brief Presence of the 192 MHz clock. */
#define NRF_CLOCK_HAS_HFCLK192M 1
#else
#define NRF_CLOCK_HAS_HFCLK192M 0
#endif
#if (defined(CLOCK_INTENSET_HFCLKAUDIOSTARTED_Msk) && !defined(NRF5340_XXAA_NETWORK)) \
|| defined(__NRFX_DOXYGEN__)
/** @brief Presence of the Audio clock. */
#define NRF_CLOCK_HAS_HFCLKAUDIO 1
#else
#define NRF_CLOCK_HAS_HFCLKAUDIO 0
#endif
#if (defined(CLOCK_HFCLKCTRL_HCLK_Msk) && !defined(NRF5340_XXAA_NETWORK)) \
|| defined(__NRFX_DOXYGEN__)
/** @brief Presence of HFCLK frequency configuration. */
#define NRF_CLOCK_HAS_HFCLK_DIV 1
#else
#define NRF_CLOCK_HAS_HFCLK_DIV 0
#endif
#if defined(CLOCK_LFCLKALWAYSRUN_ALWAYSRUN_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Presence of ALWAYSRUN registers. */
#define NRF_CLOCK_HAS_ALWAYSRUN 1
#else
#define NRF_CLOCK_HAS_ALWAYSRUN 0
#endif
#if defined(CLOCK_HFCLKSRC_SRC_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Presence of HFCLKSRC register. */
#define NRF_CLOCK_HAS_HFCLKSRC 1
#else
#define NRF_CLOCK_HAS_HFCLKSRC 0
#endif
/**
* @brief Low-frequency clock sources.
@ -70,6 +112,9 @@ extern "C" {
*/
typedef enum
{
#if defined(CLOCK_LFCLKSRC_SRC_LFULP) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_LFCLK_LFULP = CLOCK_LFCLKSRC_SRC_LFULP, /**< Internal 32 kHz Ultra-low power oscillator. */
#endif
#if defined(CLOCK_LFCLKSRC_SRC_RC) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */
#else
@ -102,11 +147,16 @@ typedef enum
#endif // defined(NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES) || defined(__NRFX_DOXYGEN__)
} nrf_clock_lfclk_t;
/** @brief High-frequency clock sources. */
/**
* @brief High-frequency clock sources.
* @details Used by HFCLKSTAT and HFCLK192MSTAT registers.
*/
typedef enum
{
#if defined(CLOCK_HFCLKSTAT_SRC_RC) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */
#elif defined(CLOCK_HFCLKSTAT_SRC_HFINT)
NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_HFINT, /**< Internal 16 MHz RC oscillator. */
#endif
#if defined(CLOCK_HFCLKSTAT_SRC_Xtal) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */
@ -115,8 +165,39 @@ typedef enum
#endif
} nrf_clock_hfclk_t;
/** @brief Clock domains. */
typedef enum
{
NRF_CLOCK_DOMAIN_LFCLK,
NRF_CLOCK_DOMAIN_HFCLK,
#if NRF_CLOCK_HAS_HFCLK192M
NRF_CLOCK_DOMAIN_HFCLK192M,
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
NRF_CLOCK_DOMAIN_HFCLKAUDIO,
#endif
} nrf_clock_domain_t;
#if NRF_CLOCK_HAS_HFCLK_DIV || NRF_CLOCK_HAS_HFCLK192M
/**
* @brief High-frequency clock frequency configuration.
* @details Used by HFCLKCTRL and HFCLK192MCTRL registers.
*/
typedef enum
{
NRF_CLOCK_HFCLK_DIV_1 = CLOCK_HFCLKCTRL_HCLK_Div1, /**< Divide HFCLK/HFCLK192M by 1 */
NRF_CLOCK_HFCLK_DIV_2 = CLOCK_HFCLKCTRL_HCLK_Div2, /**< Divide HFCLK/HFCLK192M by 2 */
#if NRF_CLOCK_HAS_HFCLK192M
NRF_CLOCK_HFCLK_DIV_4 = CLOCK_HFCLK192MCTRL_HCLK192M_Div4, /**< Divide HFCLK192M by 4 */
#endif
} nrf_clock_hfclk_div_t;
#endif // NRF_CLOCK_HAS_HFCLK_DIV || NRF_CLOCK_HAS_HFCLK192M
/**
* @brief Trigger status of task LFCLKSTART/HFCLKSTART.
*
* @note This enum is deprecated.
*
* @details Used by LFCLKRUN and HFCLKRUN registers.
*/
typedef enum
@ -128,15 +209,24 @@ typedef enum
/** @brief Interrupts. */
typedef enum
{
NRF_CLOCK_INT_HF_STARTED_MASK = CLOCK_INTENSET_HFCLKSTARTED_Msk, /**< Interrupt on HFCLKSTARTED event. */
NRF_CLOCK_INT_LF_STARTED_MASK = CLOCK_INTENSET_LFCLKSTARTED_Msk, /**< Interrupt on LFCLKSTARTED event. */
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_INT_DONE_MASK = CLOCK_INTENSET_DONE_Msk, /**< Interrupt on DONE event. */
NRF_CLOCK_INT_CTTO_MASK = CLOCK_INTENSET_CTTO_Msk, /**< Interrupt on CTTO event. */
NRF_CLOCK_INT_HF_STARTED_MASK = CLOCK_INTENSET_HFCLKSTARTED_Msk, /**< Interrupt on HFCLKSTARTED event. */
NRF_CLOCK_INT_LF_STARTED_MASK = CLOCK_INTENSET_LFCLKSTARTED_Msk, /**< Interrupt on LFCLKSTARTED event. */
#if NRF_CLOCK_HAS_CALIBRATION
NRF_CLOCK_INT_DONE_MASK = CLOCK_INTENSET_DONE_Msk, /**< Interrupt on DONE event. */
#endif
#if NRF_CLOCK_HAS_CALIBRATION_TIMER
NRF_CLOCK_INT_CTTO_MASK = CLOCK_INTENSET_CTTO_Msk, /**< Interrupt on CTTO event. */
#endif
#if defined(CLOCK_INTENSET_CTSTARTED_Msk) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_INT_CTSTARTED_MASK = CLOCK_INTENSET_CTSTARTED_Msk, /**< Interrupt on CTSTARTED event. */
NRF_CLOCK_INT_CTSTOPPED_MASK = CLOCK_INTENSET_CTSTOPPED_Msk /**< Interrupt on CTSTOPPED event. */
NRF_CLOCK_INT_CTSTARTED_MASK = CLOCK_INTENSET_CTSTARTED_Msk, /**< Interrupt on CTSTARTED event. */
NRF_CLOCK_INT_CTSTOPPED_MASK = CLOCK_INTENSET_CTSTOPPED_Msk /**< Interrupt on CTSTOPPED event. */
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
NRF_CLOCK_INT_HFAUDIO_STARTED_MASK = CLOCK_INTENSET_HFCLKAUDIOSTARTED_Msk, /**< Interrupt on HFCLKAUDIOSTARTED event. */
#endif
#if NRF_CLOCK_HAS_HFCLK192M
NRF_CLOCK_INT_HF192M_STARTED_MASK = CLOCK_INTENSET_HFCLK192MSTARTED_Msk, /**< Interrupt on HFCLK192MSTARTED event. */
#endif
} nrf_clock_int_mask_t;
@ -148,29 +238,47 @@ typedef enum
*/
typedef enum
{
NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /**< Start HFCLK clock source.*/
NRF_CLOCK_TASK_HFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTOP), /**< Stop HFCLK clock source.*/
NRF_CLOCK_TASK_LFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTART), /**< Start LFCLK clock source.*/
NRF_CLOCK_TASK_LFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTOP), /**< Stop LFCLK clock source.*/
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_TASK_CAL = offsetof(NRF_CLOCK_Type, TASKS_CAL), /**< Start calibration of LFCLK RC oscillator.*/
NRF_CLOCK_TASK_CTSTART = offsetof(NRF_CLOCK_Type, TASKS_CTSTART), /**< Start calibration timer.*/
NRF_CLOCK_TASK_CTSTOP = offsetof(NRF_CLOCK_Type, TASKS_CTSTOP) /**< Stop calibration timer.*/
NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /**< Start HFCLK clock source. */
NRF_CLOCK_TASK_HFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTOP), /**< Stop HFCLK clock source. */
NRF_CLOCK_TASK_LFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTART), /**< Start LFCLK clock source. */
NRF_CLOCK_TASK_LFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTOP), /**< Stop LFCLK clock source. */
#if NRF_CLOCK_HAS_CALIBRATION
NRF_CLOCK_TASK_CAL = offsetof(NRF_CLOCK_Type, TASKS_CAL), /**< Start calibration of LFCLK RC oscillator. */
#endif
#if NRF_CLOCK_HAS_CALIBRATION_TIMER
NRF_CLOCK_TASK_CTSTART = offsetof(NRF_CLOCK_Type, TASKS_CTSTART), /**< Start calibration timer. */
NRF_CLOCK_TASK_CTSTOP = offsetof(NRF_CLOCK_Type, TASKS_CTSTOP) /**< Stop calibration timer. */
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
NRF_CLOCK_TASK_HFCLKAUDIOSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKAUDIOSTART), /**< Start HFCLKAUDIO clock source. */
NRF_CLOCK_TASK_HFCLKAUDIOSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKAUDIOSTOP), /**< Stop HFCLKAUDIO clock source. */
#endif
#if NRF_CLOCK_HAS_HFCLK192M
NRF_CLOCK_TASK_HFCLK192MSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLK192MSTART), /**< Start HFCLK192M clock source. */
NRF_CLOCK_TASK_HFCLK192MSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLK192MSTOP), /**< Stop HFCLK192M clock source. */
#endif
} nrf_clock_task_t;
/** @brief Events. */
typedef enum
{
NRF_CLOCK_EVENT_HFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED), /**< HFCLK oscillator started.*/
NRF_CLOCK_EVENT_LFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_LFCLKSTARTED), /**< LFCLK oscillator started.*/
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_EVENT_DONE = offsetof(NRF_CLOCK_Type, EVENTS_DONE), /**< Calibration of LFCLK RC oscillator completed.*/
NRF_CLOCK_EVENT_CTTO = offsetof(NRF_CLOCK_Type, EVENTS_CTTO), /**< Calibration timer time-out.*/
NRF_CLOCK_EVENT_HFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED), /**< HFCLK oscillator started. */
NRF_CLOCK_EVENT_LFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_LFCLKSTARTED), /**< LFCLK oscillator started. */
#if NRF_CLOCK_HAS_CALIBRATION
NRF_CLOCK_EVENT_DONE = offsetof(NRF_CLOCK_Type, EVENTS_DONE), /**< Calibration of LFCLK RC oscillator completed. */
#endif
#if NRF_CLOCK_HAS_CALIBRATION_TIMER
NRF_CLOCK_EVENT_CTTO = offsetof(NRF_CLOCK_Type, EVENTS_CTTO), /**< Calibration timer time-out. */
#endif
#if defined(CLOCK_INTENSET_CTSTARTED_Msk) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_EVENT_CTSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_CTSTARTED), /**< Calibration timer started.*/
NRF_CLOCK_EVENT_CTSTOPPED = offsetof(NRF_CLOCK_Type, EVENTS_CTSTOPPED) /**< Calibration timer stopped.*/
NRF_CLOCK_EVENT_CTSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_CTSTARTED), /**< Calibration timer started. */
NRF_CLOCK_EVENT_CTSTOPPED = offsetof(NRF_CLOCK_Type, EVENTS_CTSTOPPED) /**< Calibration timer stopped. */
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
NRF_CLOCK_EVENT_HFCLKAUDIOSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKAUDIOSTARTED), /**< HFCLKAUDIO oscillator started. */
#endif
#if NRF_CLOCK_HAS_HFCLK192M
NRF_CLOCK_EVENT_HFCLK192MSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLK192MSTARTED), /**< HFCLK192M oscillator started. */
#endif
} nrf_clock_event_t;
@ -251,9 +359,38 @@ NRF_STATIC_INLINE void nrf_clock_event_clear(NRF_CLOCK_Type * p_reg, nrf_clock_e
*/
NRF_STATIC_INLINE bool nrf_clock_event_check(NRF_CLOCK_Type const * p_reg, nrf_clock_event_t event);
/**
* @brief Function for retrieving the trigger status of the task START for given domain.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] domain Clock domain.
*
* @retval false The task START for the given domain has not been triggered.
* @retval true The task START for the given domain has been triggered.
*/
NRF_STATIC_INLINE bool nrf_clock_start_task_check(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain);
/**
* @brief Function for retrieving the state of the clock.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] domain Clock domain.
* @param[out] clk_src Clock source that is running. Set to NULL if not needed.
* Ignored for HFCLKAUDIO domain. Typecast it to @ref nrf_clock_lfclk_t for
* LFCLK and @ref nrf_clock_hfclk_t for HFCLK and HFCLK192M.
*
* @retval false The clock is not running.
* @retval true The clock is running.
*/
NRF_STATIC_INLINE bool nrf_clock_is_running(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain,
void * clk_src);
/**
* @brief Function for changing the low-frequency clock source.
* @details This function cannot be called when the low-frequency clock is running.
* @details Check in Product Specification if this function can be called when
* the low-frequency clock is running.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] source New low-frequency clock source.
@ -277,6 +414,8 @@ NRF_STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(NRF_CLOCK_Type const *
/**
* @brief Function for retrieving the active source of the low-frequency clock.
*
* @note This function is deprecated. Use @ref nrf_clock_is_running instead.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval NRF_CLOCK_LFCLK_RC The internal 32 kHz RC oscillator
@ -306,6 +445,8 @@ NRF_STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(NRF_CLOCK_Type cons
/**
* @brief Function for retrieving the state of the LFCLK clock.
*
* @note This function is deprecated. Use @ref nrf_clock_is_running instead.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval false The LFCLK clock is not running.
@ -316,6 +457,8 @@ NRF_STATIC_INLINE bool nrf_clock_lf_is_running(NRF_CLOCK_Type const * p_reg);
/**
* @brief Function for retrieving the trigger status of the task LFCLKSTART.
*
* @note This function is deprecated. Use @ref nrf_clock_start_task_check instead.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED The task LFCLKSTART has not been triggered.
@ -324,14 +467,27 @@ NRF_STATIC_INLINE bool nrf_clock_lf_is_running(NRF_CLOCK_Type const * p_reg);
NRF_STATIC_INLINE
nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(NRF_CLOCK_Type const * p_reg);
#if NRF_CLOCK_HAS_HFCLKSRC
/**
* @brief Function for retrieving the active source of the high-frequency clock.
* @brief Function for changing the high-frequency clock source.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] source New high-frequency clock source.
*/
NRF_STATIC_INLINE void nrf_clock_hf_src_set(NRF_CLOCK_Type * p_reg, nrf_clock_hfclk_t source);
#endif
/**
* @brief Function for retrieving the selected source of the high-frequency clock.
*
* For SoCs not featuring the HFCLKSRC register, this is always also the active source
* of the high-frequency clock.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval NRF_CLOCK_HFCLK_LOW_ACCURACY The internal RC oscillator is the active
* @retval NRF_CLOCK_HFCLK_LOW_ACCURACY The internal RC oscillator is the selected
* source of the high-frequency clock.
* @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY An external crystal oscillator is the active
* @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY An external crystal oscillator is the selected
* source of the high-frequency clock.
*/
NRF_STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(NRF_CLOCK_Type const * p_reg);
@ -339,6 +495,8 @@ NRF_STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(NRF_CLOCK_Type const *
/**
* @brief Function for retrieving the state of the HFCLK clock.
*
* @note This function is deprecated. Use @ref nrf_clock_is_running instead.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] clk_src Clock source to be checked.
*
@ -351,6 +509,8 @@ NRF_STATIC_INLINE bool nrf_clock_hf_is_running(NRF_CLOCK_Type const * p_reg,
/**
* @brief Function for retrieving the trigger status of the task HFCLKSTART.
*
* @note This function is deprecated. Use @ref nrf_clock_start_task_check instead.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED The task HFCLKSTART has not been triggered.
@ -359,7 +519,38 @@ NRF_STATIC_INLINE bool nrf_clock_hf_is_running(NRF_CLOCK_Type const * p_reg,
NRF_STATIC_INLINE
nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(NRF_CLOCK_Type const * p_reg);
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__)
#if NRF_CLOCK_HAS_HFCLKAUDIO
/**
* @brief Function for changing the Audio clock FREQ_VALUE.
*
* The frequency of HFCLKAUDIO ranges from 10.666 MHz to 13.333 MHz in 40.7 Hz steps.
* To calculate @p freq_value corresponding to the chosen frequency, use the following equation:
* FREQ_VALUE = 2^16 * ((12 * f_out / 32M) - 4)
*
* @warning Chosen frequency must fit in 11.176 MHz - 11.402 MHz or 12.165 MHz - 12.411 MHz frequency bands.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] freq_value New FREQ_VALUE
*/
NRF_STATIC_INLINE
void nrf_clock_hfclkaudio_config_set(NRF_CLOCK_Type * p_reg, uint16_t freq_value);
/**
* @brief Function for retrieving the Audio clock FREQ_VALUE.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* The frequency of HFCLKAUDIO ranges from 10.666 MHz to 13.333 MHz in 40.7 Hz steps.
* To calculate frequency corresponding to the returned FREQ_VALUE, use the following equation:
* f_out = 32M * (4 + FREQ_VALUE * 2^(-16))/12
* @return FREQ_VALUE of the Audio clock.
*/
NRF_STATIC_INLINE
uint16_t nrf_clock_hfclkaudio_config_get(NRF_CLOCK_Type const * p_reg);
#endif
#if NRF_CLOCK_HAS_CALIBRATION_TIMER
/**
* @brief Function for changing the calibration timer interval.
*
@ -370,6 +561,102 @@ nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(NRF_CLOCK_Type
NRF_STATIC_INLINE void nrf_clock_cal_timer_timeout_set(NRF_CLOCK_Type * p_reg, uint32_t interval);
#endif
#if NRF_CLOCK_HAS_HFCLK_DIV
/**
* @brief Function for changing the HFCLK frequency divider.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] divider New HFCLK divider.
*/
NRF_STATIC_INLINE void nrf_clock_hfclk_div_set(NRF_CLOCK_Type * p_reg,
nrf_clock_hfclk_div_t divider);
/**
* @brief Function for retrieving the HFCLK frequency divider.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return HFCLK frequency divider.
*/
NRF_STATIC_INLINE nrf_clock_hfclk_div_t nrf_clock_hfclk_div_get(NRF_CLOCK_Type const * p_reg);
#endif
#if NRF_CLOCK_HAS_HFCLK192M
/**
* @brief Function for changing the HFCLK192M frequency divider.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] divider New HFCLK192M divider.
*/
NRF_STATIC_INLINE void nrf_clock_hfclk192m_div_set(NRF_CLOCK_Type * p_reg,
nrf_clock_hfclk_div_t divider);
/**
* @brief Function for retrieving the HFCLK192M frequency divider.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return HFCLK192M frequency divider.
*/
NRF_STATIC_INLINE nrf_clock_hfclk_div_t nrf_clock_hfclk192m_div_get(NRF_CLOCK_Type const * p_reg);
/**
* @brief Function for changing the HFCLK192M source.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] source New HFCLK192M source.
*/
NRF_STATIC_INLINE void nrf_clock_hfclk192m_src_set(NRF_CLOCK_Type * p_reg,
nrf_clock_hfclk_t source);
/**
* @brief Function for retrieving the selected source of the HFCLK192M.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval NRF_CLOCK_HFCLK_LOW_ACCURACY The internal RC oscillator is the selected
* source of the HFCLK192M.
* @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY An external crystal oscillator is the selected
* source of the HFCLK192M.
*/
NRF_STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hfclk192m_src_get(NRF_CLOCK_Type const * p_reg);
#endif // NRF_CLOCK_HAS_HFCLK192M
#if NRF_CLOCK_HAS_ALWAYSRUN
/**
* @brief Function for setting the clock domain to always run.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] domain Clock domain.
* @param[in] alwaysrun Ensure the clock is always running.
*/
NRF_STATIC_INLINE void nrf_clock_alwaysrun_set(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain,
bool alwaysrun);
/**
* @brief Function for checking if the clock domain is configured to always run.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] domain Clock domain.
*
* @retval true The clock domain is configured to always run.
* @retval false The clock domain is not configured to always run.
*/
NRF_STATIC_INLINE bool nrf_clock_alwaysrun_get(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain);
/**
* @brief Function for checking if the clock domain always run setting is active.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] domain Clock domain.
*
* @retval true The clock domain always run setting is active.
* @retval false The clock domain always run setting is not active.
*/
NRF_STATIC_INLINE bool nrf_clock_alwaysrun_active_get(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain);
#endif
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
@ -462,6 +749,89 @@ NRF_STATIC_INLINE bool nrf_clock_event_check(NRF_CLOCK_Type const * p_reg, nrf_c
return (bool)*((volatile uint32_t *)((uint8_t *)p_reg + event));
}
NRF_STATIC_INLINE bool nrf_clock_start_task_check(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain)
{
switch (domain)
{
case NRF_CLOCK_DOMAIN_LFCLK:
return ((p_reg->LFCLKRUN & CLOCK_LFCLKRUN_STATUS_Msk)
>> CLOCK_LFCLKRUN_STATUS_Pos);
case NRF_CLOCK_DOMAIN_HFCLK:
return ((p_reg->HFCLKRUN & CLOCK_HFCLKRUN_STATUS_Msk)
>> CLOCK_HFCLKRUN_STATUS_Pos);
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
return ((p_reg->HFCLK192MRUN & CLOCK_HFCLK192MRUN_STATUS_Msk)
>> CLOCK_HFCLK192MRUN_STATUS_Pos);
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
case NRF_CLOCK_DOMAIN_HFCLKAUDIO:
return ((p_reg->HFCLKAUDIORUN & CLOCK_HFCLKAUDIORUN_STATUS_Msk)
>> CLOCK_HFCLKAUDIORUN_STATUS_Pos);
#endif
default:
NRFX_ASSERT(0);
return false;
}
}
NRF_STATIC_INLINE bool nrf_clock_is_running(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain,
void * clk_src)
{
switch (domain)
{
case NRF_CLOCK_DOMAIN_LFCLK:
if (clk_src != NULL)
{
(*(uint32_t *)clk_src) = ((p_reg->LFCLKSTAT & CLOCK_LFCLKSTAT_SRC_Msk)
>> CLOCK_LFCLKSTAT_SRC_Pos);
}
if ((p_reg->LFCLKSTAT & CLOCK_LFCLKSTAT_STATE_Msk)
>> CLOCK_LFCLKSTAT_STATE_Pos)
{
return true;
}
break;
case NRF_CLOCK_DOMAIN_HFCLK:
if (clk_src != NULL)
{
(*(uint32_t *)clk_src) = ((p_reg->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk)
>> CLOCK_HFCLKSTAT_SRC_Pos);
}
if ((p_reg->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk)
>> CLOCK_HFCLKSTAT_STATE_Pos)
{
return true;
}
break;
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
if (clk_src != NULL)
{
(*(uint32_t *)clk_src) = ((p_reg->HFCLK192MSTAT & CLOCK_HFCLK192MSTAT_SRC_Msk)
>> CLOCK_HFCLK192MSTAT_SRC_Pos);
}
if ((p_reg->HFCLK192MSTAT & CLOCK_HFCLK192MSTAT_STATE_Msk)
>> CLOCK_HFCLK192MSTAT_STATE_Pos)
{
return true;
}
break;
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
case NRF_CLOCK_DOMAIN_HFCLKAUDIO:
return (p_reg->HFCLKAUDIOSTAT & CLOCK_HFCLKAUDIOSTAT_STATE_Msk) ==
CLOCK_HFCLKAUDIOSTAT_STATE_Msk;
#endif
default:
NRFX_ASSERT(0);
return false;
}
return false;
}
NRF_STATIC_INLINE void nrf_clock_lf_src_set(NRF_CLOCK_Type * p_reg, nrf_clock_lfclk_t source)
{
p_reg->LFCLKSRC = (uint32_t)(source);
@ -474,8 +844,9 @@ NRF_STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(NRF_CLOCK_Type const *
NRF_STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(NRF_CLOCK_Type const * p_reg)
{
return (nrf_clock_lfclk_t)((p_reg->LFCLKSTAT & CLOCK_LFCLKSTAT_SRC_Msk)
>> CLOCK_LFCLKSTAT_SRC_Pos);
nrf_clock_lfclk_t clk_src;
(void)nrf_clock_is_running(p_reg, NRF_CLOCK_DOMAIN_LFCLK, &clk_src);
return clk_src;
}
NRF_STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(NRF_CLOCK_Type const * p_reg)
@ -486,43 +857,203 @@ NRF_STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(NRF_CLOCK_Type cons
NRF_STATIC_INLINE bool nrf_clock_lf_is_running(NRF_CLOCK_Type const * p_reg)
{
return ((p_reg->LFCLKSTAT & CLOCK_LFCLKSTAT_STATE_Msk) >> CLOCK_LFCLKSTAT_STATE_Pos);
return nrf_clock_is_running(p_reg, NRF_CLOCK_DOMAIN_LFCLK, NULL);
}
NRF_STATIC_INLINE
nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(NRF_CLOCK_Type const * p_reg)
{
return (nrf_clock_start_task_status_t)((p_reg->LFCLKRUN & CLOCK_LFCLKRUN_STATUS_Msk)
>> CLOCK_LFCLKRUN_STATUS_Pos);
return (nrf_clock_start_task_status_t)nrf_clock_start_task_check(p_reg,
NRF_CLOCK_DOMAIN_LFCLK);
}
#if NRF_CLOCK_HAS_HFCLKSRC
NRF_STATIC_INLINE void nrf_clock_hf_src_set(NRF_CLOCK_Type * p_reg, nrf_clock_hfclk_t source)
{
p_reg->HFCLKSRC = (uint32_t)(source);
}
#endif
NRF_STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(NRF_CLOCK_Type const * p_reg)
{
#if NRF_CLOCK_HAS_HFCLKSRC
return (nrf_clock_hfclk_t)(p_reg->HFCLKSRC);
#else
return (nrf_clock_hfclk_t)((p_reg->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk)
>> CLOCK_HFCLKSTAT_SRC_Pos);
#endif
}
NRF_STATIC_INLINE bool nrf_clock_hf_is_running(NRF_CLOCK_Type const * p_reg,
nrf_clock_hfclk_t clk_src)
{
return (p_reg->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) ==
(CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos));
nrf_clock_hfclk_t active_clk_src;
bool ret = nrf_clock_is_running(p_reg, NRF_CLOCK_DOMAIN_HFCLK, &active_clk_src);
return (ret && (active_clk_src == clk_src));
}
NRF_STATIC_INLINE
nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(NRF_CLOCK_Type const * p_reg)
{
return (nrf_clock_start_task_status_t)((p_reg->HFCLKRUN & CLOCK_HFCLKRUN_STATUS_Msk)
>> CLOCK_HFCLKRUN_STATUS_Pos);
return (nrf_clock_start_task_status_t)nrf_clock_start_task_check(p_reg,
NRF_CLOCK_DOMAIN_HFCLK);
}
#if (NRF_CLOCK_HAS_CALIBRATION)
#if NRF_CLOCK_HAS_HFCLKAUDIO
NRF_STATIC_INLINE
void nrf_clock_hfclkaudio_config_set(NRF_CLOCK_Type * p_reg, uint16_t freq_value)
{
p_reg->HFCLKAUDIO.FREQUENCY = freq_value;
}
NRF_STATIC_INLINE
uint16_t nrf_clock_hfclkaudio_config_get(NRF_CLOCK_Type const * p_reg)
{
return (uint16_t)(p_reg->HFCLKAUDIO.FREQUENCY);
}
#endif
#if NRF_CLOCK_HAS_HFCLK_DIV
NRF_STATIC_INLINE
void nrf_clock_hfclk_div_set(NRF_CLOCK_Type * p_reg, nrf_clock_hfclk_div_t divider)
{
p_reg->HFCLKCTRL = (((uint8_t)(divider) << CLOCK_HFCLKCTRL_HCLK_Pos) &
CLOCK_HFCLKCTRL_HCLK_Msk);
}
NRF_STATIC_INLINE nrf_clock_hfclk_div_t nrf_clock_hfclk_div_get(NRF_CLOCK_Type const * p_reg)
{
return (nrf_clock_hfclk_div_t)((p_reg->HFCLKCTRL & CLOCK_HFCLKCTRL_HCLK_Msk)
>> CLOCK_HFCLKCTRL_HCLK_Pos);
}
#endif
#if NRF_CLOCK_HAS_HFCLK192M
NRF_STATIC_INLINE
void nrf_clock_hfclk192m_div_set(NRF_CLOCK_Type * p_reg, nrf_clock_hfclk_div_t divider)
{
p_reg->HFCLK192MCTRL = (((uint8_t)(divider) << CLOCK_HFCLK192MCTRL_HCLK192M_Pos) &
CLOCK_HFCLK192MCTRL_HCLK192M_Msk);
}
NRF_STATIC_INLINE nrf_clock_hfclk_div_t nrf_clock_hfclk192m_div_get(NRF_CLOCK_Type const * p_reg)
{
return (nrf_clock_hfclk_div_t)((p_reg->HFCLK192MCTRL & CLOCK_HFCLK192MCTRL_HCLK192M_Msk)
>> CLOCK_HFCLK192MCTRL_HCLK192M_Pos);
}
NRF_STATIC_INLINE void nrf_clock_hfclk192m_src_set(NRF_CLOCK_Type * p_reg, nrf_clock_hfclk_t source)
{
p_reg->HFCLK192MSRC = (uint32_t)(source);
}
NRF_STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hfclk192m_src_get(NRF_CLOCK_Type const * p_reg)
{
return (nrf_clock_hfclk_t)(p_reg->HFCLK192MSRC);
}
#endif
#if NRF_CLOCK_HAS_CALIBRATION_TIMER
NRF_STATIC_INLINE void nrf_clock_cal_timer_timeout_set(NRF_CLOCK_Type * p_reg, uint32_t interval)
{
p_reg->CTIV = ((interval << CLOCK_CTIV_CTIV_Pos) & CLOCK_CTIV_CTIV_Msk);
}
#endif
#if NRF_CLOCK_HAS_ALWAYSRUN
NRF_STATIC_INLINE void nrf_clock_alwaysrun_set(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain,
bool alwaysrun)
{
/* ALWAYSRUN registers should be R/W, but are marked as read-only.
* Redefine them as R/W as a workaround. */
switch (domain)
{
case NRF_CLOCK_DOMAIN_LFCLK:
*(volatile uint32_t *)(&p_reg->LFCLKALWAYSRUN) =
((alwaysrun << CLOCK_LFCLKALWAYSRUN_ALWAYSRUN_Pos)
& CLOCK_LFCLKALWAYSRUN_ALWAYSRUN_Msk);
break;
case NRF_CLOCK_DOMAIN_HFCLK:
*(volatile uint32_t *)(&p_reg->HFCLKALWAYSRUN) =
((alwaysrun << CLOCK_HFCLKALWAYSRUN_ALWAYSRUN_Pos)
& CLOCK_HFCLKALWAYSRUN_ALWAYSRUN_Msk);
break;
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
*(volatile uint32_t *)(&p_reg->HFCLK192MALWAYSRUN) =
((alwaysrun << CLOCK_HFCLK192MALWAYSRUN_ALWAYSRUN_Pos)
& CLOCK_HFCLK192MALWAYSRUN_ALWAYSRUN_Msk);
break;
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
case NRF_CLOCK_DOMAIN_HFCLKAUDIO:
*(volatile uint32_t *)(&p_reg->HFCLKAUDIOALWAYSRUN) =
((alwaysrun << CLOCK_HFCLKAUDIOALWAYSRUN_ALWAYSRUN_Pos)
& CLOCK_HFCLKAUDIOALWAYSRUN_ALWAYSRUN_Msk);
break;
#endif
default:
NRFX_ASSERT(0);
break;
}
}
NRF_STATIC_INLINE bool nrf_clock_alwaysrun_get(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain)
{
switch (domain)
{
case NRF_CLOCK_DOMAIN_LFCLK:
return ((p_reg->LFCLKALWAYSRUN & CLOCK_LFCLKALWAYSRUN_ALWAYSRUN_Msk)
>> CLOCK_LFCLKALWAYSRUN_ALWAYSRUN_Pos);
case NRF_CLOCK_DOMAIN_HFCLK:
return ((p_reg->HFCLKALWAYSRUN & CLOCK_HFCLKALWAYSRUN_ALWAYSRUN_Msk)
>> CLOCK_HFCLKALWAYSRUN_ALWAYSRUN_Pos);
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
return ((p_reg->HFCLK192MALWAYSRUN & CLOCK_HFCLK192MALWAYSRUN_ALWAYSRUN_Msk)
>> CLOCK_HFCLK192MALWAYSRUN_ALWAYSRUN_Pos);
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
case NRF_CLOCK_DOMAIN_HFCLKAUDIO:
return ((p_reg->HFCLKAUDIOALWAYSRUN & CLOCK_HFCLKAUDIOALWAYSRUN_ALWAYSRUN_Msk)
>> CLOCK_HFCLKAUDIOALWAYSRUN_ALWAYSRUN_Pos);
#endif
default:
NRFX_ASSERT(0);
return false;
}
}
NRF_STATIC_INLINE bool nrf_clock_alwaysrun_active_get(NRF_CLOCK_Type const * p_reg,
nrf_clock_domain_t domain)
{
switch (domain)
{
case NRF_CLOCK_DOMAIN_LFCLK:
return ((p_reg->LFCLKSTAT & CLOCK_LFCLKSTAT_ALWAYSRUNNING_Msk)
>> CLOCK_LFCLKSTAT_ALWAYSRUNNING_Pos);
case NRF_CLOCK_DOMAIN_HFCLK:
return ((p_reg->HFCLKSTAT & CLOCK_HFCLKSTAT_ALWAYSRUNNING_Msk)
>> CLOCK_HFCLKSTAT_ALWAYSRUNNING_Pos);
#if NRF_CLOCK_HAS_HFCLK192M
case NRF_CLOCK_DOMAIN_HFCLK192M:
return ((p_reg->HFCLK192MSTAT & CLOCK_HFCLK192MSTAT_ALWAYSRUNNING_Msk)
>> CLOCK_HFCLK192MSTAT_ALWAYSRUNNING_Pos);
#endif
#if NRF_CLOCK_HAS_HFCLKAUDIO
case NRF_CLOCK_DOMAIN_HFCLKAUDIO:
return ((p_reg->HFCLKAUDIOSTAT & CLOCK_HFCLKAUDIOSTAT_ALWAYSRUNNING_Msk)
>> CLOCK_HFCLKAUDIOSTAT_ALWAYSRUNNING_Pos);
#endif
default:
NRFX_ASSERT(0);
return false;
}
}
#endif // NRF_CLOCK_HAS_ALWAYSRUN
#if defined(DPPI_PRESENT)
NRF_STATIC_INLINE void nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg,
nrf_clock_task_t task,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

200
hal/nrf_dcnf.h Normal file
View file

@ -0,0 +1,200 @@
/*
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NRF_DCNF_H__
#define NRF_DCNF_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_dcnf_hal DCNF HAL
* @{
* @ingroup nrf_dcnf
* @brief Hardware access layer for managing the Domain Configuration (DCNF) module.
*/
/**
* @brief Function for getting the value of the CPU ID.
*
* CPU ID can be used to identify the specific CPU in the multi-core environment.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return CPU ID.
*/
NRF_STATIC_INLINE uint32_t nrf_dcnf_cpuid_get(NRF_DCNF_Type const * p_reg);
#if defined(DCNF_EXTPERI_PROTECT_SLAVE0_Msk)
/**
* @brief Function for configuring the control access to local peripheral memory regions.
* Intended for external master connected to specified AMLI master port.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] port_idx Index of the master port to configure.
* @param[in] mask Mask of the AHB slaves to be protected from being accessed
* by external AHB masters.
*/
NRF_STATIC_INLINE void nrf_dcnf_peripheral_access_set(NRF_DCNF_Type * p_reg,
uint8_t port_idx,
uint32_t mask);
/**
* @brief Function for getting the configuration of control access to local peripheral
* memory regions. Intended for external master connected to specified AMLI master port.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] port_idx Index of the master port to configure.
*
* @return Mask of the AHB slaves that are currently protected.
*/
NRF_STATIC_INLINE uint32_t nrf_dcnf_peripheral_access_get(NRF_DCNF_Type const * p_reg,
uint8_t port_idx);
#endif // defined(DCNF_EXTPERI_PROTECT_SLAVE0_Msk)
#if defined(DCNF_EXTRAM_PROTECT_SLAVE0_Msk)
/**
* @brief Function for configuring the control access to local RAM memory regions.
* Intended for external master connected to specified AMLI master port.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] port_idx Index of the master port to configure.
* @param[in] mask Mask of the AHB slaves to be protected from being accessed
* by external AHB masters.
*/
NRF_STATIC_INLINE void nrf_dcnf_ram_access_set(NRF_DCNF_Type * p_reg,
uint8_t port_idx,
uint32_t mask);
/**
* @brief Function for getting the configuration of control access to local RAM
* memory regions. Intended for external master connected to specified AMLI master port.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] port_idx Index of the master port to configure.
*
* @return Mask of the AHB slaves that are currently protected.
*/
NRF_STATIC_INLINE uint32_t nrf_dcnf_ram_access_get(NRF_DCNF_Type const * p_reg,
uint8_t port_idx);
#endif // defined(DCNF_EXTRAM_PROTECT_SLAVE0_Msk)
#if defined(DCNF_EXTCODE_PROTECT_SLAVE0_Msk)
/**
* @brief Function for configuring the control access to local code memory regions.
* Intended for external master connected to specified AMLI master port.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] port_idx Index of the master port to configure.
* @param[in] mask Mask of the AHB slaves to be protected from being accessed
* by external AHB masters.
*/
NRF_STATIC_INLINE void nrf_dcnf_code_access_set(NRF_DCNF_Type * p_reg,
uint8_t port_idx,
uint32_t mask);
/**
* @brief Function for getting the configuration of control access to local code
* memory regions. Intended for external master connected to specified AMLI master port.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] port_idx Index of the master port to configure.
*
* @return Mask of the AHB slaves that are currently protected.
*/
NRF_STATIC_INLINE uint32_t nrf_dcnf_code_access_get(NRF_DCNF_Type const * p_reg,
uint8_t port_idx);
#endif // defined(DCNF_EXTCODE_PROTECT_SLAVE0_Msk)
#ifndef NRF_DECLARE_ONLY
NRF_STATIC_INLINE uint32_t nrf_dcnf_cpuid_get(NRF_DCNF_Type const * p_reg)
{
return p_reg->CPUID;
}
#if defined(DCNF_EXTPERI_PROTECT_SLAVE0_Msk)
NRF_STATIC_INLINE void nrf_dcnf_peripheral_access_set(NRF_DCNF_Type * p_reg,
uint8_t port_idx,
uint32_t mask)
{
p_reg->EXTPERI[port_idx].PROTECT = mask;
}
NRF_STATIC_INLINE uint32_t nrf_dcnf_peripheral_access_get(NRF_DCNF_Type const * p_reg,
uint8_t port_idx)
{
return p_reg->EXTPERI[port_idx].PROTECT;
}
#endif
#if defined(DCNF_EXTRAM_PROTECT_SLAVE0_Msk)
NRF_STATIC_INLINE void nrf_dcnf_ram_access_set(NRF_DCNF_Type * p_reg,
uint8_t port_idx,
uint32_t mask)
{
p_reg->EXTRAM[port_idx].PROTECT = mask;
}
NRF_STATIC_INLINE uint32_t nrf_dcnf_ram_access_get(NRF_DCNF_Type const * p_reg,
uint8_t port_idx)
{
return p_reg->EXTRAM[port_idx].PROTECT;
}
#endif
#if defined(DCNF_EXTCODE_PROTECT_SLAVE0_Msk)
NRF_STATIC_INLINE void nrf_dcnf_code_access_set(NRF_DCNF_Type * p_reg,
uint8_t port_idx,
uint32_t mask)
{
p_reg->EXTCODE[port_idx].PROTECT = mask;
}
NRF_STATIC_INLINE uint32_t nrf_dcnf_code_access_get(NRF_DCNF_Type const * p_reg,
uint8_t port_idx)
{
return p_reg->EXTCODE[port_idx].PROTECT;
}
#endif
#endif // NRF_DECLARE_ONLY
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_DCNF_H__

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2012 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
* Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -59,6 +59,11 @@ extern "C" {
* @brief Hardware access layer for managing the GPIO peripheral.
*/
#if defined(GPIO_LATCH_PIN0_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Symbol indicating whether the functionality of latching GPIO state change is present. */
#define NRF_GPIO_LATCH_PRESENT
#endif
/** @brief Macro for mapping port and pin numbers to values understandable for nrf_gpio functions. */
#define NRF_GPIO_PIN_MAP(port, pin) (((port) << 5) | ((pin) & 0x1F))
@ -91,14 +96,35 @@ typedef enum
/** @brief Enumerator used for selecting output drive mode. */
typedef enum
{
NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1'.
NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High-drive '0', standard '1'.
NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high-drive '1'.
NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high-drive '1'.
NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1'.
NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high-drive '1'.
NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0', disconnect '1'.
NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High-drive '0', disconnect '1'.
NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< Standard '0', standard '1'.
NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< High drive '0', standard '1'.
NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< Standard '0', high drive '1'.
NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< High drive '0', high drive '1'.
NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< Disconnect '0' standard '1'.
NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< Disconnect '0', high drive '1'.
NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< Standard '0', disconnect '1'.
NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< High drive '0', disconnect '1'.
#if defined(GPIO_PIN_CNF_DRIVE_E0S1) || defined(__NRFX_DOXYGEN__)
NRF_GPIO_PIN_E0S1 = GPIO_PIN_CNF_DRIVE_E0S1, ///< Extra high drive '0', standard '1'.
#endif
#if defined(GPIO_PIN_CNF_DRIVE_S0E1) || defined(__NRFX_DOXYGEN__)
NRF_GPIO_PIN_S0E1 = GPIO_PIN_CNF_DRIVE_S0E1, ///< Standard '0', extra high drive '1'.
#endif
#if defined(GPIO_PIN_CNF_DRIVE_E0E1) || defined(__NRFX_DOXYGEN__)
NRF_GPIO_PIN_E0E1 = GPIO_PIN_CNF_DRIVE_E0E1, ///< Extra high drive '0', extra high drive '1'.
#endif
#if defined(GPIO_PIN_CNF_DRIVE_E0H1) || defined(__NRFX_DOXYGEN__)
NRF_GPIO_PIN_E0H1 = GPIO_PIN_CNF_DRIVE_E0H1, ///< Extra high drive '0', high drive '1'.
#endif
#if defined(GPIO_PIN_CNF_DRIVE_H0E1) || defined(__NRFX_DOXYGEN__)
NRF_GPIO_PIN_H0E1 = GPIO_PIN_CNF_DRIVE_H0E1, ///< High drive '0', extra high drive '1'.
#endif
#if defined(GPIO_PIN_CNF_DRIVE_D0E1) || defined(__NRFX_DOXYGEN__)
NRF_GPIO_PIN_D0E1 = GPIO_PIN_CNF_DRIVE_D0E1, ///< Disconnect '0', extra high drive '1'.
#endif
#if defined(GPIO_PIN_CNF_DRIVE_E0D1) || defined(__NRFX_DOXYGEN__)
NRF_GPIO_PIN_E0D1 = GPIO_PIN_CNF_DRIVE_E0D1, ///< Extra high drive '0', disconnect '1'.
#endif
} nrf_gpio_pin_drive_t;
/** @brief Enumerator used for selecting the pin to sense high or low level on the pin input. */
@ -421,7 +447,7 @@ NRF_STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port,
uint32_t length,
uint32_t * p_masks);
#if defined(GPIO_DETECTMODE_DETECTMODE_LDETECT) || defined(__NRF_DOXYGEN__)
#if defined(NRF_GPIO_LATCH_PRESENT)
/**
* @brief Function for reading latch state of multiple consecutive ports.
*
@ -433,6 +459,17 @@ NRF_STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port,
uint32_t length,
uint32_t * p_masks);
/**
* @brief Function for reading and immediate clearing latch state of multiple consecutive ports.
*
* @param start_port Index of the first port to read and clear.
* @param length Number of ports to read and clear.
* @param p_masks Pointer to output array where latch states will be stored.
*/
NRF_STATIC_INLINE void nrf_gpio_latches_read_and_clear(uint32_t start_port,
uint32_t length,
uint32_t * p_masks);
/**
* @brief Function for reading latch state of single pin.
*
@ -448,7 +485,7 @@ NRF_STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number);
* @param pin_number Pin number.
*/
NRF_STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number);
#endif
#endif // defined(NRF_GPIO_LATCH_PRESENT)
#if defined(GPIO_PIN_CNF_MCUSEL_Msk) || defined(__NRFX_DOXYGEN__)
/**
@ -789,7 +826,7 @@ NRF_STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port,
}
#ifdef GPIO_DETECTMODE_DETECTMODE_LDETECT
#if defined(NRF_GPIO_LATCH_PRESENT)
NRF_STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port,
uint32_t length,
uint32_t * p_masks)
@ -804,6 +841,23 @@ NRF_STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port,
}
}
NRF_STATIC_INLINE void nrf_gpio_latches_read_and_clear(uint32_t start_port,
uint32_t length,
uint32_t * p_masks)
{
NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST;
uint32_t i;
for (i = start_port; i < (start_port + length); i++)
{
*p_masks = gpio_regs[i]->LATCH;
// The LATCH register is cleared by writing a '1' to the bit that shall be cleared.
gpio_regs[i]->LATCH = *p_masks;
p_masks++;
}
}
NRF_STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number)
{
@ -819,7 +873,7 @@ NRF_STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number)
reg->LATCH = (1 << pin_number);
}
#endif
#endif // defined(NRF_GPIO_LATCH_PRESENT)
#if defined(GPIO_PIN_CNF_MCUSEL_Msk)
NRF_STATIC_INLINE void nrf_gpio_pin_mcu_select(uint32_t pin_number, nrf_gpio_pin_mcusel_t mcu)

Some files were not shown because too many files have changed in this diff Show more