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 # Changelog
All notable changes to this project are documented in this file. 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 ## [2.0.0] - 2019-11-06
### Added ### Added
- Added support for nRF5340. - 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. All rights reserved.
Redistribution and use in source and binary forms, with or without 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_clock |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |
@ref nrf_comp |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross | @ref nrf_comp |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross |
@ref nrf_systick |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick | @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_dppi |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagGreenTick |@tagGreenTick |
@ref nrf_ecb |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross | @ref nrf_ecb |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross |
@ref nrf_egu |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick | @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_twis |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |
@ref nrf_uart |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross |@tagRedCross | @ref nrf_uart |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagRedCross |@tagRedCross |
@ref nrf_uarte |@tagRedCross |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick | @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_vmc |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagRedCross |@tagGreenTick |@tagGreenTick |
@ref nrf_wdt |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@tagGreenTick |@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 This file, similarly to the integration files mentioned above, can be placed
in any suitable location within the host environment. in any suitable location within the host environment.
The <a href="../../templates/">templates</a> subfolder contains templates of The <a href="../../templates/">templates</a> subfolder contains templates of
configuration files for all currently supported Nordic SoCs placed in respective configuration files for all currently supported Nordic SoCs. These files are
subfolders. 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 Refer to the "driver configuration" section in the API reference for a given
driver for more information regarding configuration options available for it. driver for more information regarding configuration options available for it.

View file

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

View file

