mirror of https://github.com/ARMmbed/mbed-os.git
Added missing SDK drivers, added SOFTDEVICE_PRESENT macros in targets definitions.
parent
6afe131cfa
commit
2eaa468c50
|
@ -1100,7 +1100,7 @@
|
|||
"inherits": ["Target"],
|
||||
"core": "Cortex-M0",
|
||||
"OVERRIDE_BOOTLOADER_FILENAME": "nrf51822_bootloader.hex",
|
||||
"macros": ["NRF51", "TARGET_NRF51822"],
|
||||
"macros": ["NRF51", "TARGET_NRF51822", "SOFTDEVICE_PRESENT"],
|
||||
"MERGE_BOOTLOADER": false,
|
||||
"extra_labels": ["NORDIC", "MCU_NRF51", "MCU_NRF51822", "NRF5"],
|
||||
"OUTPUT_EXT": "hex",
|
||||
|
@ -1738,11 +1738,11 @@
|
|||
"MCU_NRF52": {
|
||||
"inherits": ["Target"],
|
||||
"core": "Cortex-M4F",
|
||||
"macros": ["NRF52", "TARGET_NRF52832"],
|
||||
"macros": ["NRF52", "TARGET_NRF52832", "SOFTDEVICE_PRESENT"],
|
||||
"extra_labels": ["NORDIC", "MCU_NRF52", "MCU_NRF52832", "NRF5"],
|
||||
"OUTPUT_EXT": "hex",
|
||||
"is_disk_virtual": true,
|
||||
"supported_toolchains": ["ARM", "GCC_ARM"],
|
||||
"supported_toolchains": ["GCC_ARM"],
|
||||
"public": false,
|
||||
"detect_code": ["1101"],
|
||||
"program_cycle_s": 6,
|
||||
|
|
|
@ -0,0 +1,479 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nrf_drv_clock.h"
|
||||
#include "nrf_error.h"
|
||||
#include "nordic_common.h"
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#include "nrf_sdm.h"
|
||||
#include "nrf_soc.h"
|
||||
#include "app_util_platform.h"
|
||||
#else
|
||||
#include "app_util_platform.h"
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
/*lint -save -e652 */
|
||||
#define NRF_CLOCK_LFCLK_RC CLOCK_LFCLKSRC_SRC_RC
|
||||
#define NRF_CLOCK_LFCLK_Xtal CLOCK_LFCLKSRC_SRC_Xtal
|
||||
#define NRF_CLOCK_LFCLK_Synth CLOCK_LFCLKSRC_SRC_Synth
|
||||
/*lint -restore */
|
||||
|
||||
#define INT_MAX 0xFFFFFFFF
|
||||
|
||||
#if (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LFCLK_RC) && !defined(SOFTDEVICE_PRESENT)
|
||||
#define CALIBRATION_SUPPORT 1
|
||||
#else
|
||||
#define CALIBRATION_SUPPORT 0
|
||||
#endif
|
||||
typedef enum
|
||||
{
|
||||
CAL_STATE_IDLE,
|
||||
CAL_STATE_CT,
|
||||
CAL_STATE_HFCLK_REQ,
|
||||
CAL_STATE_CAL,
|
||||
CAL_STATE_ABORT,
|
||||
} nrf_drv_clock_cal_state_t;
|
||||
|
||||
/**@brief CLOCK control block. */
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t hfclk_requests; /*< High-frequency clock request counter. */
|
||||
volatile nrf_drv_clock_handler_item_t * p_hf_head;
|
||||
bool module_initialized; /*< Indicate the state of module */
|
||||
volatile bool hfclk_on; /*< High-frequency clock state. */
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
volatile bool lfclk_on; /*< Low-frequency clock state. */
|
||||
uint32_t lfclk_requests; /*< Low-frequency clock request counter. */
|
||||
volatile nrf_drv_clock_handler_item_t * p_lf_head;
|
||||
#if CALIBRATION_SUPPORT
|
||||
nrf_drv_clock_handler_item_t cal_hfclk_started_handler_item;
|
||||
nrf_drv_clock_event_handler_t cal_done_handler;
|
||||
volatile nrf_drv_clock_cal_state_t cal_state;
|
||||
#endif //CALIBRATION_SUPPORT
|
||||
#endif //SOFTDEVICE_PRESENT
|
||||
}nrf_drv_clock_cb_t;
|
||||
|
||||
static nrf_drv_clock_cb_t m_clock_cb;
|
||||
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
/**@brief Function for starting LFCLK. This function will return immediately without waiting for start.
|
||||
*/
|
||||
static void lfclk_start(void)
|
||||
{
|
||||
nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED);
|
||||
nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK);
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
|
||||
}
|
||||
|
||||
/**@brief Function for stopping LFCLK and calibration (if it was set up).
|
||||
*/
|
||||
static void lfclk_stop(void)
|
||||
{
|
||||
#if CALIBRATION_SUPPORT
|
||||
(void)nrf_drv_clock_calibration_abort();
|
||||
#endif //CALIBRATION_SUPPORT
|
||||
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP);
|
||||
while (nrf_clock_lf_is_running())
|
||||
{}
|
||||
}
|
||||
#endif
|
||||
static void hfclk_start(void)
|
||||
{
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
|
||||
nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK);
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART);
|
||||
#else
|
||||
UNUSED_VARIABLE(sd_clock_hfclk_request());
|
||||
#endif
|
||||
}
|
||||
|
||||
static void hfclk_stop(void)
|
||||
{
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP);
|
||||
while (nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY))
|
||||
{}
|
||||
#else
|
||||
UNUSED_VARIABLE(sd_clock_hfclk_release());
|
||||
#endif
|
||||
}
|
||||
|
||||
ret_code_t nrf_drv_clock_init(void)
|
||||
{
|
||||
uint32_t result = NRF_SUCCESS;
|
||||
|
||||
if (m_clock_cb.module_initialized)
|
||||
{
|
||||
return MODULE_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
m_clock_cb.p_hf_head = NULL;
|
||||
m_clock_cb.hfclk_requests = 0;
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
m_clock_cb.p_lf_head = NULL;
|
||||
m_clock_cb.lfclk_requests = 0;
|
||||
nrf_clock_xtalfreq_set(CLOCK_CONFIG_XTAL_FREQ);
|
||||
nrf_clock_lf_src_set((nrf_clock_lfclk_t)CLOCK_CONFIG_LF_SRC);
|
||||
nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY);
|
||||
#if CALIBRATION_SUPPORT
|
||||
m_clock_cb.cal_state = CAL_STATE_IDLE;
|
||||
#endif // CALIBRATION_SUPPORT
|
||||
#else // SOFTDEVICE_PRESENT
|
||||
uint8_t is_enabled;
|
||||
result = sd_softdevice_is_enabled(&is_enabled);
|
||||
if((result == NRF_SUCCESS) && !is_enabled)
|
||||
{
|
||||
result = NRF_ERROR_SOFTDEVICE_NOT_ENABLED;
|
||||
}
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
m_clock_cb.module_initialized = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void nrf_drv_clock_uninit(void)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
nrf_drv_common_irq_disable(POWER_CLOCK_IRQn);
|
||||
nrf_clock_int_disable(0xFFFFFFFF);
|
||||
lfclk_stop();
|
||||
#endif
|
||||
hfclk_stop();
|
||||
m_clock_cb.module_initialized = false;
|
||||
}
|
||||
|
||||
static void item_enqueue(nrf_drv_clock_handler_item_t ** p_head,
|
||||
nrf_drv_clock_handler_item_t * p_item)
|
||||
{
|
||||
if (*p_head)
|
||||
{
|
||||
p_item->p_next = *p_head;
|
||||
*p_head = p_item;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_item->p_next = NULL;
|
||||
*p_head = p_item;
|
||||
}
|
||||
}
|
||||
|
||||
static nrf_drv_clock_handler_item_t * item_dequeue(nrf_drv_clock_handler_item_t ** p_head)
|
||||
{
|
||||
nrf_drv_clock_handler_item_t * p_item = *p_head;
|
||||
if (p_item)
|
||||
{
|
||||
*p_head = p_item->p_next;
|
||||
}
|
||||
|
||||
return p_item;
|
||||
}
|
||||
|
||||
void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
ASSERT(m_clock_cb.lfclk_requests != INT_MAX);
|
||||
CRITICAL_REGION_ENTER();
|
||||
if (m_clock_cb.lfclk_on)
|
||||
{
|
||||
if (p_handler_item)
|
||||
{
|
||||
p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (p_handler_item)
|
||||
{
|
||||
item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head, p_handler_item);
|
||||
}
|
||||
if (m_clock_cb.lfclk_requests == 0)
|
||||
{
|
||||
lfclk_start();
|
||||
}
|
||||
}
|
||||
m_clock_cb.lfclk_requests++;
|
||||
CRITICAL_REGION_EXIT();
|
||||
#else
|
||||
if (p_handler_item)
|
||||
{
|
||||
p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED);
|
||||
}
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
}
|
||||
|
||||
|
||||
void nrf_drv_clock_lfclk_release(void)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
ASSERT(m_clock_cb.lfclk_requests > 0);
|
||||
|
||||
CRITICAL_REGION_ENTER();
|
||||
m_clock_cb.lfclk_requests--;
|
||||
if (m_clock_cb.lfclk_requests == 0)
|
||||
{
|
||||
lfclk_stop();
|
||||
m_clock_cb.lfclk_on = false;
|
||||
m_clock_cb.p_lf_head = NULL;
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
}
|
||||
|
||||
|
||||
bool nrf_drv_clock_lfclk_is_running(void)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
bool result;
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
result = nrf_clock_lf_is_running();
|
||||
#else
|
||||
result = true;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
ASSERT(m_clock_cb.hfclk_requests != INT_MAX);
|
||||
|
||||
CRITICAL_REGION_ENTER();
|
||||
if (m_clock_cb.hfclk_on)
|
||||
{
|
||||
if (p_handler_item)
|
||||
{
|
||||
p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_HFCLK_STARTED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p_handler_item)
|
||||
{
|
||||
item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head, p_handler_item);
|
||||
}
|
||||
if (m_clock_cb.hfclk_requests == 0)
|
||||
{
|
||||
hfclk_start();
|
||||
}
|
||||
}
|
||||
m_clock_cb.hfclk_requests++;
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
|
||||
void nrf_drv_clock_hfclk_release(void)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
ASSERT(m_clock_cb.hfclk_requests > 0);
|
||||
|
||||
//disable interrupts CLOCK or SoftDevice events
|
||||
CRITICAL_REGION_ENTER();
|
||||
m_clock_cb.hfclk_requests--;
|
||||
if (m_clock_cb.hfclk_requests == 0)
|
||||
{
|
||||
hfclk_stop();
|
||||
m_clock_cb.hfclk_on = false;
|
||||
m_clock_cb.p_hf_head = NULL;
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
//enable interrupts CLOCK or SoftDevice events
|
||||
}
|
||||
|
||||
bool nrf_drv_clock_hfclk_is_running(void)
|
||||
{
|
||||
bool result;
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
result = nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY);
|
||||
#else
|
||||
uint32_t is_running;
|
||||
UNUSED_VARIABLE(sd_clock_hfclk_is_running(&is_running));
|
||||
result = is_running ? true : false;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#if CALIBRATION_SUPPORT
|
||||
static void clock_calibration_hf_started(nrf_drv_clock_evt_type_t event)
|
||||
{
|
||||
if (m_clock_cb.cal_state == CAL_STATE_ABORT)
|
||||
{
|
||||
nrf_drv_clock_hfclk_release();
|
||||
m_clock_cb.cal_state = CAL_STATE_IDLE;
|
||||
if (m_clock_cb.cal_done_handler)
|
||||
{
|
||||
m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf_clock_int_enable(NRF_CLOCK_INT_DONE_MASK);
|
||||
m_clock_cb.cal_state = CAL_STATE_CAL;
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_CAL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret_code_t nrf_drv_clock_calibration_start(uint8_t interval, nrf_drv_clock_event_handler_t handler)
|
||||
{
|
||||
#if CALIBRATION_SUPPORT
|
||||
ASSERT(m_clock_cb.cal_state == CAL_STATE_IDLE);
|
||||
ret_code_t ret = NRF_SUCCESS;
|
||||
if (m_clock_cb.lfclk_on == false)
|
||||
{
|
||||
ret = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
else if (m_clock_cb.cal_state == CAL_STATE_IDLE)
|
||||
{
|
||||
m_clock_cb.cal_done_handler = handler;
|
||||
m_clock_cb.cal_hfclk_started_handler_item.event_handler = clock_calibration_hf_started;
|
||||
if (interval == 0)
|
||||
{
|
||||
m_clock_cb.cal_state = CAL_STATE_HFCLK_REQ;
|
||||
nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clock_cb.cal_state = CAL_STATE_CT;
|
||||
nrf_clock_cal_timer_timeout_set(interval);
|
||||
nrf_clock_int_enable(NRF_CLOCK_INT_CTTO_MASK);
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTART);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NRF_ERROR_BUSY;
|
||||
}
|
||||
return ret;
|
||||
#else //CALIBRATION_SUPPORT
|
||||
return NRF_ERROR_FORBIDDEN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf_drv_clock_calibration_abort(void)
|
||||
{
|
||||
#if CALIBRATION_SUPPORT
|
||||
CRITICAL_REGION_ENTER();
|
||||
switch(m_clock_cb.cal_state)
|
||||
{
|
||||
case CAL_STATE_CT:
|
||||
nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK);
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTOP);
|
||||
m_clock_cb.cal_state = CAL_STATE_IDLE;
|
||||
if (m_clock_cb.cal_done_handler)
|
||||
{
|
||||
m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED);
|
||||
}
|
||||
break;
|
||||
case CAL_STATE_HFCLK_REQ:
|
||||
/* fall through. */
|
||||
case CAL_STATE_CAL:
|
||||
m_clock_cb.cal_state = CAL_STATE_ABORT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
return NRF_SUCCESS;
|
||||
#else //CALIBRATION_SUPPORT
|
||||
return NRF_ERROR_FORBIDDEN;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating)
|
||||
{
|
||||
#if CALIBRATION_SUPPORT
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
*p_is_calibrating = (m_clock_cb.cal_state != CAL_STATE_IDLE);
|
||||
return NRF_SUCCESS;
|
||||
#else //CALIBRATION_SUPPORT
|
||||
return NRF_ERROR_FORBIDDEN;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __INLINE void clock_clk_started_notify(nrf_drv_clock_handler_item_t **p_head,
|
||||
nrf_drv_clock_evt_type_t evt_type)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
nrf_drv_clock_handler_item_t * p_item = item_dequeue(p_head);
|
||||
if (p_item)
|
||||
{
|
||||
p_item->event_handler(evt_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
void POWER_CLOCK_IRQHandler(void)
|
||||
{
|
||||
if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED))
|
||||
{
|
||||
nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
|
||||
nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK);
|
||||
m_clock_cb.hfclk_on = true;
|
||||
clock_clk_started_notify((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head, NRF_DRV_CLOCK_EVT_HFCLK_STARTED);
|
||||
}
|
||||
if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED))
|
||||
{
|
||||
nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED);
|
||||
nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK);
|
||||
m_clock_cb.lfclk_on = true;
|
||||
clock_clk_started_notify((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head, NRF_DRV_CLOCK_EVT_LFCLK_STARTED);
|
||||
}
|
||||
#if CALIBRATION_SUPPORT
|
||||
if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO))
|
||||
{
|
||||
nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO);
|
||||
nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK);
|
||||
nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item);
|
||||
}
|
||||
|
||||
if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE))
|
||||
{
|
||||
nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE);
|
||||
nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK);
|
||||
|
||||
nrf_drv_clock_hfclk_release();
|
||||
nrf_drv_clock_evt_type_t evt_type = (m_clock_cb.cal_state == CAL_STATE_ABORT) ?
|
||||
NRF_DRV_CLOCK_EVT_CAL_ABORTED : NRF_DRV_CLOCK_EVT_CAL_DONE;
|
||||
m_clock_cb.cal_state = CAL_STATE_IDLE;
|
||||
if (m_clock_cb.cal_done_handler)
|
||||
{
|
||||
m_clock_cb.cal_done_handler(evt_type);
|
||||
}
|
||||
}
|
||||
#endif //CALIBRATION_SUPPORT
|
||||
}
|
||||
#else
|
||||
void nrf_drv_clock_on_soc_event(uint32_t evt_id)
|
||||
{
|
||||
if (evt_id == NRF_EVT_HFCLKSTARTED)
|
||||
{
|
||||
clock_clk_started_notify((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head, NRF_DRV_CLOCK_EVT_HFCLK_STARTED);
|
||||
}
|
||||
}
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
#undef NRF_CLOCK_LFCLK_RC
|
||||
#undef NRF_CLOCK_LFCLK_Xtal
|
||||
#undef NRF_CLOCK_LFCLK_Synth
|
|
@ -0,0 +1,246 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NRF_DRV_CLOCK_H__
|
||||
#define NRF_DRV_CLOCK_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "sdk_errors.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nrf_clock.h"
|
||||
#include "nrf_drv_config.h"
|
||||
#include "nrf_drv_common.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* @addtogroup nrf_clock Clock HAL and driver
|
||||
* @ingroup nrf_drivers
|
||||
* @brief Clock APIs.
|
||||
* @details The clock HAL provides basic APIs for accessing the registers of the clock.
|
||||
* The clock driver provides APIs on a higher level.
|
||||
*
|
||||
* @defgroup nrf_clock_drv Clock driver
|
||||
* @{
|
||||
* @ingroup nrf_clock
|
||||
* @brief Driver for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK).
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Clock events.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started.
|
||||
NRF_DRV_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started.
|
||||
NRF_DRV_CLOCK_EVT_CAL_DONE, ///< Calibration is done.
|
||||
NRF_DRV_CLOCK_EVT_CAL_ABORTED, ///< Calibration has been aborted.
|
||||
} nrf_drv_clock_evt_type_t;
|
||||
|
||||
/**
|
||||
* @brief Clock event handler.
|
||||
*
|
||||
* @param[in] event Event.
|
||||
*/
|
||||
typedef void (*nrf_drv_clock_event_handler_t)(nrf_drv_clock_evt_type_t event);
|
||||
|
||||
// Forward declaration of the nrf_drv_clock_handler_item_t type.
|
||||
typedef struct nrf_drv_clock_handler_item_s nrf_drv_clock_handler_item_t;
|
||||
|
||||
struct nrf_drv_clock_handler_item_s
|
||||
{
|
||||
nrf_drv_clock_handler_item_t * p_next; ///< A pointer to the next handler that should be called when the clock is started.
|
||||
nrf_drv_clock_event_handler_t event_handler; ///< Function to be called when the clock is started.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Function for initializing the nrf_drv_clock module.
|
||||
*
|
||||
* After initialization, the module is in power off state (clocks are not requested).
|
||||
*
|
||||
* @retval NRF_SUCCESS If the procedure was successful.
|
||||
* @retval MODULE_ALREADY_INITIALIZED If the driver was already initialized.
|
||||
* @retval NRF_ERROR_SOFTDEVICE_NOT_ENABLED If the SoftDevice was not enabled.
|
||||
*/
|
||||
ret_code_t nrf_drv_clock_init(void);
|
||||
|
||||
/**
|
||||
* @brief Function for uninitializing the clock module.
|
||||
*
|
||||
*/
|
||||
void nrf_drv_clock_uninit(void);
|
||||
|
||||
/**
|
||||
* @brief Function for requesting the LFCLK.
|
||||
*
|
||||
* The low-frequency clock can be requested by different modules
|
||||
* or contexts. The driver ensures that the clock will be started only when it is requested
|
||||
* the first time. If the clock is not ready but it was already started, the handler item that is
|
||||
* provided as an input parameter is added to the list of handlers that will be notified
|
||||
* when the clock is started. If the clock is already enabled, user callback is called from the
|
||||
* current context.
|
||||
*
|
||||
* The first request will start the selected LFCLK source. If an event handler is
|
||||
* provided, it will be called once the LFCLK is started. If the LFCLK was already started at this
|
||||
* time, the event handler will be called from the context of this function. Additionally,
|
||||
* the @ref nrf_drv_clock_lfclk_is_running function can be polled to check if the clock has started.
|
||||
*
|
||||
* @note When a SoftDevice is enabled, the LFCLK is always running and the driver cannot control it.
|
||||
*
|
||||
* @note The handler item provided by the user cannot be an automatic variable.
|
||||
*
|
||||
* @param[in] p_handler_item A pointer to the event handler structure.
|
||||
*/
|
||||
void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item);
|
||||
|
||||
/**
|
||||
* @brief Function for releasing the LFCLK.
|
||||
*
|
||||
* If there are no more requests, the LFCLK source will be stopped.
|
||||
*
|
||||
* @note When a SoftDevice is enabled, the LFCLK is always running.
|
||||
*/
|
||||
void nrf_drv_clock_lfclk_release(void);
|
||||
|
||||
/**
|
||||
* @brief Function for checking the LFCLK state.
|
||||
*
|
||||
* @retval true If the LFCLK is running.
|
||||
* @retval false If the LFCLK is not running.
|
||||
*/
|
||||
bool nrf_drv_clock_lfclk_is_running(void);
|
||||
|
||||
/**
|
||||
* @brief Function for requesting the high-accuracy source HFCLK.
|
||||
*
|
||||
* The high-accuracy source
|
||||
* can be requested by different modules or contexts. The driver ensures that the high-accuracy
|
||||
* clock will be started only when it is requested the first time. If the clock is not ready
|
||||
* but it was already started, the handler item that is provided as an input parameter is added
|
||||
* to the list of handlers that will be notified when the clock is started.
|
||||
*
|
||||
* If an event handler is provided, it will be called once the clock is started. If the clock was already
|
||||
* started at this time, the event handler will be called from the context of this function. Additionally,
|
||||
* the @ref nrf_drv_clock_hfclk_is_running function can be polled to check if the clock has started.
|
||||
*
|
||||
* @note If a SoftDevice is running, the clock is managed by the SoftDevice and all requests are handled by
|
||||
* the SoftDevice. This function cannot be called from all interrupt priority levels in that case.
|
||||
* @note The handler item provided by the user cannot be an automatic variable.
|
||||
*
|
||||
* @param[in] p_handler_item A pointer to the event handler structure.
|
||||
*/
|
||||
void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item);
|
||||
|
||||
/**
|
||||
* @brief Function for releasing the high-accuracy source HFCLK.
|
||||
*
|
||||
* If there are no more requests, the high-accuracy source will be released.
|
||||
*/
|
||||
void nrf_drv_clock_hfclk_release(void);
|
||||
|
||||
/**
|
||||
* @brief Function for checking the HFCLK state.
|
||||
*
|
||||
* @retval true If the HFCLK is running (for \nRFXX XTAL source).
|
||||
* @retval false If the HFCLK is not running.
|
||||
*/
|
||||
bool nrf_drv_clock_hfclk_is_running(void);
|
||||
|
||||
/**
|
||||
* @brief Function for starting a single calibration process.
|
||||
*
|
||||
* This function can also delay the start of calibration by a user-specified value. The delay will use
|
||||
* a low-power timer that is part of the CLOCK module. @ref nrf_drv_clock_is_calibrating can be called to
|
||||
* check if calibration is still in progress. If a handler is provided, the user can be notified when
|
||||
* calibration is completed. The ext calibration can be started from the handler context.
|
||||
*
|
||||
* The calibration process consists of three phases:
|
||||
* - Delay (optional)
|
||||
* - Requesting the high-accuracy HFCLK
|
||||
* - Hardware-supported calibration
|
||||
*
|
||||
* @param[in] delay Time after which the calibration will be started (in 0.25 s units).
|
||||
* @param[in] handler NULL or user function to be called when calibration is completed or aborted.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the procedure was successful.
|
||||
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
|
||||
* @retval NRF_ERROR_INVALID_STATE If the low-frequency clock is off.
|
||||
* @retval NRF_ERROR_BUSY If calibration is in progress.
|
||||
*/
|
||||
ret_code_t nrf_drv_clock_calibration_start(uint8_t delay, nrf_drv_clock_event_handler_t handler);
|
||||
|
||||
/**
|
||||
* @brief Function for aborting calibration.
|
||||
*
|
||||
* This function aborts on-going calibration. If calibration was started, it cannot be stopped. If a handler
|
||||
* was provided by @ref nrf_drv_clock_calibration_start, this handler will be called once
|
||||
* aborted calibration is completed. @ref nrf_drv_clock_is_calibrating can also be used to check
|
||||
* if the system is calibrating.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the procedure was successful.
|
||||
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
|
||||
*/
|
||||
ret_code_t nrf_drv_clock_calibration_abort(void);
|
||||
|
||||
/**
|
||||
* @brief Function for checking if calibration is in progress.
|
||||
*
|
||||
* This function indicates that the system is
|
||||
* in calibration if it is in any of the calibration process phases (see @ref nrf_drv_clock_calibration_start).
|
||||
*
|
||||
* @param[out] p_is_calibrating True if calibration is in progress, false if not.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the procedure was successful.
|
||||
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
|
||||
*/
|
||||
ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating);
|
||||
|
||||
/**@brief Function for returning a requested task address for the clock driver module.
|
||||
*
|
||||
* @param[in] task One of the peripheral tasks.
|
||||
*
|
||||
* @return Task address.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task);
|
||||
|
||||
/**@brief Function for returning a requested event address for the clock driver module.
|
||||
*
|
||||
* @param[in] event One of the peripheral events.
|
||||
*
|
||||
* @return Event address.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event);
|
||||
|
||||
/**
|
||||
* @brief Function called by the SoftDevice handler if an @ref nrf_soc event is received from the SoftDevice.
|
||||
*/
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
void nrf_drv_clock_on_soc_event(uint32_t evt_id);
|
||||
#endif
|
||||
/**
|
||||
*@}
|
||||
**/
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task)
|
||||
{
|
||||
return nrf_clock_task_address_get(task);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event)
|
||||
{
|
||||
return nrf_clock_event_address_get(event);
|
||||
}
|
||||
#endif //SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
/*lint --flb "Leave library region" */
|
||||
#endif // NRF_CLOCK_H__
|
|
@ -0,0 +1,208 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "nrf_drv_common.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "app_util_platform.h"
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#include "nrf_soc.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
|
||||
typedef struct {
|
||||
nrf_drv_irq_handler_t handler;
|
||||
bool acquired;
|
||||
} shared_resource_t;
|
||||
|
||||
// SPIM0, SPIS0, SPI0, TWIM0, TWIS0, TWI0
|
||||
#if (SPI0_ENABLED || SPIS0_ENABLED || TWI0_ENABLED || TWIS0_ENABLED)
|
||||
#define SERIAL_BOX_0_IN_USE
|
||||
// [this checking may need a different form in unit tests, hence macro]
|
||||
#ifndef IS_SERIAL_BOX_0
|
||||
#define IS_SERIAL_BOX_0(p_per_base) (p_per_base == NRF_SPI0)
|
||||
#endif
|
||||
|
||||
static shared_resource_t m_serial_box_0 = { .acquired = false };
|
||||
void SPI0_TWI0_IRQHandler(void)
|
||||
{
|
||||
ASSERT(m_serial_box_0.handler);
|
||||
m_serial_box_0.handler();
|
||||
}
|
||||
#endif // (SPI0_ENABLED || SPIS0_ENABLED || TWI0_ENABLED || TWIS0_ENABLED)
|
||||
|
||||
// SPIM1, SPIS1, SPI1, TWIM1, TWIS1, TWI1
|
||||
#if (SPI1_ENABLED || SPIS1_ENABLED || TWI1_ENABLED || TWIS1_ENABLED)
|
||||
#define SERIAL_BOX_1_IN_USE
|
||||
// [this checking may need a different form in unit tests, hence macro]
|
||||
#ifndef IS_SERIAL_BOX_1
|
||||
#define IS_SERIAL_BOX_1(p_per_base) (p_per_base == NRF_SPI1)
|
||||
#endif
|
||||
|
||||
static shared_resource_t m_serial_box_1 = { .acquired = false };
|
||||
void SPI1_TWI1_IRQHandler(void)
|
||||
{
|
||||
ASSERT(m_serial_box_1.handler);
|
||||
m_serial_box_1.handler();
|
||||
}
|
||||
#endif // (SPI1_ENABLED || SPIS1_ENABLED || TWI1_ENABLED || TWIS1_ENABLED)
|
||||
|
||||
// SPIM2, SPIS2, SPI2
|
||||
#if (SPI2_ENABLED || SPIS2_ENABLED)
|
||||
#define SERIAL_BOX_2_IN_USE
|
||||
// [this checking may need a different form in unit tests, hence macro]
|
||||
#ifndef IS_SERIAL_BOX_2
|
||||
#define IS_SERIAL_BOX_2(p_per_base) (p_per_base == NRF_SPI2)
|
||||
#endif
|
||||
|
||||
static shared_resource_t m_serial_box_2 = { .acquired = false };
|
||||
void SPIM2_SPIS2_SPI2_IRQHandler(void)
|
||||
{
|
||||
ASSERT(m_serial_box_2.handler);
|
||||
m_serial_box_2.handler();
|
||||
}
|
||||
#endif // (SPI2_ENABLED || SPIS2_ENABLED)
|
||||
|
||||
// COMP, LPCOMP
|
||||
#if (COMP_ENABLED || LPCOMP_ENABLED)
|
||||
#define COMP_LPCOMP_IN_USE
|
||||
|
||||
#ifndef IS_COMP_LPCOMP
|
||||
#define IS_COMP_LPCOMP(p_per_base) ((p_per_base) == NRF_LPCOMP)
|
||||
#endif
|
||||
|
||||
static shared_resource_t m_comp_lpcomp = { .acquired = false };
|
||||
void LPCOMP_IRQHandler(void)
|
||||
{
|
||||
ASSERT(m_comp_lpcomp.handler);
|
||||
m_comp_lpcomp.handler();
|
||||
}
|
||||
#endif // (COMP_ENABLED || LPCOMP_ENABLED)
|
||||
|
||||
#if defined(SERIAL_BOX_0_IN_USE) || \
|
||||
defined(SERIAL_BOX_1_IN_USE) || \
|
||||
defined(SERIAL_BOX_2_IN_USE) || \
|
||||
defined(COMP_LPCOMP_IN_USE)
|
||||
static ret_code_t acquire_shared_resource(shared_resource_t * p_resource,
|
||||
nrf_drv_irq_handler_t handler)
|
||||
{
|
||||
bool busy = false;
|
||||
|
||||
CRITICAL_REGION_ENTER();
|
||||
if (p_resource->acquired)
|
||||
{
|
||||
busy = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_resource->acquired = true;
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
if (busy)
|
||||
{
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
p_resource->handler = handler;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base,
|
||||
nrf_drv_irq_handler_t handler)
|
||||
{
|
||||
#ifdef SERIAL_BOX_0_IN_USE
|
||||
if (IS_SERIAL_BOX_0(p_per_base))
|
||||
{
|
||||
return acquire_shared_resource(&m_serial_box_0, handler);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_BOX_1_IN_USE
|
||||
if (IS_SERIAL_BOX_1(p_per_base))
|
||||
{
|
||||
return acquire_shared_resource(&m_serial_box_1, handler);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_BOX_2_IN_USE
|
||||
if (IS_SERIAL_BOX_2(p_per_base))
|
||||
{
|
||||
return acquire_shared_resource(&m_serial_box_2, handler);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMP_LPCOMP_IN_USE
|
||||
if (IS_COMP_LPCOMP(p_per_base))
|
||||
{
|
||||
return acquire_shared_resource(&m_comp_lpcomp, handler);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
void nrf_drv_common_per_res_release(void const * p_per_base)
|
||||
{
|
||||
#ifdef SERIAL_BOX_0_IN_USE
|
||||
if (IS_SERIAL_BOX_0(p_per_base))
|
||||
{
|
||||
m_serial_box_0.acquired = false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_BOX_1_IN_USE
|
||||
if (IS_SERIAL_BOX_1(p_per_base))
|
||||
{
|
||||
m_serial_box_1.acquired = false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_BOX_2_IN_USE
|
||||
if (IS_SERIAL_BOX_2(p_per_base))
|
||||
{
|
||||
m_serial_box_2.acquired = false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifdef COMP_LPCOMP_IN_USE
|
||||
if (IS_COMP_LPCOMP(p_per_base))
|
||||
{
|
||||
m_comp_lpcomp.acquired = false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
{}
|
||||
}
|
||||
|
||||
#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
|
||||
|
||||
void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority)
|
||||
{
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
ASSERT((priority == APP_IRQ_PRIORITY_LOW) || (priority == APP_IRQ_PRIORITY_HIGH));
|
||||
#endif
|
||||
|
||||
NVIC_SetPriority(IRQn, priority);
|
||||
NVIC_ClearPendingIRQ(IRQn);
|
||||
NVIC_EnableIRQ(IRQn);
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NRF_DRV_COMMON_H__
|
||||
#define NRF_DRV_COMMON_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf.h"
|
||||
#include "sdk_errors.h"
|
||||
#include "nrf_drv_config.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Offset of event registers in every peripheral instance
|
||||
*
|
||||
* This is the offset where event registers start in the every peripheral.
|
||||
*/
|
||||
#define NRF_DRV_COMMON_EVREGS_OFFSET 0x100U
|
||||
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_STATE_UNINITIALIZED, /**< Uninitialized. */
|
||||
NRF_DRV_STATE_INITIALIZED, /**< Initialized but powered off. */
|
||||
NRF_DRV_STATE_POWERED_ON
|
||||
} nrf_drv_state_t;
|
||||
|
||||
/**
|
||||
* @brief Driver power state selection.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_PWR_CTRL_ON, /**< Power on request. */
|
||||
NRF_DRV_PWR_CTRL_OFF /**< Power off request. */
|
||||
} nrf_drv_pwr_ctrl_t;
|
||||
|
||||
/**
|
||||
* @brief IRQ handler type.
|
||||
*/
|
||||
typedef void (*nrf_drv_irq_handler_t)(void);
|
||||
|
||||
|
||||
#if PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
|
||||
/**
|
||||
* @brief Function for acquiring shared peripheral resources associated with
|
||||
* the specified peripheral.
|
||||
*
|
||||
* Certain resources and registers are shared among peripherals that have
|
||||
* the same ID (for example: SPI0, SPIM0, SPIS0, TWI0, TWIM0, and TWIS0).
|
||||
* Only one of them can be utilized at a given time. This function reserves
|
||||
* proper resources to be used by the specified peripheral.
|
||||
* If PERIPHERAL_RESOURCE_SHARING_ENABLED is set to a non-zero value, IRQ
|
||||
* handlers for peripherals that are sharing resources with others are
|
||||
* implemented by the nrf_drv_common module instead of individual drivers.
|
||||
* The drivers must then specify their interrupt handling routines and
|
||||
* register them by using this function.
|
||||
*
|
||||
* @param[in] p_per_base Requested peripheral base pointer.
|
||||
* @param[in] handler Interrupt handler to register. May be NULL
|
||||
* if interrupts are not used for the peripheral.
|
||||
*
|
||||
* @retval NRF_SUCCESS If resources were acquired successfully.
|
||||
* @retval NRF_ERROR_BUSY If resources were already acquired.
|
||||
* @retval NRF_ERROR_INVALID_PARAM If the specified peripheral is not enabled
|
||||
* or the peripheral does not share resources
|
||||
* with other peripherals.
|
||||
*/
|
||||
ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base,
|
||||
nrf_drv_irq_handler_t handler);
|
||||
|
||||
/**
|
||||
* @brief Function for releasing shared resources reserved previously by
|
||||
* @ref nrf_drv_common_per_res_acquire() for the specified peripheral.
|
||||
*
|
||||
* @param[in] p_per_base Requested peripheral base pointer.
|
||||
*/
|
||||
void nrf_drv_common_per_res_release(void const * p_per_base);
|
||||
|
||||
#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function sets priority and enables NVIC interrupt
|
||||
*
|
||||
* @note Function checks if correct priority is used when softdevice is present
|
||||
*
|
||||
* @param[in] IRQn Interrupt id
|
||||
* @param[in] priority Interrupt priority
|
||||
*/
|
||||
void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority);
|
||||
|
||||
/**
|
||||
* @brief Function disables NVIC interrupt
|
||||
*
|
||||
* @param[in] IRQn Interrupt id
|
||||
*/
|
||||
__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn);
|
||||
|
||||
/**
|
||||
* @brief Convert bit position to event code
|
||||
*
|
||||
* Function for converting the bit position in INTEN register to event code
|
||||
* that is equivalent to the offset of the event register from the beginning
|
||||
* of peripheral instance.
|
||||
*
|
||||
* For example the result of this function can be casted directly to
|
||||
* the types like @ref nrf_twis_event_t or @ref nrf_rng_events_t...
|
||||
*
|
||||
* @param bit Bit position in INTEN register
|
||||
* @return Event code to be casted to the right enum type or to be used in functions like
|
||||
* @ref nrf_rng_event_get
|
||||
*
|
||||
* @sa nrf_drv_event_to_bitpos
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit);
|
||||
|
||||
/**
|
||||
* @brief Convert event code to bit position
|
||||
*
|
||||
* This function can be used to get bit position in INTEN register from event code.
|
||||
*
|
||||
* @param event Event code that may be casted from enum values from types like
|
||||
* @ref nrf_twis_event_t or @ref nrf_rng_events_t
|
||||
* @return Bit position in INTEN register that corresponds to the given code.
|
||||
*
|
||||
* @sa nrf_drv_bitpos_to_event
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event);
|
||||
|
||||
/**
|
||||
* @brief Get interrupt number connected with given instance
|
||||
*
|
||||
* Function returns interrupt number for a given instance of any peripheral.
|
||||
* @param[in] pinst Pointer to peripheral registry
|
||||
* @return Interrupt number
|
||||
*/
|
||||
__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst);
|
||||
|
||||
/**
|
||||
* @brief Check if given object is in RAM
|
||||
*
|
||||
* Function for analyzing if given location is placed in RAM.
|
||||
* This function is used to determine if we have address that can be supported by EasyDMA.
|
||||
* @param[in] ptr Pointer to the object
|
||||
* @retval true Object is located in RAM
|
||||
* @retval false Object is not located in RAM
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr);
|
||||
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC_DisableIRQ(IRQn);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit)
|
||||
{
|
||||
return NRF_DRV_COMMON_EVREGS_OFFSET + bit * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event)
|
||||
{
|
||||
return (event - NRF_DRV_COMMON_EVREGS_OFFSET) / sizeof(uint32_t);
|
||||
}
|
||||
|
||||
__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst)
|
||||
{
|
||||
uint8_t ret = (uint8_t)((uint32_t)pinst>>12U);
|
||||
return (IRQn_Type) ret;
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr)
|
||||
{
|
||||
return ((((uintptr_t)ptr) & 0xE0000000u) == 0x20000000u);
|
||||
}
|
||||
|
||||
#endif // SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
#endif // NRF_DRV_COMMON_H__
|
|
@ -0,0 +1,414 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NRF_CLOCK_H__
|
||||
#define NRF_CLOCK_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "nrf.h"
|
||||
|
||||
/**
|
||||
* @defgroup nrf_clock_hal Clock HAL
|
||||
* @{
|
||||
* @ingroup nrf_clock
|
||||
* @brief Hardware access layer for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK).
|
||||
*/
|
||||
|
||||
#define NRF_CLOCK_TASK_TRIGGER (1UL)
|
||||
#define NRF_CLOCK_EVENT_CLEAR (0UL)
|
||||
|
||||
/**
|
||||
* @brief Low-frequency clock sources.
|
||||
* @details Used by LFCLKSRC, LFCLKSTAT, and LFCLKSRCCOPY registers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */
|
||||
NRF_CLOCK_LFCLK_Xtal = CLOCK_LFCLKSRC_SRC_Xtal, /**< External 32 kHz crystal. */
|
||||
NRF_CLOCK_LFCLK_Synth = CLOCK_LFCLKSRC_SRC_Synth /**< Internal 32 kHz synthesizer from HFCLK system clock. */
|
||||
} nrf_clock_lfclk_t;
|
||||
|
||||
/**
|
||||
* @brief High-frequency clock sources.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */
|
||||
NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */
|
||||
} nrf_clock_hfclk_t;
|
||||
|
||||
/**
|
||||
* @brief Trigger status of task LFCLKSTART/HFCLKSTART.
|
||||
* @details Used by LFCLKRUN and HFCLKRUN registers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_CLOCK_START_TASK_NOT_TRIGGERED = CLOCK_LFCLKRUN_STATUS_NotTriggered, /**< Task LFCLKSTART/HFCLKSTART has not been triggered. */
|
||||
NRF_CLOCK_START_TASK_TRIGGERED = CLOCK_LFCLKRUN_STATUS_Triggered /**< Task LFCLKSTART/HFCLKSTART has been triggered. */
|
||||
} nrf_clock_start_task_status_t;
|
||||
|
||||
/**
|
||||
* @brief Crystal frequency selection.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
#ifdef NRF51
|
||||
NRF_CLOCK_XTALFREQ_Default = CLOCK_XTALFREQ_XTALFREQ_16MHz, /**< Default. 32 MHz. */
|
||||
NRF_CLOCK_XTALFREQ_16MHz = CLOCK_XTALFREQ_XTALFREQ_16MHz, /**< 16 MHz crystal. */
|
||||
NRF_CLOCK_XTALFREQ_32MHz = CLOCK_XTALFREQ_XTALFREQ_32MHz /**< 32 MHz crystal. */
|
||||
#elif defined NRF52
|
||||
NRF_CLOCK_XTALFREQ_Default, /**< Default. 64MHz. */
|
||||
#endif
|
||||
} nrf_clock_xtalfreq_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupts.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_CLOCK_INT_HF_STARTED_MASK = CLOCK_INTENSET_HFCLKSTARTED_Msk, /**< Interrupt on HFCLKSTARTED event. */
|
||||
NRF_CLOCK_INT_LF_STARTED_MASK = CLOCK_INTENSET_LFCLKSTARTED_Msk, /**< Interrupt on LFCLKSTARTED event. */
|
||||
NRF_CLOCK_INT_DONE_MASK = CLOCK_INTENSET_DONE_Msk, /**< Interrupt on DONE event. */
|
||||
NRF_CLOCK_INT_CTTO_MASK = CLOCK_INTENSET_CTTO_Msk /**< Interrupt on CTTO event. */
|
||||
} nrf_clock_int_mask_t;
|
||||
|
||||
/**
|
||||
* @brief Tasks.
|
||||
*
|
||||
* @details The NRF_CLOCK_TASK_LFCLKSTOP task cannot be set when the low-frequency clock is not running.
|
||||
* The NRF_CLOCK_TASK_HFCLKSTOP task cannot be set when the high-frequency clock is not running.
|
||||
*/
|
||||
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
|
||||
{
|
||||
NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /**< Start HFCLK clock source.*/
|
||||
NRF_CLOCK_TASK_HFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTOP), /**< Stop HFCLK clock source.*/
|
||||
NRF_CLOCK_TASK_LFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTART), /**< Start LFCLK clock source.*/
|
||||
NRF_CLOCK_TASK_LFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTOP), /**< Stop LFCLK clock source.*/
|
||||
NRF_CLOCK_TASK_CAL = offsetof(NRF_CLOCK_Type, TASKS_CAL), /**< Start calibration of LFCLK RC oscillator.*/
|
||||
NRF_CLOCK_TASK_CTSTART = offsetof(NRF_CLOCK_Type, TASKS_CTSTART), /**< Start calibration timer.*/
|
||||
NRF_CLOCK_TASK_CTSTOP = offsetof(NRF_CLOCK_Type, TASKS_CTSTOP) /**< Stop calibration timer.*/
|
||||
} nrf_clock_task_t; /*lint -restore */
|
||||
|
||||
/**
|
||||
* @brief Events.
|
||||
*/
|
||||
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
|
||||
{
|
||||
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_DONE = offsetof(NRF_CLOCK_Type, EVENTS_DONE), /**< Calibration of LFCLK RC oscillator completed.*/
|
||||
NRF_CLOCK_EVENT_CTTO = offsetof(NRF_CLOCK_Type, EVENTS_CTTO) /**< Calibration timer time-out.*/
|
||||
} nrf_clock_event_t; /*lint -restore */
|
||||
|
||||
/**
|
||||
* @brief Function for enabling a specific interrupt.
|
||||
*
|
||||
* @param[in] int_mask Interrupt.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask);
|
||||
|
||||
/**
|
||||
* @brief Function for disabling a specific interrupt.
|
||||
*
|
||||
* @param[in] int_mask Interrupt.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the state of a specific interrupt.
|
||||
*
|
||||
* @param[in] int_mask Interrupt.
|
||||
*
|
||||
* @retval true If the interrupt is enabled.
|
||||
* @retval false If the interrupt is not enabled.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the address of a specific task.
|
||||
* @details This function can be used by the PPI module.
|
||||
*
|
||||
* @param[in] task Task.
|
||||
*
|
||||
* @return Address of the requested task register.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task);
|
||||
|
||||
/**
|
||||
* @brief Function for setting a specific task.
|
||||
*
|
||||
* @param[in] task Task.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the address of a specific event.
|
||||
* @details This function can be used by the PPI module.
|
||||
*
|
||||
* @param[in] event Event.
|
||||
*
|
||||
* @return Address of the requested event register.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event);
|
||||
|
||||
/**
|
||||
* @brief Function for clearing a specific event.
|
||||
*
|
||||
* @param[in] event Event.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the state of a specific event.
|
||||
*
|
||||
* @param[in] event Event.
|
||||
*
|
||||
* @retval true If the event is set.
|
||||
* @retval false If the event is not set.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event);
|
||||
|
||||
/**
|
||||
* @brief Function for changing the low-frequency clock source.
|
||||
* @details This function cannot be called when the low-frequency clock is running.
|
||||
*
|
||||
* @param[in] source New low-frequency clock source.
|
||||
*
|
||||
*/
|
||||
__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the selected source for the low-frequency clock.
|
||||
*
|
||||
* @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the selected source for the low-frequency clock.
|
||||
* @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the selected source for the low-frequency clock.
|
||||
* @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the selected source for the low-frequency clock.
|
||||
*/
|
||||
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the active source of the low-frequency clock.
|
||||
*
|
||||
* @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the active source of the low-frequency clock.
|
||||
* @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the active source of the low-frequency clock.
|
||||
* @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the active source of the low-frequency clock.
|
||||
*/
|
||||
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the clock source for the LFCLK clock when the task LKCLKSTART is triggered.
|
||||
*
|
||||
* @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is running and generating the LFCLK clock.
|
||||
* @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is running and generating the LFCLK clock.
|
||||
* @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is running and generating the LFCLK clock.
|
||||
*/
|
||||
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the state of the LFCLK clock.
|
||||
*
|
||||
* @retval false If the LFCLK clock is not running.
|
||||
* @retval true If the LFCLK clock is running.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_clock_lf_is_running(void);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the trigger status of the task LFCLKSTART.
|
||||
*
|
||||
* @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task LFCLKSTART has not been triggered.
|
||||
* @retval NRF_CLOCK_START_TASK_TRIGGERED If the task LFCLKSTART has been triggered.
|
||||
*/
|
||||
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the active source of the high-frequency clock.
|
||||
*
|
||||
* @retval NRF_CLOCK_HFCLK_LOW_ACCURACY If the internal 16 MHz RC oscillator is the active source of the high-frequency clock.
|
||||
* @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY If an external 16 MHz/32 MHz crystal oscillator is the active source of the high-frequency clock.
|
||||
*/
|
||||
__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the state of the HFCLK clock.
|
||||
*
|
||||
* @param[in] clk_src Clock source to be checked.
|
||||
*
|
||||
* @retval false If the HFCLK clock is not running.
|
||||
* @retval true If the HFCLK clock is running.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the trigger status of the task HFCLKSTART.
|
||||
*
|
||||
* @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task HFCLKSTART has not been triggered.
|
||||
* @retval NRF_CLOCK_START_TASK_TRIGGERED If the task HFCLKSTART has been triggered.
|
||||
*/
|
||||
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the frequency selection of the external crystal.
|
||||
*
|
||||
* @retval NRF_CLOCK_XTALFREQ_16MHz If a 16 MHz crystal is used as source for the HFCLK oscillator.
|
||||
* @retval NRF_CLOCK_XTALFREQ_32MHz If a 32 MHz crystal is used as source for the HFCLK oscillator.
|
||||
*/
|
||||
__STATIC_INLINE nrf_clock_xtalfreq_t nrf_clock_xtalfreq_get(void);
|
||||
|
||||
/**
|
||||
* @brief Function for changing the frequency selection of the external crystal.
|
||||
*
|
||||
* @param[in] xtalfreq New frequency selection for the external crystal.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_clock_xtalfreq_set(nrf_clock_xtalfreq_t xtalfreq);
|
||||
|
||||
/**
|
||||
* @brief Function for changing the calibration timer interval.
|
||||
*
|
||||
* @param[in] interval New calibration timer interval in 0.25 s resolution (range: 0.25 seconds to 31.75 seconds).
|
||||
*/
|
||||
__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval);
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask)
|
||||
{
|
||||
NRF_CLOCK->INTENSET = int_mask;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask)
|
||||
{
|
||||
NRF_CLOCK->INTENCLR = int_mask;
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask)
|
||||
{
|
||||
return (bool)(NRF_CLOCK->INTENCLR & int_mask);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task)
|
||||
{
|
||||
return ((uint32_t )NRF_CLOCK + task);
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task)
|
||||
{
|
||||
*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + task)) = NRF_CLOCK_TASK_TRIGGER;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event)
|
||||
{
|
||||
return ((uint32_t)NRF_CLOCK + event);
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event)
|
||||
{
|
||||
*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)) = NRF_CLOCK_EVENT_CLEAR;
|
||||
#if __CORTEX_M == 0x04
|
||||
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event));
|
||||
(void)dummy;
|
||||
#endif
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event)
|
||||
{
|
||||
return (bool)*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event));
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source)
|
||||
{
|
||||
NRF_CLOCK->LFCLKSRC =
|
||||
(uint32_t)((source << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
|
||||
}
|
||||
|
||||
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void)
|
||||
{
|
||||
return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRC &
|
||||
CLOCK_LFCLKSRC_SRC_Msk) >> CLOCK_LFCLKSRC_SRC_Pos);
|
||||
}
|
||||
|
||||
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void)
|
||||
{
|
||||
return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSTAT &
|
||||
CLOCK_LFCLKSTAT_SRC_Msk) >> CLOCK_LFCLKSTAT_SRC_Pos);
|
||||
}
|
||||
|
||||
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void)
|
||||
{
|
||||
return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRCCOPY &
|
||||
CLOCK_LFCLKSRCCOPY_SRC_Msk) >> CLOCK_LFCLKSRCCOPY_SRC_Pos);
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool nrf_clock_lf_is_running(void)
|
||||
{
|
||||
return ((NRF_CLOCK->LFCLKSTAT &
|
||||
CLOCK_LFCLKSTAT_STATE_Msk) >> CLOCK_LFCLKSTAT_STATE_Pos);
|
||||
}
|
||||
|
||||
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void)
|
||||
{
|
||||
return (nrf_clock_start_task_status_t)((NRF_CLOCK->LFCLKRUN &
|
||||
CLOCK_LFCLKRUN_STATUS_Msk) >>
|
||||
CLOCK_LFCLKRUN_STATUS_Pos);
|
||||
}
|
||||
|
||||
__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void)
|
||||
{
|
||||
return (nrf_clock_hfclk_t)((NRF_CLOCK->HFCLKSTAT &
|
||||
CLOCK_HFCLKSTAT_SRC_Msk) >> CLOCK_HFCLKSTAT_SRC_Pos);
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src)
|
||||
{
|
||||
return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) ==
|
||||
(CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos));
|
||||
}
|
||||
|
||||
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void)
|
||||
{
|
||||
return (nrf_clock_start_task_status_t)((NRF_CLOCK->HFCLKRUN &
|
||||
CLOCK_HFCLKRUN_STATUS_Msk) >>
|
||||
CLOCK_HFCLKRUN_STATUS_Pos);
|
||||
}
|
||||
|
||||
__STATIC_INLINE nrf_clock_xtalfreq_t nrf_clock_xtalfreq_get(void)
|
||||
{
|
||||
#ifdef NRF51
|
||||
return (nrf_clock_xtalfreq_t)((NRF_CLOCK->XTALFREQ &
|
||||
CLOCK_XTALFREQ_XTALFREQ_Msk) >> CLOCK_XTALFREQ_XTALFREQ_Pos);
|
||||
#elif defined NRF52
|
||||
return NRF_CLOCK_XTALFREQ_Default;
|
||||
#endif
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_clock_xtalfreq_set(nrf_clock_xtalfreq_t xtalfreq)
|
||||
{
|
||||
#ifdef NRF51
|
||||
NRF_CLOCK->XTALFREQ =
|
||||
(uint32_t)((xtalfreq << CLOCK_XTALFREQ_XTALFREQ_Pos) & CLOCK_XTALFREQ_XTALFREQ_Msk);
|
||||
#elif defined NRF52
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval)
|
||||
{
|
||||
NRF_CLOCK->CTIV = ((interval << CLOCK_CTIV_CTIV_Pos) & CLOCK_CTIV_CTIV_Msk);
|
||||
}
|
||||
|
||||
#endif // SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
/**
|
||||
*@}
|
||||
**/
|
||||
#endif // NRF_CLOCK_H__
|
Loading…
Reference in New Issue