@ -40,7 +40,7 @@ PROJECT_NAME = "nrfx"
### EDIT THIS ### ### EDIT THIS ###
PROJECT_NUMBER = "2.0" PROJECT_NUMBER = "2.1"
# Using the PROJECT_BRIEF tag one can provide an optional one line description # 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 # 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. # 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" \ ALIASES = "tagGreenTick=@htmlonly<CENTER><font color= green>✔</font></CENTER>@endhtmlonly" \
"tagRedCross=@htmlonly<CENTER><font color= red>✖</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)"
# This tag can be used to specify a number of word-keyword mappings (TCL only). # 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" # 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_systick Cortex-M Systick
@defgroup nrf_dcnf DCNF
@defgroup nrf_dppi DPPI @defgroup nrf_dppi DPPI
@defgroup nrf_ecb ECB @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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -50,10 +50,12 @@ extern "C" {
/** @brief Clock events. */ /** @brief Clock events. */
typedef enum typedef enum
{ {
NRFX_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started. NRFX_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started.
NRFX_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started. NRFX_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started.
NRFX_CLOCK_EVT_CTTO, ///< Calibration timeout. NRFX_CLOCK_EVT_CTTO, ///< Calibration timeout.
NRFX_CLOCK_EVT_CAL_DONE ///< Calibration has been done. 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; } nrfx_clock_evt_type_t;
/** /**
@ -85,34 +87,137 @@ void nrfx_clock_disable(void);
/** @brief Function for uninitializing the clock module. */ /** @brief Function for uninitializing the clock module. */
void nrfx_clock_uninit(void); 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. * @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 true The LFCLK is running.
* @retval false The LFCLK is not running. * @retval false The LFCLK is not running.
*/ */
NRFX_STATIC_INLINE bool nrfx_clock_lfclk_is_running(void); 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. * @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 true The HFCLK is running (XTAL source).
* @retval false The HFCLK is not running. * @retval false The HFCLK is not running.
*/ */
NRFX_STATIC_INLINE bool nrfx_clock_hfclk_is_running(void); 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. * @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); NRFX_STATIC_INLINE uint32_t nrfx_clock_ppi_event_addr(nrf_clock_event_t event);
#ifndef NRFX_DECLARE_ONLY #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) NRFX_STATIC_INLINE uint32_t nrfx_clock_ppi_task_addr(nrf_clock_task_t task)
{ {
return nrf_clock_task_address_get(NRF_CLOCK, 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); 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) 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) 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 #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -69,13 +69,17 @@ typedef struct
* if this signal is not needed. */ * if this signal is not needed. */
uint8_t irq_priority; ///< Interrupt priority. uint8_t irq_priority; ///< Interrupt priority.
nrf_i2s_mode_t mode; ///< Mode of operation. nrf_i2s_mode_t mode; ///< Mode of operation.
nrf_i2s_format_t format; ///< Frame format. nrf_i2s_format_t format; ///< Frame format.
nrf_i2s_align_t alignment; ///< Alignment of sample within a frame. nrf_i2s_align_t alignment; ///< Alignment of sample within a frame.
nrf_i2s_swidth_t sample_width; ///< Sample width. nrf_i2s_swidth_t sample_width; ///< Sample width.
nrf_i2s_channels_t channels; ///< Enabled channels. nrf_i2s_channels_t channels; ///< Enabled channels.
nrf_i2s_mck_t mck_setup; ///< Master clock setup. nrf_i2s_mck_t mck_setup; ///< Master clock setup.
nrf_i2s_ratio_t ratio; ///< MCK/LRCK ratio. 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; } nrfx_i2s_config_t;
/** @brief I2S driver buffers structure. */ /** @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. uint32_t const * p_tx_buffer; ///< Pointer to the buffer with data to be sent.
} nrfx_i2s_buffers_t; } 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. * @brief I2S driver default configuration.
* *
@ -118,15 +130,20 @@ typedef struct
.channels = NRF_I2S_CHANNELS_LEFT, \ .channels = NRF_I2S_CHANNELS_LEFT, \
.mck_setup = NRF_I2S_MCK_32MDIV8, \ .mck_setup = NRF_I2S_MCK_32MDIV8, \
.ratio = NRF_I2S_RATIO_32X, \ .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 /**< 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 * part of the transfer. A call to @ref nrfx_i2s_next_buffers_set must
* be done before the currently used buffers are completely processed * be done before the currently used buffers are completely processed
* (that is, the time remaining for supplying the next buffers depends on * (that is, the time remaining for supplying the next buffers depends on
* the used size of the buffers). */ * 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. * @brief I2S driver data handler type.
* *
@ -155,14 +172,22 @@ typedef struct
* Both pointers in this structure are NULL when the * Both pointers in this structure are NULL when the
* handler is called for the first time after a transfer * handler is called for the first time after a transfer
* is started, because no data has been transferred yet * 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 * specify what has been sent (TX) and what has been
* received (RX) in the part of transfer that has just * received (RX) in the part of the transfer that has
* been completed (provided that a given direction is * just been completed (provided that a given direction
* enabled, see @ref nrfx_i2s_start). * 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. * @param[in] status Bit field describing the current status of the transfer.
* It can be 0 or a combination of the following flags: * It can be 0 or a combination of the following flags:
* - @ref NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED * - @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, typedef void (* nrfx_i2s_data_handler_t)(nrfx_i2s_buffers_t const * p_released,
uint32_t status); 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 * 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. * right-aligned 24-bit sample sign-extended to a 32-bit value.
* For a detailed memory mapping for different supported configurations, * 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 * @note Peripherals using EasyDMA (including I2S) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met, * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -70,7 +70,7 @@ typedef struct
* *
* @param[in] _input Comparator input pin. * @param[in] _input Comparator input pin.
*/ */
#ifdef NRF52_SERIES #if defined(LPCOMP_FEATURE_HYST_PRESENT)
#define NRFX_LPCOMP_DEFAULT_CONFIG(_input) \ #define NRFX_LPCOMP_DEFAULT_CONFIG(_input) \
{ \ { \
.hal = { NRF_LPCOMP_REF_SUPPLY_4_8, \ .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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -67,16 +67,39 @@ typedef struct
/** @brief PDM interface driver configuration structure. */ /** @brief PDM interface driver configuration structure. */
typedef struct typedef struct
{ {
nrf_pdm_mode_t mode; ///< Interface operation mode. nrf_pdm_mode_t mode; ///< Interface operation mode.
nrf_pdm_edge_t edge; ///< Sampling mode. nrf_pdm_edge_t edge; ///< Sampling mode.
uint8_t pin_clk; ///< CLK pin. uint8_t pin_clk; ///< CLK pin.
uint8_t pin_din; ///< DIN pin. uint8_t pin_din; ///< DIN pin.
nrf_pdm_freq_t clock_freq; ///< Clock frequency. nrf_pdm_freq_t clock_freq; ///< Clock frequency.
nrf_pdm_gain_t gain_l; ///< Left channel gain. nrf_pdm_gain_t gain_l; ///< Left channel gain.
nrf_pdm_gain_t gain_r; ///< Right channel gain. nrf_pdm_gain_t gain_r; ///< Right channel gain.
uint8_t interrupt_priority; ///< Interrupt priority. 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; } 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. * @brief PDM driver default configuration.
* *
@ -98,7 +121,9 @@ typedef struct
.clock_freq = NRF_PDM_FREQ_1032K, \ .clock_freq = NRF_PDM_FREQ_1032K, \
.gain_l = NRF_PDM_GAIN_DEFAULT, \ .gain_l = NRF_PDM_GAIN_DEFAULT, \
.gain_r = 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 #ifndef NRFX_DECLARE_ONLY
NRFX_STATIC_INLINE uint32_t nrfx_pdm_task_address_get(nrf_pdm_task_t task) 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) 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 #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -35,6 +35,7 @@
#include <nrfx.h> #include <nrfx.h>
#include <hal/nrf_power.h> #include <hal/nrf_power.h>
#include <nrfx_power_clock.h> #include <nrfx_power_clock.h>
#include "nrfx_power_compat.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -47,6 +48,29 @@ extern "C" {
* @brief POWER peripheral driver. * @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 * @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_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_READY /**< From the power viewpoint, USB is ready for working. */
}nrfx_power_usb_state_t; }nrfx_power_usb_state_t;
#endif /* NRF_POWER_HAS_USBREG */ #endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/** /**
* @name Callback types * @name Callback types
@ -145,7 +169,7 @@ typedef struct
*/ */
bool dcdcen:1; bool dcdcen:1;
#if NRF_POWER_HAS_VDDH || defined(__NRFX_DOXYGEN__) #if NRFX_POWER_SUPPORTS_DCDCEN_VDDH
/** /**
* @brief Enable HV DCDC regulator. * @brief Enable HV DCDC regulator.
* *
@ -166,10 +190,10 @@ typedef struct
typedef struct typedef struct
{ {
nrfx_power_pofwarn_event_handler_t handler; //!< Event handler. 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 nrf_power_pof_thr_t thr; //!< Threshold for power failure detection
#endif #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. nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on the VDDH pin.
#endif #endif
}nrfx_power_pofwarn_config_t; }nrfx_power_pofwarn_config_t;
@ -198,7 +222,7 @@ typedef struct
{ {
nrfx_power_usb_event_handler_t handler; //!< Event processing. nrfx_power_usb_event_handler_t handler; //!< Event processing.
}nrfx_power_usbevt_config_t; }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. * @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. * @return Handler of the USB power.
*/ */
nrfx_power_usb_event_handler_t nrfx_power_usb_handler_get(void); 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. * @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); 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. * @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. * Clears the settings of the power failure comparator.
*/ */
void nrfx_power_pof_uninit(void); 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__) #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); 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 #ifndef NRFX_DECLARE_ONLY
#if NRF_POWER_HAS_USBREG #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; return NRFX_POWER_USB_STATE_READY;
} }
#endif /* NRF_POWER_HAS_USBREG */ #endif // NRF_POWER_HAS_USBREG
#endif /* NRFX_DECLARE_ONLY */ #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. 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_load_t load_mode; ///< Mode of loading sequence data from RAM.
nrf_pwm_dec_step_t step_mode; ///< Mode of advancing the active sequence. 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; } nrfx_pwm_config_t;
/** /**
@ -117,19 +121,20 @@ typedef struct
* @param[in] _out_2 PWM output 2 pin. * @param[in] _out_2 PWM output 2 pin.
* @param[in] _out_3 PWM output 3 pin. * @param[in] _out_3 PWM output 3 pin.
*/ */
#define NRFX_PWM_DEFAULT_CONFIG(_out_0, _out_1, _out_2, _out_3) \ #define NRFX_PWM_DEFAULT_CONFIG(_out_0, _out_1, _out_2, _out_3) \
{ \ { \
.output_pins = { _out_0, \ .output_pins = { _out_0, \
_out_1, \ _out_1, \
_out_2, \ _out_2, \
_out_3 \ _out_3 \
}, \ }, \
.irq_priority = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY, \ .irq_priority = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY, \
.base_clock = NRF_PWM_CLK_1MHz, \ .base_clock = NRF_PWM_CLK_1MHz, \
.count_mode = NRF_PWM_MODE_UP, \ .count_mode = NRF_PWM_MODE_UP, \
.top_value = 1000, \ .top_value = 1000, \
.load_mode = NRF_PWM_LOAD_COMMON, \ .load_mode = NRF_PWM_LOAD_COMMON, \
.step_mode = NRF_PWM_STEP_AUTO, \ .step_mode = NRF_PWM_STEP_AUTO, \
.skip_gpio_cfg = false \
} }
/** @brief PWM flags providing additional playback options. */ /** @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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -66,7 +66,7 @@ typedef struct
* - PP opcode for writing * - PP opcode for writing
* - 24 bit addressing mode * - 24 bit addressing mode
* - Deep Power-down disabled * - 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 * - 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') * - 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, \ .sck_delay = 0x05, \
.dpmen = false, \ .dpmen = false, \
.spi_mode = NRF_QSPI_MODE_0, \ .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, \ .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, size_t transfer_length,
bool finalize); 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -116,6 +116,7 @@ typedef struct
* - clock frequency 4 MHz * - clock frequency 4 MHz
* - mode 0 enabled (SCK active high, sample on leading edge of clock) * - mode 0 enabled (SCK active high, sample on leading edge of clock)
* - MSB shifted out first * - MSB shifted out first
* - MISO pull-up disabled
* *
* @param[in] _pin_sck SCK pin. * @param[in] _pin_sck SCK pin.
* @param[in] _pin_mosi MOSI pin. * @param[in] _pin_mosi MOSI pin.
@ -133,6 +134,7 @@ typedef struct
.frequency = NRF_SPI_FREQ_4M, \ .frequency = NRF_SPI_FREQ_4M, \
.mode = NRF_SPI_MODE_0, \ .mode = NRF_SPI_MODE_0, \
.bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST, \ .bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST, \
.miso_pull = NRF_GPIO_PIN_NOPULL, \
} }
/** @brief Single transfer descriptor structure. */ /** @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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -67,6 +67,9 @@ enum {
#endif #endif
#if NRFX_CHECK(NRFX_SPIM3_ENABLED) #if NRFX_CHECK(NRFX_SPIM3_ENABLED)
NRFX_SPIM3_INST_IDX, NRFX_SPIM3_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_SPIM4_ENABLED)
NRFX_SPIM4_INST_IDX,
#endif #endif
NRFX_SPIM_ENABLED_COUNT 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_1_irq_handler(void);
void nrfx_spim_2_irq_handler(void); void nrfx_spim_2_irq_handler(void);
void nrfx_spim_3_irq_handler(void); void nrfx_spim_3_irq_handler(void);
void nrfx_spim_4_irq_handler(void);
#ifdef __cplusplus #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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_DONE, ///< Transfer completed event.
NRFX_TWI_EVT_ADDRESS_NACK, ///< Error event: NACK received after sending the address. 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_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; } nrfx_twi_evt_type_t;
/** @brief TWI master driver transfer types. */ /** @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_SUCCESS The procedure is successful.
* @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer. * @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_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_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_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 * @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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. */ /** @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. */ /** @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. */ /** @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. */ /** @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. */ /** @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. */ /** @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. */ /** @brief TWI master driver event types. */
typedef enum 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 * 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. * when TWIM is not active.
* - @ref NRFX_TWIM_FLAG_TX_NO_STOP - No stop condition after the TX transfer. * - @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 * @note
* Some flag combinations are invalid: * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -39,10 +39,6 @@
extern "C" { extern "C" {
#endif #endif
#ifndef NRF_WDT0
#define NRF_WDT0 NRF_WDT
#endif
/** /**
* @defgroup nrfx_wdt WDT driver * @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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -34,6 +34,7 @@
#if NRFX_CHECK(NRFX_CLOCK_ENABLED) #if NRFX_CHECK(NRFX_CLOCK_ENABLED)
#include <nrfx_clock.h> #include <nrfx_clock.h>
#include <nrf_erratas.h>
#define NRFX_LOG_MODULE CLOCK #define NRFX_LOG_MODULE CLOCK
#include <nrfx_log.h> #include <nrfx_log.h>
@ -42,13 +43,6 @@
extern bool nrfx_power_irq_enabled; extern bool nrfx_power_irq_enabled;
#endif #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 NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
#if (NRF_CLOCK_HAS_CALIBRATION == 0) #if (NRF_CLOCK_HAS_CALIBRATION == 0)
#error "Calibration is not available in the SoC that is used." #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_ASSERT(m_clock_cb.module_initialized);
nrfx_power_clock_irq_init(); nrfx_power_clock_irq_init();
nrf_clock_lf_src_set(NRF_CLOCK, (nrf_clock_lfclk_t)NRFX_CLOCK_CONFIG_LF_SRC); 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) #if NRFX_CHECK(NRFX_POWER_ENABLED)
nrfx_clock_irq_enabled = true; nrfx_clock_irq_enabled = true;
#endif #endif
@ -202,8 +201,10 @@ void nrfx_clock_disable(void)
CLOCK_INTENSET_LFCLKSTARTED_Msk | CLOCK_INTENSET_LFCLKSTARTED_Msk |
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED) #if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
CLOCK_INTENSET_DONE_Msk | CLOCK_INTENSET_DONE_Msk |
#if NRF_HAS_CALIBRATION_TIMER
CLOCK_INTENSET_CTTO_Msk | CLOCK_INTENSET_CTTO_Msk |
#endif #endif
#endif // NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED)
0); 0);
#if NRFX_CHECK(NRFX_POWER_ENABLED) #if NRFX_CHECK(NRFX_POWER_ENABLED)
nrfx_clock_irq_enabled = false; nrfx_clock_irq_enabled = false;
@ -217,49 +218,97 @@ void nrfx_clock_uninit(void)
{ {
return; return;
} }
nrfx_clock_lfclk_stop(); nrfx_clock_stop(NRF_CLOCK_DOMAIN_LFCLK);
nrfx_clock_hfclk_stop(); 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; m_clock_cb.module_initialized = false;
NRFX_LOG_INFO("Uninitialized."); 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); NRFX_ASSERT(m_clock_cb.module_initialized);
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_LFCLKSTARTED); switch (domain)
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_LF_STARTED_MASK); {
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) #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_132)
nrfx_clock_anomaly_132(); nrfx_clock_anomaly_132();
#endif #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); NRFX_ASSERT(m_clock_cb.module_initialized);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP); switch (domain)
while (nrf_clock_lf_is_running(NRF_CLOCK)) {
{} case NRF_CLOCK_DOMAIN_LFCLK:
} nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP);
break;
void nrfx_clock_hfclk_start(void) case NRF_CLOCK_DOMAIN_HFCLK:
{ nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP);
NRFX_ASSERT(m_clock_cb.module_initialized); break;
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED); #if NRF_CLOCK_HAS_HFCLK192M
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_HF_STARTED_MASK); case NRF_CLOCK_DOMAIN_HFCLK192M:
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLK192MSTOP);
} break;
#endif
void nrfx_clock_hfclk_stop(void) #if NRF_CLOCK_HAS_HFCLKAUDIO
{ case NRF_CLOCK_DOMAIN_HFCLKAUDIO:
NRFX_ASSERT(m_clock_cb.module_initialized); nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKAUDIOSTOP);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); break;
while (nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY)) #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) #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 #endif
} }
@ -268,12 +317,18 @@ nrfx_err_t nrfx_clock_calibration_start(void)
nrfx_err_t err_code = NRFX_SUCCESS; nrfx_err_t err_code = NRFX_SUCCESS;
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED) #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; 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; 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) 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_cal_timer_timeout_set(NRF_CLOCK, interval);
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_CTTO); nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_CTTO);
nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_CTTO_MASK); 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) 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_int_disable(NRF_CLOCK, NRF_CLOCK_INT_CTTO_MASK);
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_CTSTOP); nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_CTSTOP);
#endif #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) void nrfx_clock_irq_handler(void)
{ {
if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED)) if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED))
{ {
nrf_clock_event_clear(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); nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_HF_STARTED_MASK);
#if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_201) #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)) if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_LFCLKSTARTED))
{ {
nrf_clock_event_clear(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); nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_LF_STARTED_MASK);
m_clock_cb.event_handler(NRFX_CLOCK_EVT_LFCLK_STARTED); m_clock_cb.event_handler(NRFX_CLOCK_EVT_LFCLK_STARTED);
} }
#if NRFX_CHECK(NRFX_CLOCK_CONFIG_LF_CAL_ENABLED) #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)) if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_CTTO))
{ {
nrf_clock_event_clear(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); nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_CTTO_MASK);
m_clock_cb.event_handler(NRFX_CLOCK_EVT_CTTO); 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)) 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; *(volatile uint32_t *)0x40000C34 = 0x00000000;
#endif #endif
nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_DONE); 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); nrf_clock_int_disable(NRF_CLOCK, NRF_CLOCK_INT_DONE_MASK);
m_clock_cb.cal_state = CAL_STATE_IDLE; m_clock_cb.cal_state = CAL_STATE_IDLE;
m_clock_cb.event_handler(NRFX_CLOCK_EVT_CAL_DONE); 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) #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -44,11 +44,11 @@
#define PIN_NOT_USED (-1) #define PIN_NOT_USED (-1)
#define PIN_USED (-2) #define PIN_USED (-2)
#define NO_CHANNELS (-1) #define NO_CHANNELS (-1)
#define SENSE_FIELD_POS (6) #define POLARITY_FIELD_POS (6)
#define SENSE_FIELD_MASK (0xC0) #define POLARITY_FIELD_MASK (0xC0)
/* Check if every pin can be encoded on provided number of bits. */ /* 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" */ /*lint -save -e571*/ /* Suppress "Warning 571: Suspicious cast" */
typedef struct typedef struct
@ -145,6 +145,17 @@ static nrfx_gpiote_evt_handler_t channel_handler_get(uint32_t channel)
return m_cb.handlers[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) 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 else
{ {
m_cb.port_handlers_pins[channel - GPIOTE_CH_NUM] |= (p_config->sense) << m_cb.port_handlers_pins[channel - GPIOTE_CH_NUM] |= (p_config->sense) <<
SENSE_FIELD_POS; POLARITY_FIELD_POS;
} }
} }
else 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)); NRFX_ASSERT(pin_in_use_by_gpiote(pin));
if (pin_in_use_by_port(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 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; nrf_gpio_pin_sense_t sense;
if (polarity == NRF_GPIOTE_POLARITY_TOGGLE) 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); 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) 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); nrf_gpiote_event_clear(NRF_GPIOTE, NRF_GPIOTE_EVENT_PORT);
status |= (uint32_t)NRF_GPIOTE_INT_PORT_MASK; 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); nrf_gpio_ports_read(0, GPIO_COUNT, input);
#endif
} }
/* Process pin events. */ /* 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) if (status & (uint32_t)NRF_GPIOTE_INT_PORT_MASK)
{ {
/* Process port event. */ port_event_handle(input);
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);
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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)); NRFX_LOG_ERROR_STRING_GET(err_code));
return 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); configure_pins(p_config);
m_cb.handler = handler; m_cb.handler = handler;
@ -380,12 +384,18 @@ void nrfx_i2s_irq_handler(void)
nrf_i2s_disable(NRF_I2S); nrf_i2s_disable(NRF_I2S);
// When stopped, release all buffers, including these scheduled for // When stopped, release all buffers, including these scheduled for
// the next transfer. // the next part of the transfer, and signal that the transfer has
m_cb.handler(&m_cb.current_buffers, 0); // finished.
m_cb.handler(&m_cb.next_buffers, 0);
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; m_cb.state = NRFX_DRV_STATE_INITIALIZED;
NRFX_LOG_INFO("Stopped."); NRFX_LOG_INFO("Stopped.");
m_cb.handler(&m_cb.next_buffers, NRFX_I2S_STATUS_TRANSFER_STOPPED);
} }
else else
{ {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, Nordic Semiconductor ASA * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,6 +43,13 @@
*/ */
#define NVMC_BYTES_IN_WORD 4 #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. * 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_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)) if (!is_page_aligned_check(addr))
{ {
@ -253,7 +260,7 @@ void nrfx_nvmc_all_erase(void)
#if defined(NRF_NVMC_PARTIAL_ERASE_PRESENT) #if defined(NRF_NVMC_PARTIAL_ERASE_PRESENT)
nrfx_err_t nrfx_nvmc_page_partial_erase_init(uint32_t addr, uint32_t duration_ms) 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)) 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) 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; uint8_t val_on_addr = *(uint8_t const *)addr;
return (val_to_check & val_on_addr) == val_to_check; 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) 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)); NRFX_ASSERT(nrfx_is_word_aligned((void const *)addr));
uint32_t val_on_addr = *(uint32_t 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) 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)); NRFX_ASSERT(nrfx_is_word_aligned((void const *)addr));
nvmc_write_mode_set(); 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) 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(); 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) 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((void const *)addr));
NRFX_ASSERT(nrfx_is_word_aligned(src)); 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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) 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)); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_PDM_EVENT_STARTED));
uint8_t finished_buffer = m_cb.active_buffer; 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; 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)); 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; m_cb.op_state = NRFX_PDM_STATE_IDLE;
// Release the buffers. // 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.event_handler = event_handler;
m_cb.op_state = NRFX_PDM_STATE_IDLE; m_cb.op_state = NRFX_PDM_STATE_IDLE;
nrf_pdm_clock_set(NRF_PDM, p_config->clock_freq); #if NRF_PDM_HAS_RATIO_CONFIG
nrf_pdm_mode_set(NRF_PDM, p_config->mode, p_config->edge); nrf_pdm_ratio_set(NRF_PDM0, p_config->ratio);
nrf_pdm_gain_set(NRF_PDM, p_config->gain_l, p_config->gain_r); #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_cfg_output(p_config->pin_clk);
nrf_gpio_pin_clear(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_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_PDM0, NRF_PDM_EVENT_STARTED);
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_END); nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_END);
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_STOPPED); nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_STOPPED);
nrf_pdm_int_enable(NRF_PDM, NRF_PDM_INT_STARTED | NRF_PDM_INT_STOPPED); nrf_pdm_int_enable(NRF_PDM0, NRF_PDM_INT_STARTED | NRF_PDM_INT_STOPPED);
NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_PDM), p_config->interrupt_priority); NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_PDM0), p_config->interrupt_priority);
NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_PDM)); NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_PDM0));
m_cb.drv_state = NRFX_DRV_STATE_INITIALIZED; m_cb.drv_state = NRFX_DRV_STATE_INITIALIZED;
err_code = NRFX_SUCCESS; err_code = NRFX_SUCCESS;
@ -230,8 +237,8 @@ void nrfx_pdm_uninit(void)
{ {
return; return;
} }
nrf_pdm_disable(NRF_PDM); nrf_pdm_disable(NRF_PDM0);
nrf_pdm_psel_disconnect(NRF_PDM); nrf_pdm_psel_disconnect(NRF_PDM0);
m_cb.drv_state = NRFX_DRV_STATE_UNINITIALIZED; m_cb.drv_state = NRFX_DRV_STATE_UNINITIALIZED;
NRFX_LOG_INFO("Uninitialized."); NRFX_LOG_INFO("Uninitialized.");
} }
@ -239,15 +246,15 @@ void nrfx_pdm_uninit(void)
static void pdm_start() static void pdm_start()
{ {
m_cb.drv_state = NRFX_DRV_STATE_POWERED_ON; m_cb.drv_state = NRFX_DRV_STATE_POWERED_ON;
nrf_pdm_enable(NRF_PDM); nrf_pdm_enable(NRF_PDM0);
nrf_pdm_event_clear(NRF_PDM, NRF_PDM_EVENT_STARTED); nrf_pdm_event_clear(NRF_PDM0, NRF_PDM_EVENT_STARTED);
nrf_pdm_task_trigger(NRF_PDM, NRF_PDM_TASK_START); nrf_pdm_task_trigger(NRF_PDM0, NRF_PDM_TASK_START);
} }
static void pdm_buf_request() static void pdm_buf_request()
{ {
m_cb.irq_buff_request = 1; 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) 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; nrfx_err_t err_code = NRFX_SUCCESS;
// Enter the PDM critical section. // 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; uint8_t next_buffer = (~m_cb.active_buffer) & 0x01;
if (m_cb.op_state == NRFX_PDM_STATE_STARTING) 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_address[next_buffer] = buffer;
m_cb.buff_length[next_buffer] = buffer_length; 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) 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; return err_code;
} }
@ -339,7 +346,7 @@ nrfx_err_t nrfx_pdm_stop(void)
if (m_cb.op_state == NRFX_PDM_STATE_IDLE || if (m_cb.op_state == NRFX_PDM_STATE_IDLE ||
m_cb.op_state == NRFX_PDM_STATE_STARTING) 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; m_cb.op_state = NRFX_PDM_STATE_IDLE;
err_code = NRFX_SUCCESS; err_code = NRFX_SUCCESS;
NRFX_LOG_INFO("Function: %s, error code: %s.", 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.drv_state = NRFX_DRV_STATE_INITIALIZED;
m_cb.op_state = NRFX_PDM_STATE_STOPPING; 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; err_code = NRFX_SUCCESS;
NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
return 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -34,9 +34,6 @@
#if NRFX_CHECK(NRFX_POWER_ENABLED) #if NRFX_CHECK(NRFX_POWER_ENABLED)
#include <nrfx_power.h> #include <nrfx_power.h>
#if defined(REGULATORS_PRESENT)
#include <hal/nrf_regulators.h>
#endif
#if NRFX_CHECK(NRFX_CLOCK_ENABLED) #if NRFX_CHECK(NRFX_CLOCK_ENABLED)
extern bool nrfx_clock_irq_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 #if NRF_POWER_HAS_DCDCEN_VDDH
nrf_power_dcdcen_vddh_set(NRF_POWER, p_config->dcdcenhv); 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 #endif
#if NRF_POWER_HAS_DCDCEN #if NRF_POWER_HAS_DCDCEN
nrf_power_dcdcen_set(NRF_POWER, p_config->dcdcen); nrf_power_dcdcen_set(NRF_POWER, p_config->dcdcen);
#elif defined(REGULATORS_PRESENT) #elif defined(REGULATORS_PRESENT)
@ -135,19 +135,19 @@ void nrfx_power_uninit(void)
{ {
NRFX_IRQ_DISABLE(nrfx_get_irq_number(NRF_POWER)); NRFX_IRQ_DISABLE(nrfx_get_irq_number(NRF_POWER));
} }
#if NRF_POWER_HAS_POFCON #if NRFX_POWER_SUPPORTS_POFCON
nrfx_power_pof_uninit(); nrfx_power_pof_uninit();
#endif #endif
#if NRF_POWER_HAS_SLEEPEVT #if NRF_POWER_HAS_SLEEPEVT
nrfx_power_sleepevt_uninit(); nrfx_power_sleepevt_uninit();
#endif #endif
#if NRF_POWER_HAS_USBREG #if NRF_POWER_HAS_USBREG || defined(USBREG_PRESENT)
nrfx_power_usbevt_uninit(); nrfx_power_usbevt_uninit();
#endif #endif
m_initialized = false; 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) void nrfx_power_pof_init(nrfx_power_pofwarn_config_t const * p_config)
{ {
NRFX_ASSERT(p_config != NULL); 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) 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); nrf_power_pofcon_set(NRF_POWER, true, p_config->thr);
#if NRF_POWER_HAS_VDDH #elif NRF_REGULATORS_HAS_POFCON
nrf_power_pofcon_vddh_set(NRF_POWER, p_config->thrvddh); nrf_regulators_pofcon_set(NRF_REGULATORS, true, p_config->thr);
#endif #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) if (m_pofwarn_handler != NULL)
{ {
nrf_power_int_enable(NRF_POWER, NRF_POWER_INT_POFWARN_MASK); 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) void nrfx_power_pof_disable(void)
{ {
#if NRF_POWER_HAS_POFCON
nrf_power_pofcon_set(NRF_POWER, false, NRF_POWER_POFTHR_V27); 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); 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; m_pofwarn_handler = NULL;
} }
#endif // NRF_POWER_HAS_POFCON #endif // NRFX_POWER_SUPPORTS_POFCON
#if NRF_POWER_HAS_SLEEPEVT #if NRF_POWER_HAS_SLEEPEVT
void nrfx_power_sleepevt_init(nrfx_power_sleepevt_config_t const * p_config) 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) void nrfx_power_usbevt_uninit(void)
{ {
nrfx_power_usbevt_disable();
m_usbevt_handler = NULL; m_usbevt_handler = NULL;
} }
#endif /* NRF_POWER_HAS_USBREG */ #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); 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)) && if ((0 != (enabled & NRF_POWER_INT_POFWARN_MASK)) &&
nrf_power_event_get_and_clear(NRF_POWER, NRF_POWER_EVENT_POFWARN)) 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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; bool inverted = output_pin & NRFX_PWM_PIN_INVERTED;
out_pins[i] = 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]); if (inverted)
} {
else nrf_gpio_pin_set(out_pins[i]);
{ }
nrf_gpio_pin_clear(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 else
{ {
@ -368,14 +371,22 @@ bool nrfx_pwm_stop(nrfx_pwm_t const * p_instance,
bool ret_val = false; 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)) if (nrfx_pwm_is_stopped(p_instance))
{ {
ret_val = true; ret_val = true;
} }
else else
{ {
nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_STOP);
do { do {
if (nrfx_pwm_is_stopped(p_instance)) 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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); nrf_qdec_int_enable(NRF_QDEC, int_mask);
NRFX_IRQ_PRIORITY_SET(QDEC_IRQn, p_config->interrupt_priority); NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_QDEC), p_config->interrupt_priority);
NRFX_IRQ_ENABLE(QDEC_IRQn); NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_QDEC));
m_state = NRFX_DRV_STATE_INITIALIZED; m_state = NRFX_DRV_STATE_INITIALIZED;
@ -158,7 +158,7 @@ void nrfx_qdec_uninit(void)
return; return;
} }
nrfx_qdec_disable(); nrfx_qdec_disable();
NRFX_IRQ_DISABLE(QDEC_IRQn); NRFX_IRQ_DISABLE(nrfx_get_irq_number(NRF_QDEC));
m_state = NRFX_DRV_STATE_UNINITIALIZED; m_state = NRFX_DRV_STATE_UNINITIALIZED;
NRFX_LOG_INFO("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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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); 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) void nrfx_qspi_irq_handler(void)
{ {
// Catch Event ready interrupts // 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,24 +36,18 @@
#define NRFX_LOG_MODULE SAADC #define NRFX_LOG_MODULE SAADC
#include <nrfx_log.h> #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) #if defined(NRF52_SERIES) && !defined(USE_WORKAROUND_FOR_ANOMALY_212)
// ANOMALY 212 - SAADC events are missing when switching from single channel // ANOMALY 212 - SAADC events are missing when switching from single channel
// to multi channel configuration with burst enabled. // to multi channel configuration with burst enabled.
#define USE_WORKAROUND_FOR_ANOMALY_212 1 #define USE_WORKAROUND_FOR_ANOMALY_212 1
#endif #endif
#if defined(NRF91_SERIES) || defined(NRF53_SERIES) #if defined(NRF53_SERIES) || defined(NRF91_SERIES)
// Make sure that SAADC is stopped before channel configuration. // Make sure that SAADC is stopped before channel configuration.
#define STOP_SAADC_ON_CHANNEL_CONFIG 1 #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 #endif
/** @brief SAADC driver states.*/ /** @brief SAADC driver states.*/
@ -75,9 +69,12 @@ typedef struct
nrfx_saadc_event_handler_t event_handler; ///< Event handler function pointer. 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_primary; ///< Pointer to the primary result buffer.
nrf_saadc_value_t * p_buffer_secondary; ///< Pointer to the secondary 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_primary; ///< Size of the primary result buffer.
uint16_t size_secondary; ///< Size of the secondary 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_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_input_t channels_pseln[SAADC_CH_NUM]; ///< Array holding each channel negative input.
nrf_saadc_state_t saadc_state; ///< State of the SAADC driver. 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_low_activated; ///< Bitmask of the activated low limits.
uint8_t limits_high_activated; ///< Bitmask of the activated high 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 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; } nrfx_saadc_cb_t;
static nrfx_saadc_cb_t m_cb; 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) #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, static nrfx_err_t saadc_channel_count_get(uint32_t ch_to_activate_mask,
uint8_t * p_active_ch_count) 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) #if NRFX_CHECK(STOP_SAADC_ON_CHANNEL_CONFIG)
nrf_saadc_int_disable(NRF_SAADC, NRF_SAADC_INT_STOPPED); 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); nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STOPPED)) 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_STOPPED);
#endif #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.p_buffer_secondary = NULL;
m_cb.event_handler = event_handler; m_cb.event_handler = event_handler;
m_cb.channels_activated = ch_to_activate_mask; m_cb.channels_activated = ch_to_activate_mask;
m_cb.samples_converted = 0;
nrf_saadc_resolution_set(NRF_SAADC, resolution); nrf_saadc_resolution_set(NRF_SAADC, resolution);
nrf_saadc_oversample_set(NRF_SAADC, oversampling); nrf_saadc_oversample_set(NRF_SAADC, oversampling);
if (event_handler) if (event_handler)
{ {
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STARTED); nrf_saadc_int_set(NRF_SAADC,
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED); NRF_SAADC_INT_STARTED |
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END); NRF_SAADC_INT_STOPPED |
nrf_saadc_int_enable(NRF_SAADC, NRF_SAADC_INT_END);
NRF_SAADC_INT_STARTED |
NRF_SAADC_INT_STOPPED |
NRF_SAADC_INT_END);
} }
else else
{ {
nrf_saadc_int_disable(NRF_SAADC, nrf_saadc_int_set(NRF_SAADC, 0);
NRF_SAADC_INT_STARTED |
NRF_SAADC_INT_STOPPED |
NRF_SAADC_INT_END);
} }
for (uint32_t ch_pos = 0; ch_pos < SAADC_CH_NUM; ch_pos++) 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 nrfx_saadc_init(uint8_t interrupt_priority)
{ {
nrfx_err_t err_code;
if (m_cb.saadc_state != NRF_SAADC_STATE_UNINITIALIZED) if (m_cb.saadc_state != NRF_SAADC_STATE_UNINITIALIZED)
{ {
err_code = NRFX_ERROR_INVALID_STATE;
NRFX_LOG_WARNING("Function: %s, error code: %s.", NRFX_LOG_WARNING("Function: %s, error code: %s.",
__func__, __func__,
NRFX_LOG_ERROR_STRING_GET(err_code)); NRFX_LOG_ERROR_STRING_GET(err_code));
return NRFX_ERROR_INVALID_STATE; return err_code;
} }
m_cb.saadc_state = NRF_SAADC_STATE_IDLE; 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_ENABLE(SAADC_IRQn);
NRFX_IRQ_PRIORITY_SET(SAADC_IRQn, interrupt_priority); 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)); 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) void nrfx_saadc_uninit(void)
@ -340,6 +326,7 @@ nrfx_err_t nrfx_saadc_simple_mode_set(uint32_t channel_mask,
} }
else else
{ {
// Burst is implicitly enabled if oversampling is enabled.
burst = NRF_SAADC_BURST_ENABLED; burst = NRF_SAADC_BURST_ENABLED;
} }
@ -349,17 +336,6 @@ nrfx_err_t nrfx_saadc_simple_mode_set(uint32_t channel_mask,
burst, burst,
event_handler); 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.channels_activated_count = active_ch_count;
m_cb.saadc_state = NRF_SAADC_STATE_SIMPLE_MODE; 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; return NRFX_ERROR_NOT_SUPPORTED;
} }
bool oversampling_without_burst = false;
if ((p_config->oversampling != NRF_SAADC_OVERSAMPLE_DISABLED) && if ((p_config->oversampling != NRF_SAADC_OVERSAMPLE_DISABLED) &&
(p_config->burst == NRF_SAADC_BURST_DISABLED)) (p_config->burst == NRF_SAADC_BURST_DISABLED))
{ {
// Oversampling without burst
if (active_ch_count > 1) if (active_ch_count > 1)
{ {
// Oversampling without burst is possible only on single channel.
return NRFX_ERROR_NOT_SUPPORTED; return NRFX_ERROR_NOT_SUPPORTED;
} }
else else
{ {
m_cb.samples_per_trigger = oversampling_without_burst = true;
nrf_saadc_oversample_sample_count_get(p_config->oversampling);
} }
} }
else
{
m_cb.samples_per_trigger = active_ch_count;
}
saadc_generic_mode_set(channel_mask, saadc_generic_mode_set(channel_mask,
resolution, 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.channels_activated_count = active_ch_count;
m_cb.start_on_end = p_config->start_on_end; 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; 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; return NRFX_ERROR_INVALID_LENGTH;
} }
m_cb.p_buffer_primary = p_buffer;
m_cb.size_primary = size; m_cb.size_primary = size;
nrf_saadc_buffer_init(NRF_SAADC, p_buffer, size); m_cb.p_buffer_primary = p_buffer;
break; break;
case NRF_SAADC_STATE_ADV_MODE_SAMPLE_STARTED: 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: case NRF_SAADC_STATE_ADV_MODE_SAMPLE:
if (m_cb.p_buffer_primary) if (m_cb.p_buffer_primary)
{ {
m_cb.p_buffer_secondary = p_buffer;
m_cb.size_secondary = size; m_cb.size_secondary = size;
m_cb.p_buffer_secondary = p_buffer;
} }
else else
{ {
m_cb.p_buffer_primary = p_buffer;
m_cb.size_primary = size; m_cb.size_primary = size;
nrf_saadc_buffer_init(NRF_SAADC, p_buffer, size); m_cb.p_buffer_primary = p_buffer;
} }
break; break;
@ -505,9 +476,14 @@ nrfx_err_t nrfx_saadc_mode_trigger(void)
} }
nrfx_err_t result = NRFX_SUCCESS; nrfx_err_t result = NRFX_SUCCESS;
switch (m_cb.saadc_state) { switch (m_cb.saadc_state)
{
case NRF_SAADC_STATE_SIMPLE_MODE: case NRF_SAADC_STATE_SIMPLE_MODE:
nrf_saadc_enable(NRF_SAADC); 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) if (m_cb.event_handler)
{ {
m_cb.saadc_state = NRF_SAADC_STATE_SIMPLE_MODE_SAMPLE; 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); 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)) while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END))
{} {}
nrf_saadc_event_clear(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); nrf_saadc_enable(NRF_SAADC);
if (m_cb.event_handler) 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; 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); nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
break; 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); nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STARTED)) while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STARTED))
{} {}
nrf_saadc_event_clear(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.oversampling_without_burst)
if (m_cb.event_handler)
{ {
result = NRFX_ERROR_INVALID_STATE; // Oversampling without burst is possible only on single channel.
break; // 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(); for (uint32_t sample_idx = 0; sample_idx < samples_to_take; sample_idx++)
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)
{ {
nrf_saadc_buffer_init(NRF_SAADC, nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_DONE);
m_cb.p_buffer_primary, nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
m_cb.size_primary); while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_DONE))
{}
} }
else
{
nrf_saadc_disable(NRF_SAADC);
}
result = NRFX_SUCCESS;
} }
else 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; 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; break;
default: default:
@ -589,43 +580,19 @@ void nrfx_saadc_abort(void)
{ {
NRFX_ASSERT(m_cb.saadc_state != NRF_SAADC_STATE_UNINITIALIZED); 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_primary = NULL;
m_cb.p_buffer_secondary = 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: // STOPPED event does not appear when the calibration is ongoing
m_cb.saadc_state = NRF_SAADC_STATE_SIMPLE_MODE; m_cb.saadc_state = NRF_SAADC_STATE_IDLE;
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;
} }
} }
} }
@ -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.saadc_state = NRF_SAADC_STATE_CALIBRATION;
m_cb.event_handler = event_handler; m_cb.event_handler = event_handler;
nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE);
nrf_saadc_enable(NRF_SAADC); 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); nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_CALIBRATEOFFSET);
if (event_handler) 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); nrf_saadc_disable(NRF_SAADC);
m_cb.saadc_state = NRF_SAADC_STATE_IDLE; m_cb.saadc_state = NRF_SAADC_STATE_IDLE;
} }
#endif // NRFX_CHECK(INTERCEPT_SAADC_CALIBRATION_SAMPLES)
return NRFX_SUCCESS; return NRFX_SUCCESS;
} }
@ -737,14 +728,25 @@ static void saadc_event_started_handle(void)
/* fall-through */ /* fall-through */
case NRF_SAADC_STATE_ADV_MODE_SAMPLE_STARTED: case NRF_SAADC_STATE_ADV_MODE_SAMPLE_STARTED:
evt_data.type = NRFX_SAADC_EVT_BUF_REQ; if (!m_cb.p_buffer_secondary)
m_cb.event_handler(&evt_data); {
// 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; break;
case NRF_SAADC_STATE_SIMPLE_MODE_SAMPLE: case NRF_SAADC_STATE_SIMPLE_MODE_SAMPLE:
nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE); nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
break; 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: default:
break; break;
} }
@ -819,16 +821,6 @@ void nrfx_saadc_irq_handler(void)
saadc_event_started_handle(); 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)) if (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_STOPPED);
@ -842,7 +834,15 @@ void nrfx_saadc_irq_handler(void)
if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END)) if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END))
{ {
nrf_saadc_event_clear(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); 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)) if (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_CALIBRATEDONE);
nrf_saadc_disable(NRF_SAADC);
m_cb.saadc_state = NRF_SAADC_STATE_IDLE; 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; evt_data.type = NRFX_SAADC_EVT_CALIBRATEDONE;
m_cb.event_handler(&evt_data); 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) #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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_SPIM_ENABLED)
#if !(NRFX_CHECK(NRFX_SPIM0_ENABLED) || NRFX_CHECK(NRFX_SPIM1_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>." #error "No enabled SPIM instances. Check <nrfx_config.h>."
#endif #endif
@ -121,29 +122,45 @@
#define SPIM3_SUPPORTED_FREQ_VALIDATE(...) 0 #define SPIM3_SUPPORTED_FREQ_VALIDATE(...) 0
#endif #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) \ #define SPIM_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) \
(SPIM0_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) || \ SPIM1_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) || \
SPIM2_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) \ #define SPIM_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) \
(SPIM0_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) || \ (SPIM0_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM1_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) || \ SPIM1_HW_CSN_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM2_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) \ #define SPIM_DCX_PRESENT_VALIDATE(drv_inst_idx) \
(SPIM0_DCX_PRESENT_VALIDATE(drv_inst_idx) || \ (SPIM0_DCX_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM1_DCX_PRESENT_VALIDATE(drv_inst_idx) || \ SPIM1_DCX_PRESENT_VALIDATE(drv_inst_idx) || \
SPIM2_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) \ #define SPIM_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) \
(SPIM0_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) || \ (SPIM0_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) || \
SPIM1_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) || \ SPIM1_SUPPORTED_FREQ_VALIDATE(drv_inst_idx, freq) || \
SPIM2_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)) #if defined(NRF52840_XXAA) && (NRFX_CHECK(NRFX_SPIM3_ENABLED))
// Enable workaround for nRF52840 anomaly 195 (SPIM3 continues to draw current after disable). // 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) #if NRFX_CHECK(NRFX_SPIM3_ENABLED)
nrfx_spim_3_irq_handler, nrfx_spim_3_irq_handler,
#endif #endif
#if NRFX_CHECK(NRFX_SPIM4_ENABLED)
nrfx_spim_4_irq_handler,
#endif
}; };
if (nrfx_prs_acquire(p_instance->p_reg, if (nrfx_prs_acquire(p_instance->p_reg,
irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS) irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
@ -757,4 +777,11 @@ void nrfx_spim_3_irq_handler(void)
} }
#endif #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) #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \
(event == NRFX_TWI_EVT_DATA_NACK ? "EVT_DATA_NACK" : \ (event == NRFX_TWI_EVT_DATA_NACK ? "EVT_DATA_NACK" : \
(event == NRFX_TWI_EVT_OVERRUN ? "EVT_OVERRUN" : \ (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) \ #define EVT_TO_STR_TWI(event) \
(event == NRF_TWI_EVENT_STOPPED ? "NRF_TWI_EVENT_STOPPED" : \ (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; 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_err_t nrfx_twi_init(nrfx_twi_t const * p_instance,
nrfx_twi_config_t const * p_config, 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) if (p_cb->bytes_transferred < p_cb->curr_length)
{ {
nrf_twi_txd_set(p_twi, p_cb->p_curr_buf[p_cb->bytes_transferred]); nrf_twi_txd_set(p_twi, p_cb->p_curr_buf[p_cb->bytes_transferred]);
++(p_cb->bytes_transferred);
} }
else else
{ {
@ -321,7 +339,19 @@ static bool twi_receive_byte(NRF_TWI_Type * p_twi,
static bool twi_transfer(NRF_TWI_Type * p_twi, static bool twi_transfer(NRF_TWI_Type * p_twi,
twi_control_block_t * p_cb) 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) 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)) if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT))
{ {
nrf_twi_event_clear(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)); 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)) 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; 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; 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); ret_code = twi_process_error(errorsrc);
} }
else
{
ret_code = NRFX_ERROR_INTERNAL;
}
} }
if (hw_timeout <= 0) 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); ret_code = twi_process_error(errorsrc);
} }
else
{
ret_code = NRFX_ERROR_INTERNAL;
}
} }
if (hw_timeout <= 0) 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; event.type = NRFX_TWI_EVT_OVERRUN;
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(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 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; 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); 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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_DONE ? "EVT_DONE" : \
(event == NRFX_TWIM_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \ (event == NRFX_TWIM_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \
(event == NRFX_TWIM_EVT_DATA_NACK ? "EVT_DATA_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) \ #define EVT_TO_STR_TWIM(event) \
(event == NRF_TWIM_EVENT_STOPPED ? "NRF_TWIM_EVENT_STOPPED" : \ (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; 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, // 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 // 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 // In such case the peripheral has to be disabled and re-enabled, so that its
// internal state machine is reinitialized. // 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) switch (p_cb->xfer_desc.type)
{ {
case NRFX_TWIM_XFER_TXTX: 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)) || (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))) (nrf_twim_txd_amount_get(p_twim) != p_cb->xfer_desc.secondary_length)))
{ {
transfer_complete = false; 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; nrfx_err_t err_code = NRFX_SUCCESS;
nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX; 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; p_cb->error = false;
if (!nrfx_is_in_ram(p_xfer_desc->p_primary_buf)) 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->xfer_desc = *p_xfer_desc;
p_cb->repeated = (flags & NRFX_TWIM_FLAG_REPEATED_XFER) ? true : false; 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_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_STOPPED);
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); 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); twim_list_enable_handle(p_twim, flags);
switch (p_xfer_desc->type) 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_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_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_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_RESUME);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED)) 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)); 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_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); 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; break;
case NRFX_TWIM_XFER_TXRX: case NRFX_TWIM_XFER_TXRX:
nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); 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_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_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK |
NRF_TWIM_SHORT_LASTRX_STOP_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); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
break; break;
case NRFX_TWIM_XFER_TX: 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) if (NRFX_TWIM_FLAG_TX_NO_STOP & flags)
{ {
nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); 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; p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK;
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
evt_to_wait = NRF_TWIM_EVENT_SUSPENDED;
} }
else else
{ {
nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); 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); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
break; break;
case NRFX_TWIM_XFER_RX: 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_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); 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; start_task = NRF_TWIM_TASK_STARTRX;
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
break; 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) 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); nrf_twim_int_enable(p_twim, p_cb->int_mask);
#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED) #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) || if ((flags & NRFX_TWIM_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRFX_TWIM_XFER_RX))
(p_xfer_desc->type == NRFX_TWIM_XFER_TXRX)))
{ {
p_cb->flags = flags;
twim_list_enable_handle(p_twim, 0); twim_list_enable_handle(p_twim, 0);
p_twim->FREQUENCY = 0; p_twim->FREQUENCY = 0;
nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK); nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
}
else
{
nrf_twim_frequency_set(p_twim, p_cb->bus_frequency);
} }
#endif #endif
} }
else 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)) 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_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
evt_to_wait = NRF_TWIM_EVENT_STOPPED; 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); 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 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; 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; p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
nrf_twim_int_enable(p_twim, p_cb->int_mask); nrf_twim_int_enable(p_twim, p_cb->int_mask);
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); if (!(nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_LASTTX) &&
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); (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; p_cb->error = true;
return; 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)); NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED));
nrf_twim_event_clear(p_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); 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); // Further processing of STOPPED event is valid only if NO_XFER_EVT_HANDLER
if (!p_cb->repeated || p_cb->error) // setting is not used.
if (!(p_cb->flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER))
{ {
nrf_twim_shorts_set(p_twim, 0); event.xfer_desc = p_cb->xfer_desc;
p_cb->int_mask = 0; nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK); 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 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); nrf_twim_shorts_set(p_twim, 0);
p_cb->int_mask = 0; p_cb->int_mask = 0;
nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK); 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 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) else if (errorsrc & NRF_TWIM_ERROR_OVERRUN)
{ {
event.type = NRFX_TWIM_EVT_DATA_NACK; event.type = NRFX_TWIM_EVT_OVERRUN;
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DATA_NACK)); 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 else
{ {
if (p_cb->error) event.type = NRFX_TWIM_EVT_DONE;
{
event.type = NRFX_TWIM_EVT_BUS_ERROR;
}
else
{
event.type = NRFX_TWIM_EVT_DONE;
}
NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(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->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) #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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_err_t nrfx_uarte_init(nrfx_uarte_t const * p_instance,
nrfx_uarte_config_t const * p_config, nrfx_uarte_config_t const * p_config,
nrfx_uarte_event_handler_t event_handler) 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_config(p_instance, p_config);
apply_workaround_for_enable_anomaly(p_instance);
p_cb->handler = event_handler; p_cb->handler = event_handler;
p_cb->p_context = p_config->p_context; p_cb->p_context = p_config->p_context;
@ -262,6 +296,7 @@ void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
{ {
return; return;
} }
NRF_UARTE_Type * p_reg = p_instance->p_reg;
if (p_cb->handler) 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 // Make sure all transfers are finished before UARTE is disabled
// to achieve the lowest power consumption. // to achieve the lowest power consumption.
nrf_uarte_shorts_disable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX); nrf_uarte_shorts_disable(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); // Check if there is any ongoing reception.
nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX); if (p_cb->rx_buffer_length)
while (!nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED)) {
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); pins_to_default(p_instance);
#if NRFX_CHECK(NRFX_PRS_ENABLED) #if NRFX_CHECK(NRFX_PRS_ENABLED)
nrfx_prs_release(p_instance->p_reg); nrfx_prs_release(p_reg);
#endif #endif
p_cb->state = NRFX_DRV_STATE_UNINITIALIZED; 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. */ /* Workaround: Disarm the endpoint if there is any data buffered. */
if(ep != NRFX_USBD_EPIN0) if(ep != NRFX_USBD_EPIN0)
{ {
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1)); *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1));
uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); uint8_t temp = *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
temp |= (1U << 1); temp |= (1U << 1);
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) |= temp;
(void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); (void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
} }
else else
{ {
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7B4; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7B4;
uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); uint8_t temp = *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
temp |= (1U << 2); temp |= (1U << 2);
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) |= temp;
(void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); (void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
} }
} }
if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U << ep2bit(ep))) 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); 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); nrfx_systick_delay_us(2);
} }
@ -1573,54 +1573,54 @@ void nrfx_usbd_irq_handler(void)
{ {
uint8_t usbi, uoi, uii; uint8_t usbi, uoi, uii;
/* Testing */ /* Testing */
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7A9;
uii = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); uii = (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
if (0 != uii) 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; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AA;
uoi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); uoi = (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
if (0 != uoi) 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; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AB;
usbi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); usbi = (uint8_t)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
if (0 != usbi) 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 */ /* Processing */
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AC; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AC;
uii &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); uii &= (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
if (0 != uii) if (0 != uii)
{ {
uint8_t rb; uint8_t rb;
m_simulated_dataepstatus |= ((uint32_t)uii) << NRFX_USBD_EPIN_BITPOS_0; m_simulated_dataepstatus |= ((uint32_t)uii) << NRFX_USBD_EPIN_BITPOS_0;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7A9;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uii; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = uii;
rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); rb = (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" uii: 0x%.2x (0x%.2x)", uii, rb); NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" uii: 0x%.2x (0x%.2x)", uii, rb);
(void)rb; (void)rb;
} }
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AD; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AD;
uoi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); uoi &= (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
if (0 != uoi) if (0 != uoi)
{ {
uint8_t rb; uint8_t rb;
m_simulated_dataepstatus |= ((uint32_t)uoi) << NRFX_USBD_EPOUT_BITPOS_0; m_simulated_dataepstatus |= ((uint32_t)uoi) << NRFX_USBD_EPOUT_BITPOS_0;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AA;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uoi; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = uoi;
rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); rb = (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" uoi: 0x%.2u (0x%.2x)", uoi, rb); NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" uoi: 0x%.2u (0x%.2x)", uoi, rb);
(void)rb; (void)rb;
} }
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AE; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AE;
usbi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); usbi &= (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
if (0 != usbi) if (0 != usbi)
{ {
uint8_t rb; uint8_t rb;
@ -1632,9 +1632,9 @@ void nrfx_usbd_irq_handler(void)
{ {
active |= USBD_INTEN_USBRESET_Msk; active |= USBD_INTEN_USBRESET_Msk;
} }
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7AB;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = usbi; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = usbi;
rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); rb = (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" usbi: 0x%.2u (0x%.2x)", usbi, rb); NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" usbi: 0x%.2u (0x%.2x)", usbi, rb);
(void)rb; (void)rb;
} }
@ -1791,8 +1791,8 @@ void nrfx_usbd_enable(void)
if (nrfx_usbd_errata_166()) if (nrfx_usbd_errata_166())
{ {
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7E3; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7E3;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0x40; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = 0x40;
__ISB(); __ISB();
__DSB(); __DSB();
} }
@ -2339,9 +2339,9 @@ void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep)
{ {
NRFX_CRITICAL_SECTION_ENTER(); NRFX_CRITICAL_SECTION_ENTER();
m_ep_ready &= ~(1U << ep2bit(ep)); m_ep_ready &= ~(1U << ep2bit(ep));
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + (2u * NRF_USBD_EP_NR_GET(ep)); *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7C5 + (2u * NRF_USBD_EP_NR_GET(ep));
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0; *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = 0;
(void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); (void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
NRFX_CRITICAL_SECTION_EXIT(); NRFX_CRITICAL_SECTION_EXIT();
} }
else else

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -33,6 +33,8 @@
#define NRFX_USBD_ERRATA_H__ #define NRFX_USBD_ERRATA_H__
#include <stdbool.h> #include <stdbool.h>
#include <nrfx.h>
#include <nrf_erratas.h>
#ifndef NRFX_USBD_ERRATA_ENABLE #ifndef NRFX_USBD_ERRATA_ENABLE
/** /**
@ -43,106 +45,46 @@
#define NRFX_USBD_ERRATA_ENABLE 1 #define NRFX_USBD_ERRATA_ENABLE 1
#endif #endif
static inline bool nrfx_usbd_errata_type_52840(void) /* Errata: USBD: EPDATA event is not always generated. **/
{
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.
**/
static inline bool nrfx_usbd_errata_104(void) static inline bool nrfx_usbd_errata_104(void)
{ {
return (NRFX_USBD_ERRATA_ENABLE && (nrfx_usbd_errata_type_52840() return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_104();
&& !nrfx_usbd_errata_type_52840_eng_b_or_later()));
} }
/* Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task. /* Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task. **/
*
* Applies to nRF52840 Engineering A.
**/
static inline bool nrfx_usbd_errata_154(void) static inline bool nrfx_usbd_errata_154(void)
{ {
return (NRFX_USBD_ERRATA_ENABLE && (nrfx_usbd_errata_type_52840() return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_154();
&& !nrfx_usbd_errata_type_52840_eng_b_or_later()));
} }
/* Errata: ISO double buffering not functional. /* Errata: ISO double buffering not functional. **/
*
* Applies to nRF52840.
**/
static inline bool nrfx_usbd_errata_166(void) 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. /* Errata: USBD might not reach its active state. **/
*
* Applies to nRF52840.
**/
static inline bool nrfx_usbd_errata_171(void) 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. /* Errata: USB cannot be enabled. **/
*
* Applies to nRF52840 Engineering B or later and nRF52833.
**/
static inline bool nrfx_usbd_errata_187(void) static inline bool nrfx_usbd_errata_187(void)
{ {
return (NRFX_USBD_ERRATA_ENABLE && (nrfx_usbd_errata_type_52840_eng_b_or_later() return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_187();
|| nrfx_usbd_errata_type_52833()));
} }
/* Errata: USBD cannot receive tasks during DMA. /* Errata: USBD cannot receive tasks during DMA. **/
*
* Applies to nRF52840.
**/
static inline bool nrfx_usbd_errata_199(void) 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. /* Errata: SIZE.EPOUT not writable. **/
*
* Applies to nRF52840 Engineering A.
**/
static inline bool nrfx_usbd_errata_200(void) static inline bool nrfx_usbd_errata_200(void)
{ {
return (NRFX_USBD_ERRATA_ENABLE && (nrfx_usbd_errata_type_52840() return NRFX_USBD_ERRATA_ENABLE && nrf52_errata_200();
&& !nrfx_usbd_errata_type_52840_eng_b_or_later()));
} }
#endif // NRFX_USBD_ERRATA_H__ #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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 #define NRFX_PRS_BOX_0_ADDR NRF_UARTE0
// SPIM1, SPIS1, TWIM1, TWIS1, UARTE1 // SPIM1, SPIS1, TWIM1, TWIS1, UARTE1
#define NRFX_PRS_BOX_1_ADDR NRF_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 // COMP, LPCOMP
#define NRFX_PRS_BOX_2_ADDR NRF_COMP #define NRFX_PRS_BOX_4_ADDR NRF_COMP
#elif defined(NRF5340_XXAA_NETWORK) #elif defined(NRF5340_XXAA_NETWORK)
// SPIM0, SPIS0, TWIM0, TWIS0, UARTE0 // SPIM0, SPIS0, TWIM0, TWIS0, UARTE0
#define NRFX_PRS_BOX_0_ADDR NRF_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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * NVM protection is disabled by default while debugging.
* *
* @param[in] p_reg Pointer to the structure of registers of the peripheral. * @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. * @param[in] enable True if NVM protection during debug is to be enabled, false otherwise.
* False if otherwise.
*/ */
NRF_STATIC_INLINE void nrf_bprot_nvm_protection_in_debug_set(NRF_BPROT_Type * p_reg, NRF_STATIC_INLINE void nrf_bprot_nvm_protection_in_debug_set(NRF_BPROT_Type * p_reg,
bool enable); bool enable);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, Nordic Semiconductor ASA * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * @brief Function for setting the cache profiling.
* *
* @param[in] p_reg Pointer to the structure of registers of the peripheral. * @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable True if cache profiling is to be enabled. * @param[in] enable True if cache profiling is to be enabled, false otherwise.
* False if otherwise.
*/ */
NRF_STATIC_INLINE void nrf_cache_profiling_set(NRF_CACHE_Type * p_reg, bool enable); 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. * @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] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable True if the cache RAM mode is to be enabled. * @param[in] enable True if the cache RAM mode is to be enabled, false otherwise.
* False if otherwise.
*/ */
NRF_STATIC_INLINE void nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg, bool enable); 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. * @note Blocking is ignored in the RAM mode.
* *
* @param[in] p_reg Pointer to the structure of registers of the peripheral. * @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. * @param[in] enable True if cache content update lock is to be enabled, false otherwise.
* False if otherwise.
*/ */
NRF_STATIC_INLINE void nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg, bool enable); 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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) 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); return (uint32_t *)(p_reg->CNFPTR);
#endif
} }
NRF_STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type * p_reg, 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) 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); return (uint32_t *)(p_reg->INPTR);
#endif
} }
NRF_STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type * p_reg, 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) 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); return (uint32_t *)(p_reg->OUTPTR);
#endif
} }
NRF_STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg, 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) 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); return (uint32_t *)(p_reg->SCRATCHPTR);
#endif
} }
#if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) #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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -44,8 +44,9 @@ extern "C" {
* @ingroup nrf_clock * @ingroup nrf_clock
* @brief Hardware access layer for managing the CLOCK peripheral. * @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 * This code can be used to manage low-frequency clock (LFCLK), high-frequency clock (HFCLK),
* (HFCLK) settings. * high-frequency 192 MHz clock (HFCLK192M) and high-frequency audio clock (HFCLKAUDIO)
* settings.
*/ */
#if defined(CLOCK_LFCLKSRC_BYPASS_Msk) && defined(CLOCK_LFCLKSRC_EXTERNAL_Msk) #if defined(CLOCK_LFCLKSRC_BYPASS_Msk) && defined(CLOCK_LFCLKSRC_EXTERNAL_Msk)
@ -53,16 +54,57 @@ extern "C" {
#define NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES #define NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES
#endif #endif
#if defined(CLOCK_CTIV_CTIV_Msk) || defined(__NRFX_DOXYGEN__) #if defined(CLOCK_INTENSET_DONE_Msk) || defined(__NRFX_DOXYGEN__)
/** /** @brief Presence of the Low Frequency Clock calibration. */
* @brief Presence of the Low Frequency Clock calibration.
*
* In some MCUs there is possibility to use LFCLK calibration.
*/
#define NRF_CLOCK_HAS_CALIBRATION 1 #define NRF_CLOCK_HAS_CALIBRATION 1
#else #else
#define NRF_CLOCK_HAS_CALIBRATION 0 #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. * @brief Low-frequency clock sources.
@ -70,6 +112,9 @@ extern "C" {
*/ */
typedef enum 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__) #if defined(CLOCK_LFCLKSRC_SRC_RC) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */ NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */
#else #else
@ -102,11 +147,16 @@ typedef enum
#endif // defined(NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES) || defined(__NRFX_DOXYGEN__) #endif // defined(NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES) || defined(__NRFX_DOXYGEN__)
} nrf_clock_lfclk_t; } nrf_clock_lfclk_t;
/** @brief High-frequency clock sources. */ /**
* @brief High-frequency clock sources.
* @details Used by HFCLKSTAT and HFCLK192MSTAT registers.
*/
typedef enum typedef enum
{ {
#if defined(CLOCK_HFCLKSTAT_SRC_RC) || defined(__NRFX_DOXYGEN__) #if defined(CLOCK_HFCLKSTAT_SRC_RC) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */ 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 #endif
#if defined(CLOCK_HFCLKSTAT_SRC_Xtal) || defined(__NRFX_DOXYGEN__) #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. */ NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */
@ -115,8 +165,39 @@ typedef enum
#endif #endif
} nrf_clock_hfclk_t; } 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. * @brief Trigger status of task LFCLKSTART/HFCLKSTART.
*
* @note This enum is deprecated.
*
* @details Used by LFCLKRUN and HFCLKRUN registers. * @details Used by LFCLKRUN and HFCLKRUN registers.
*/ */
typedef enum typedef enum
@ -128,15 +209,24 @@ typedef enum
/** @brief Interrupts. */ /** @brief Interrupts. */
typedef enum typedef enum
{ {
NRF_CLOCK_INT_HF_STARTED_MASK = CLOCK_INTENSET_HFCLKSTARTED_Msk, /**< Interrupt on HFCLKSTARTED 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. */ NRF_CLOCK_INT_LF_STARTED_MASK = CLOCK_INTENSET_LFCLKSTARTED_Msk, /**< Interrupt on LFCLKSTARTED event. */
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__) #if NRF_CLOCK_HAS_CALIBRATION
NRF_CLOCK_INT_DONE_MASK = CLOCK_INTENSET_DONE_Msk, /**< Interrupt on DONE event. */ 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. */ #endif
#if NRF_CLOCK_HAS_CALIBRATION_TIMER
NRF_CLOCK_INT_CTTO_MASK = CLOCK_INTENSET_CTTO_Msk, /**< Interrupt on CTTO event. */
#endif #endif
#if defined(CLOCK_INTENSET_CTSTARTED_Msk) || defined(__NRFX_DOXYGEN__) #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_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_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 #endif
} nrf_clock_int_mask_t; } nrf_clock_int_mask_t;
@ -148,29 +238,47 @@ typedef enum
*/ */
typedef enum typedef enum
{ {
NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /**< Start HFCLK clock source.*/ 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_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_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.*/ NRF_CLOCK_TASK_LFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTOP), /**< Stop LFCLK clock source. */
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__) #if NRF_CLOCK_HAS_CALIBRATION
NRF_CLOCK_TASK_CAL = offsetof(NRF_CLOCK_Type, TASKS_CAL), /**< Start calibration of LFCLK RC oscillator.*/ 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.*/ #endif
NRF_CLOCK_TASK_CTSTOP = offsetof(NRF_CLOCK_Type, TASKS_CTSTOP) /**< Stop calibration timer.*/ #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 #endif
} nrf_clock_task_t; } nrf_clock_task_t;
/** @brief Events. */ /** @brief Events. */
typedef enum typedef enum
{ {
NRF_CLOCK_EVENT_HFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED), /**< HFCLK oscillator started.*/ 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.*/ NRF_CLOCK_EVENT_LFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_LFCLKSTARTED), /**< LFCLK oscillator started. */
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__) #if NRF_CLOCK_HAS_CALIBRATION
NRF_CLOCK_EVENT_DONE = offsetof(NRF_CLOCK_Type, EVENTS_DONE), /**< Calibration of LFCLK RC oscillator completed.*/ 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.*/ #endif
#if NRF_CLOCK_HAS_CALIBRATION_TIMER
NRF_CLOCK_EVENT_CTTO = offsetof(NRF_CLOCK_Type, EVENTS_CTTO), /**< Calibration timer time-out. */
#endif #endif
#if defined(CLOCK_INTENSET_CTSTARTED_Msk) || defined(__NRFX_DOXYGEN__) #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_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_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 #endif
} nrf_clock_event_t; } 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); 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. * @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] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] source New low-frequency clock source. * @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. * @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. * @param[in] p_reg Pointer to the structure of registers of the peripheral.
* *
* @retval NRF_CLOCK_LFCLK_RC The internal 32 kHz RC oscillator * @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. * @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. * @param[in] p_reg Pointer to the structure of registers of the peripheral.
* *
* @retval false The LFCLK clock is not running. * @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. * @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. * @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. * @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_STATIC_INLINE
nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(NRF_CLOCK_Type const * p_reg); 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. * @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. * 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. * source of the high-frequency clock.
*/ */
NRF_STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(NRF_CLOCK_Type const * p_reg); 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. * @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] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] clk_src Clock source to be checked. * @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. * @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. * @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. * @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_STATIC_INLINE
nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(NRF_CLOCK_Type const * p_reg); 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. * @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); NRF_STATIC_INLINE void nrf_clock_cal_timer_timeout_set(NRF_CLOCK_Type * p_reg, uint32_t interval);
#endif #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__) #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/** /**
* @brief Function for setting the subscribe configuration for a given * @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)); 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) 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); 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) 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) nrf_clock_lfclk_t clk_src;
>> CLOCK_LFCLKSTAT_SRC_Pos); (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) 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) 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_STATIC_INLINE
nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(NRF_CLOCK_Type const * p_reg) 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) return (nrf_clock_start_task_status_t)nrf_clock_start_task_check(p_reg,
>> CLOCK_LFCLKRUN_STATUS_Pos); 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) 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) return (nrf_clock_hfclk_t)((p_reg->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk)
>> CLOCK_HFCLKSTAT_SRC_Pos); >> CLOCK_HFCLKSTAT_SRC_Pos);
#endif
} }
NRF_STATIC_INLINE bool nrf_clock_hf_is_running(NRF_CLOCK_Type const * p_reg, NRF_STATIC_INLINE bool nrf_clock_hf_is_running(NRF_CLOCK_Type const * p_reg,
nrf_clock_hfclk_t clk_src) nrf_clock_hfclk_t clk_src)
{ {
return (p_reg->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) == nrf_clock_hfclk_t active_clk_src;
(CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos)); 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_STATIC_INLINE
nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(NRF_CLOCK_Type const * p_reg) 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) return (nrf_clock_start_task_status_t)nrf_clock_start_task_check(p_reg,
>> CLOCK_HFCLKRUN_STATUS_Pos); 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) 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); p_reg->CTIV = ((interval << CLOCK_CTIV_CTIV_Pos) & CLOCK_CTIV_CTIV_Msk);
} }
#endif #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) #if defined(DPPI_PRESENT)
NRF_STATIC_INLINE void nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg, NRF_STATIC_INLINE void nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg,
nrf_clock_task_t task, 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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. * @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. */ /** @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)) #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. */ /** @brief Enumerator used for selecting output drive mode. */
typedef enum typedef enum
{ {
NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '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_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_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_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_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_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_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_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; } nrf_gpio_pin_drive_t;
/** @brief Enumerator used for selecting the pin to sense high or low level on the pin input. */ /** @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 length,
uint32_t * p_masks); 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. * @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 length,
uint32_t * p_masks); 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. * @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. * @param pin_number Pin number.
*/ */
NRF_STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t 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__) #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, NRF_STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port,
uint32_t length, uint32_t length,
uint32_t * p_masks) 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) 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); reg->LATCH = (1 << pin_number);
} }
#endif #endif // defined(NRF_GPIO_LATCH_PRESENT)
#if defined(GPIO_PIN_CNF_MCUSEL_Msk) #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) 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