drivers: clock_control: nrf: Switch to single clock device
Low frequency and high frequency clocks had separate devices while they are actually handled by single peripheral with single interrupt. The split was done probably because opaque subsys argument in the API was used for other purposes and there was no way to pass the information which clock should be controlled. Implementation changes some time ago and subsys parameter was no longer used. It now can be used to indicate which clock should be controlled. Change become necessary when nrf5340 is taken into account where there are more clocks and current approach would lead to create multiple devices - mess. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
9128200e6c
commit
00156ad80a
|
@ -74,13 +74,12 @@ int z_clock_driver_init(struct device *device)
|
||||||
|
|
||||||
ARG_UNUSED(device);
|
ARG_UNUSED(device);
|
||||||
|
|
||||||
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
if (!clock) {
|
if (!clock) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* turn on clock in blocking mode. */
|
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
clock_control_on(clock, (void *)1);
|
|
||||||
|
|
||||||
nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_1MHz);
|
nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_1MHz);
|
||||||
nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
|
nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <sensor.h>
|
#include <sensor.h>
|
||||||
#include <drivers/clock_control.h>
|
#include <drivers/clock_control.h>
|
||||||
#include "nrf_clock_calibration.h"
|
#include "nrf_clock_calibration.h"
|
||||||
|
#include <drivers/clock_control/nrf_clock_control.h>
|
||||||
#include <hal/nrf_clock.h>
|
#include <hal/nrf_clock.h>
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -49,8 +50,8 @@ static struct clock_control_async_data cal_hf_on_data = {
|
||||||
.cb = cal_hf_on_callback
|
.cb = cal_hf_on_callback
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct device *hfclk_dev; /* Handler to hfclk device. */
|
static struct device *clk_dev;
|
||||||
static struct device *temp_sensor; /* Handler to temperature sensor device. */
|
static struct device *temp_sensor;
|
||||||
|
|
||||||
static void measure_temperature(struct k_work *work);
|
static void measure_temperature(struct k_work *work);
|
||||||
static K_WORK_DEFINE(temp_measure_work, measure_temperature);
|
static K_WORK_DEFINE(temp_measure_work, measure_temperature);
|
||||||
|
@ -91,7 +92,8 @@ void z_nrf_clock_calibration_lfclk_started(struct device *dev)
|
||||||
{
|
{
|
||||||
/* Trigger unconditional calibration when lfclk is started. */
|
/* Trigger unconditional calibration when lfclk is started. */
|
||||||
cal_state = CAL_HFCLK_REQ;
|
cal_state = CAL_HFCLK_REQ;
|
||||||
clock_control_async_on(hfclk_dev, 0, &cal_hf_on_data);
|
clock_control_async_on(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF,
|
||||||
|
&cal_hf_on_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool z_nrf_clock_calibration_stop(struct device *dev)
|
bool z_nrf_clock_calibration_stop(struct device *dev)
|
||||||
|
@ -140,7 +142,7 @@ void z_nrf_clock_calibration_init(struct device *dev)
|
||||||
temp_sensor = device_get_binding(TEMP_SENSOR_NAME);
|
temp_sensor = device_get_binding(TEMP_SENSOR_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
hfclk_dev = dev;
|
clk_dev = dev;
|
||||||
total_cnt = 0;
|
total_cnt = 0;
|
||||||
total_skips_cnt = 0;
|
total_skips_cnt = 0;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +165,7 @@ static void start_calibration(void)
|
||||||
static void to_idle(void)
|
static void to_idle(void)
|
||||||
{
|
{
|
||||||
cal_state = CAL_IDLE;
|
cal_state = CAL_IDLE;
|
||||||
clock_control_off(hfclk_dev, 0);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_CTSTART);
|
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_CTSTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +182,8 @@ static int get_temperature(s16_t *tvp)
|
||||||
int rc = sensor_sample_fetch(temp_sensor);
|
int rc = sensor_sample_fetch(temp_sensor);
|
||||||
|
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
rc = sensor_channel_get(temp_sensor, SENSOR_CHAN_DIE_TEMP, &sensor_val);
|
rc = sensor_channel_get(temp_sensor, SENSOR_CHAN_DIE_TEMP,
|
||||||
|
&sensor_val);
|
||||||
}
|
}
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
*tvp = sensor_value_to_temp_unit(&sensor_val);
|
*tvp = sensor_value_to_temp_unit(&sensor_val);
|
||||||
|
@ -248,7 +251,7 @@ static void cal_hf_on_callback(struct device *dev, void *user_data)
|
||||||
k_work_submit(&temp_measure_work);
|
k_work_submit(&temp_measure_work);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clock_control_off(hfclk_dev, 0);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
@ -267,7 +270,7 @@ static void on_cal_done(void)
|
||||||
int key = irq_lock();
|
int key = irq_lock();
|
||||||
|
|
||||||
if (cal_state == CAL_ACTIVE_OFF) {
|
if (cal_state == CAL_ACTIVE_OFF) {
|
||||||
clock_control_off(hfclk_dev, 0);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP);
|
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP);
|
||||||
cal_state = CAL_OFF;
|
cal_state = CAL_OFF;
|
||||||
} else {
|
} else {
|
||||||
|
@ -285,7 +288,8 @@ void z_nrf_clock_calibration_force_start(void)
|
||||||
|
|
||||||
if (cal_state == CAL_IDLE) {
|
if (cal_state == CAL_IDLE) {
|
||||||
cal_state = CAL_HFCLK_REQ;
|
cal_state = CAL_HFCLK_REQ;
|
||||||
clock_control_async_on(hfclk_dev, 0, &cal_hf_on_data);
|
clock_control_async_on(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF,
|
||||||
|
&cal_hf_on_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
@ -302,7 +306,9 @@ void z_nrf_clock_calibration_isr(void)
|
||||||
*/
|
*/
|
||||||
if (cal_state == CAL_IDLE) {
|
if (cal_state == CAL_IDLE) {
|
||||||
cal_state = CAL_HFCLK_REQ;
|
cal_state = CAL_HFCLK_REQ;
|
||||||
clock_control_async_on(hfclk_dev, 0, &cal_hf_on_data);
|
clock_control_async_on(clk_dev,
|
||||||
|
CLOCK_CONTROL_NRF_SUBSYS_HF,
|
||||||
|
&cal_hf_on_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,38 +14,57 @@
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(clock_control, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
|
LOG_MODULE_REGISTER(clock_control, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
|
||||||
|
|
||||||
/* Helper logging macros which prepends device name to the log. */
|
/* Helper logging macros which prepends subsys name to the log. */
|
||||||
#define CLOCK_LOG(lvl, dev, ...) \
|
#ifdef CONFIG_LOG
|
||||||
LOG_##lvl("%s: " GET_ARG1(__VA_ARGS__), dev->config->name \
|
#define CLOCK_LOG(lvl, dev, subsys, ...) \
|
||||||
COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__),\
|
LOG_##lvl("%s: " GET_ARG1(__VA_ARGS__), \
|
||||||
(), (, GET_ARGS_LESS_1(__VA_ARGS__))))
|
get_sub_config(dev, (enum clock_control_nrf_type)subsys)->name \
|
||||||
#define ERR(dev, ...) CLOCK_LOG(ERR, dev, __VA_ARGS__)
|
COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__),\
|
||||||
#define WRN(dev, ...) CLOCK_LOG(WRN, dev, __VA_ARGS__)
|
(), (, GET_ARGS_LESS_1(__VA_ARGS__))))
|
||||||
#define INF(dev, ...) CLOCK_LOG(INF, dev, __VA_ARGS__)
|
#else
|
||||||
#define DBG(dev, ...) CLOCK_LOG(DBG, dev, __VA_ARGS__)
|
#define CLOCK_LOG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ERR(dev, subsys, ...) CLOCK_LOG(ERR, dev, subsys, __VA_ARGS__)
|
||||||
|
#define WRN(dev, subsys, ...) CLOCK_LOG(WRN, dev, subsys, __VA_ARGS__)
|
||||||
|
#define INF(dev, subsys, ...) CLOCK_LOG(INF, dev, subsys, __VA_ARGS__)
|
||||||
|
#define DBG(dev, subsys, ...) CLOCK_LOG(DBG, dev, subsys, __VA_ARGS__)
|
||||||
|
|
||||||
/* returns true if clock stopping or starting can be performed. If false then
|
/* returns true if clock stopping or starting can be performed. If false then
|
||||||
* start/stop will be deferred and performed later on by handler owner.
|
* start/stop will be deferred and performed later on by handler owner.
|
||||||
*/
|
*/
|
||||||
typedef bool (*nrf_clock_handler_t)(struct device *dev);
|
typedef bool (*nrf_clock_handler_t)(struct device *dev);
|
||||||
|
|
||||||
/* Clock instance structure */
|
/* Clock subsys structure */
|
||||||
struct nrf_clock_control {
|
struct nrf_clock_control_sub_data {
|
||||||
sys_slist_t list; /* List of users requesting callback */
|
sys_slist_t list; /* List of users requesting callback */
|
||||||
u8_t ref; /* Users counter */
|
u8_t ref; /* Users counter */
|
||||||
bool started; /* Indicated that clock is started */
|
bool started; /* Indicated that clock is started */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Clock instance static configuration */
|
/* Clock subsys static configuration */
|
||||||
struct nrf_clock_control_config {
|
struct nrf_clock_control_sub_config {
|
||||||
nrf_clock_handler_t start_handler; /* Called before start */
|
nrf_clock_handler_t start_handler; /* Called before start */
|
||||||
nrf_clock_handler_t stop_handler; /* Called before stop */
|
nrf_clock_handler_t stop_handler; /* Called before stop */
|
||||||
nrf_clock_event_t started_evt; /* Clock started event */
|
nrf_clock_event_t started_evt; /* Clock started event */
|
||||||
nrf_clock_task_t start_tsk; /* Clock start task */
|
nrf_clock_task_t start_tsk; /* Clock start task */
|
||||||
nrf_clock_task_t stop_tsk; /* Clock stop task */
|
nrf_clock_task_t stop_tsk; /* Clock stop task */
|
||||||
|
#ifdef CONFIG_LOG
|
||||||
|
const char *name;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void clkstarted_handle(struct device *dev);
|
struct nrf_clock_control_data {
|
||||||
|
struct nrf_clock_control_sub_data subsys[CLOCK_CONTROL_NRF_TYPE_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nrf_clock_control_config {
|
||||||
|
struct nrf_clock_control_sub_config
|
||||||
|
subsys[CLOCK_CONTROL_NRF_TYPE_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void clkstarted_handle(struct device *dev,
|
||||||
|
enum clock_control_nrf_type type);
|
||||||
|
|
||||||
/* Return true if given event has enabled interrupt and is triggered. Event
|
/* Return true if given event has enabled interrupt and is triggered. Event
|
||||||
* is cleared.
|
* is cleared.
|
||||||
|
@ -86,11 +105,32 @@ static void clock_irqs_enable(void)
|
||||||
(0))));
|
(0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum clock_control_status get_status(struct device *dev,
|
static struct nrf_clock_control_sub_data *get_sub_data(struct device *dev,
|
||||||
clock_control_subsys_t sys)
|
enum clock_control_nrf_type type)
|
||||||
{
|
{
|
||||||
struct nrf_clock_control *data = dev->driver_data;
|
struct nrf_clock_control_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
return &data->subsys[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct nrf_clock_control_sub_config *get_sub_config(
|
||||||
|
struct device *dev,
|
||||||
|
enum clock_control_nrf_type type)
|
||||||
|
{
|
||||||
|
const struct nrf_clock_control_config *config =
|
||||||
|
dev->config->config_info;
|
||||||
|
|
||||||
|
return &config->subsys[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum clock_control_status get_status(struct device *dev,
|
||||||
|
clock_control_subsys_t subsys)
|
||||||
|
{
|
||||||
|
enum clock_control_nrf_type type = (enum clock_control_nrf_type)subsys;
|
||||||
|
struct nrf_clock_control_sub_data *data;
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(type < CLOCK_CONTROL_NRF_TYPE_COUNT);
|
||||||
|
data = get_sub_data(dev, type);
|
||||||
if (data->started) {
|
if (data->started) {
|
||||||
return CLOCK_CONTROL_STATUS_ON;
|
return CLOCK_CONTROL_STATUS_ON;
|
||||||
}
|
}
|
||||||
|
@ -102,14 +142,18 @@ static enum clock_control_status get_status(struct device *dev,
|
||||||
return CLOCK_CONTROL_STATUS_OFF;
|
return CLOCK_CONTROL_STATUS_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clock_stop(struct device *dev, clock_control_subsys_t sub_system)
|
static int clock_stop(struct device *dev, clock_control_subsys_t subsys)
|
||||||
{
|
{
|
||||||
const struct nrf_clock_control_config *config =
|
enum clock_control_nrf_type type = (enum clock_control_nrf_type)subsys;
|
||||||
dev->config->config_info;
|
const struct nrf_clock_control_sub_config *config;
|
||||||
struct nrf_clock_control *data = dev->driver_data;
|
struct nrf_clock_control_sub_data *data;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int key;
|
int key;
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(type < CLOCK_CONTROL_NRF_TYPE_COUNT);
|
||||||
|
config = get_sub_config(dev, type);
|
||||||
|
data = get_sub_data(dev, type);
|
||||||
|
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
if (data->ref == 0) {
|
if (data->ref == 0) {
|
||||||
err = -EALREADY;
|
err = -EALREADY;
|
||||||
|
@ -119,7 +163,7 @@ static int clock_stop(struct device *dev, clock_control_subsys_t sub_system)
|
||||||
if (data->ref == 0) {
|
if (data->ref == 0) {
|
||||||
bool do_stop;
|
bool do_stop;
|
||||||
|
|
||||||
DBG(dev, "Stopping");
|
DBG(dev, subsys, "Stopping");
|
||||||
sys_slist_init(&data->list);
|
sys_slist_init(&data->list);
|
||||||
|
|
||||||
do_stop = (config->stop_handler) ?
|
do_stop = (config->stop_handler) ?
|
||||||
|
@ -185,15 +229,19 @@ static struct clock_control_async_data *list_get(sys_slist_t *list)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clock_async_start(struct device *dev,
|
static int clock_async_start(struct device *dev,
|
||||||
clock_control_subsys_t sub_system,
|
clock_control_subsys_t subsys,
|
||||||
struct clock_control_async_data *data)
|
struct clock_control_async_data *data)
|
||||||
{
|
{
|
||||||
const struct nrf_clock_control_config *config =
|
enum clock_control_nrf_type type = (enum clock_control_nrf_type)subsys;
|
||||||
dev->config->config_info;
|
const struct nrf_clock_control_sub_config *config;
|
||||||
struct nrf_clock_control *clk_data = dev->driver_data;
|
struct nrf_clock_control_sub_data *clk_data;
|
||||||
int key;
|
int key;
|
||||||
u8_t ref;
|
u8_t ref;
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(type < CLOCK_CONTROL_NRF_TYPE_COUNT);
|
||||||
|
config = get_sub_config(dev, type);
|
||||||
|
clk_data = get_sub_data(dev, type);
|
||||||
|
|
||||||
__ASSERT_NO_MSG((data == NULL) ||
|
__ASSERT_NO_MSG((data == NULL) ||
|
||||||
((data != NULL) && (data->cb != NULL)));
|
((data != NULL) && (data->cb != NULL)));
|
||||||
|
|
||||||
|
@ -231,7 +279,7 @@ static int clock_async_start(struct device *dev,
|
||||||
do_start = (config->start_handler) ?
|
do_start = (config->start_handler) ?
|
||||||
config->start_handler(dev) : true;
|
config->start_handler(dev) : true;
|
||||||
if (do_start) {
|
if (do_start) {
|
||||||
DBG(dev, "Triggering start task");
|
DBG(dev, subsys, "Triggering start task");
|
||||||
nrf_clock_task_trigger(NRF_CLOCK,
|
nrf_clock_task_trigger(NRF_CLOCK,
|
||||||
config->start_tsk);
|
config->start_tsk);
|
||||||
} else {
|
} else {
|
||||||
|
@ -243,7 +291,7 @@ static int clock_async_start(struct device *dev,
|
||||||
* completed. In that case clock is still running and
|
* completed. In that case clock is still running and
|
||||||
* we can notify enlisted requests.
|
* we can notify enlisted requests.
|
||||||
*/
|
*/
|
||||||
clkstarted_handle(dev);
|
clkstarted_handle(dev, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +313,7 @@ static int clock_start(struct device *dev, clock_control_subsys_t sub_system)
|
||||||
*/
|
*/
|
||||||
void nrf_power_clock_isr(void *arg);
|
void nrf_power_clock_isr(void *arg);
|
||||||
|
|
||||||
static int hfclk_init(struct device *dev)
|
static int clk_init(struct device *dev)
|
||||||
{
|
{
|
||||||
IRQ_CONNECT(DT_INST_0_NORDIC_NRF_CLOCK_IRQ_0,
|
IRQ_CONNECT(DT_INST_0_NORDIC_NRF_CLOCK_IRQ_0,
|
||||||
DT_INST_0_NORDIC_NRF_CLOCK_IRQ_0_PRIORITY,
|
DT_INST_0_NORDIC_NRF_CLOCK_IRQ_0_PRIORITY,
|
||||||
|
@ -280,17 +328,14 @@ static int hfclk_init(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_irqs_enable();
|
clock_irqs_enable();
|
||||||
sys_slist_init(&((struct nrf_clock_control *)dev->driver_data)->list);
|
|
||||||
|
for (enum clock_control_nrf_type i = 0;
|
||||||
|
i < CLOCK_CONTROL_NRF_TYPE_COUNT; i++) {
|
||||||
|
sys_slist_init(&(get_sub_data(dev, i)->list));
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lfclk_init(struct device *dev)
|
|
||||||
{
|
|
||||||
sys_slist_init(&((struct nrf_clock_control *)dev->driver_data)->list);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct clock_control_driver_api clock_control_api = {
|
static const struct clock_control_driver_api clock_control_api = {
|
||||||
.on = clock_start,
|
.on = clock_start,
|
||||||
.off = clock_stop,
|
.off = clock_stop,
|
||||||
|
@ -298,48 +343,49 @@ static const struct clock_control_driver_api clock_control_api = {
|
||||||
.get_status = get_status,
|
.get_status = get_status,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct nrf_clock_control hfclk;
|
static struct nrf_clock_control_data data;
|
||||||
static const struct nrf_clock_control_config hfclk_config = {
|
|
||||||
.start_tsk = NRF_CLOCK_TASK_HFCLKSTART,
|
static const struct nrf_clock_control_config config = {
|
||||||
.started_evt = NRF_CLOCK_EVENT_HFCLKSTARTED,
|
.subsys = {
|
||||||
.stop_tsk = NRF_CLOCK_TASK_HFCLKSTOP
|
[CLOCK_CONTROL_NRF_TYPE_HFCLK] = {
|
||||||
|
.start_tsk = NRF_CLOCK_TASK_HFCLKSTART,
|
||||||
|
.started_evt = NRF_CLOCK_EVENT_HFCLKSTARTED,
|
||||||
|
.stop_tsk = NRF_CLOCK_TASK_HFCLKSTOP,
|
||||||
|
COND_CODE_1(CONFIG_LOG, (.name = "hfclk",), ())
|
||||||
|
},
|
||||||
|
[CLOCK_CONTROL_NRF_TYPE_LFCLK] = {
|
||||||
|
.start_tsk = NRF_CLOCK_TASK_LFCLKSTART,
|
||||||
|
.started_evt = NRF_CLOCK_EVENT_LFCLKSTARTED,
|
||||||
|
.stop_tsk = NRF_CLOCK_TASK_LFCLKSTOP,
|
||||||
|
COND_CODE_1(CONFIG_LOG, (.name = "lfclk",), ())
|
||||||
|
.start_handler =
|
||||||
|
IS_ENABLED(
|
||||||
|
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION) ?
|
||||||
|
z_nrf_clock_calibration_start : NULL,
|
||||||
|
.stop_handler =
|
||||||
|
IS_ENABLED(
|
||||||
|
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION) ?
|
||||||
|
z_nrf_clock_calibration_stop : NULL
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(clock_nrf5_m16src,
|
DEVICE_AND_API_INIT(clock_nrf,
|
||||||
DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M",
|
DT_INST_0_NORDIC_NRF_CLOCK_LABEL,
|
||||||
hfclk_init, &hfclk, &hfclk_config, PRE_KERNEL_1,
|
clk_init, &data, &config, PRE_KERNEL_1,
|
||||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||||
&clock_control_api);
|
&clock_control_api);
|
||||||
|
|
||||||
|
static void clkstarted_handle(struct device *dev,
|
||||||
static struct nrf_clock_control lfclk;
|
enum clock_control_nrf_type type)
|
||||||
static const struct nrf_clock_control_config lfclk_config = {
|
|
||||||
.start_tsk = NRF_CLOCK_TASK_LFCLKSTART,
|
|
||||||
.started_evt = NRF_CLOCK_EVENT_LFCLKSTARTED,
|
|
||||||
.stop_tsk = NRF_CLOCK_TASK_LFCLKSTOP,
|
|
||||||
.start_handler =
|
|
||||||
IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION) ?
|
|
||||||
z_nrf_clock_calibration_start : NULL,
|
|
||||||
.stop_handler =
|
|
||||||
IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION) ?
|
|
||||||
z_nrf_clock_calibration_stop : NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(clock_nrf5_k32src,
|
|
||||||
DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K",
|
|
||||||
lfclk_init, &lfclk, &lfclk_config, PRE_KERNEL_1,
|
|
||||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
|
||||||
&clock_control_api);
|
|
||||||
|
|
||||||
static void clkstarted_handle(struct device *dev)
|
|
||||||
{
|
{
|
||||||
|
struct nrf_clock_control_sub_data *sub_data = get_sub_data(dev, type);
|
||||||
struct clock_control_async_data *async_data;
|
struct clock_control_async_data *async_data;
|
||||||
struct nrf_clock_control *data = dev->driver_data;
|
|
||||||
|
|
||||||
DBG(dev, "Clock started");
|
DBG(dev, type, "Clock started");
|
||||||
data->started = true;
|
sub_data->started = true;
|
||||||
|
|
||||||
while ((async_data = list_get(&data->list)) != NULL) {
|
while ((async_data = list_get(&sub_data->list)) != NULL) {
|
||||||
async_data->cb(dev, async_data->user_data);
|
async_data->cb(dev, async_data->user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,29 +429,28 @@ static void usb_power_isr(void)
|
||||||
void nrf_power_clock_isr(void *arg)
|
void nrf_power_clock_isr(void *arg)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(arg);
|
ARG_UNUSED(arg);
|
||||||
|
struct device *dev = DEVICE_GET(clock_nrf);
|
||||||
|
|
||||||
if (clock_event_check_and_clean(NRF_CLOCK_EVENT_HFCLKSTARTED,
|
if (clock_event_check_and_clean(NRF_CLOCK_EVENT_HFCLKSTARTED,
|
||||||
NRF_CLOCK_INT_HF_STARTED_MASK)) {
|
NRF_CLOCK_INT_HF_STARTED_MASK)) {
|
||||||
struct device *hfclk_dev = DEVICE_GET(clock_nrf5_m16src);
|
struct nrf_clock_control_sub_data *data =
|
||||||
struct nrf_clock_control *data = hfclk_dev->driver_data;
|
get_sub_data(dev, CLOCK_CONTROL_NRF_TYPE_HFCLK);
|
||||||
|
|
||||||
/* Check needed due to anomaly 201:
|
/* Check needed due to anomaly 201:
|
||||||
* HFCLKSTARTED may be generated twice.
|
* HFCLKSTARTED may be generated twice.
|
||||||
*/
|
*/
|
||||||
if (!data->started) {
|
if (!data->started) {
|
||||||
clkstarted_handle(hfclk_dev);
|
clkstarted_handle(dev, CLOCK_CONTROL_NRF_TYPE_HFCLK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clock_event_check_and_clean(NRF_CLOCK_EVENT_LFCLKSTARTED,
|
if (clock_event_check_and_clean(NRF_CLOCK_EVENT_LFCLKSTARTED,
|
||||||
NRF_CLOCK_INT_LF_STARTED_MASK)) {
|
NRF_CLOCK_INT_LF_STARTED_MASK)) {
|
||||||
struct device *lfclk_dev = DEVICE_GET(clock_nrf5_k32src);
|
|
||||||
|
|
||||||
if (IS_ENABLED(
|
if (IS_ENABLED(
|
||||||
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION)) {
|
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION)) {
|
||||||
z_nrf_clock_calibration_lfclk_started(lfclk_dev);
|
z_nrf_clock_calibration_lfclk_started(dev);
|
||||||
}
|
}
|
||||||
clkstarted_handle(lfclk_dev);
|
clkstarted_handle(dev, CLOCK_CONTROL_NRF_TYPE_LFCLK);
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_power_isr();
|
usb_power_isr();
|
||||||
|
|
|
@ -526,12 +526,12 @@ static int init_rtc(struct device *dev, u8_t prescaler)
|
||||||
NRF_RTC_Type *rtc = nrfx_config->rtc;
|
NRF_RTC_Type *rtc = nrfx_config->rtc;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
if (!clock) {
|
if (!clock) {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_control_on(clock, NULL);
|
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
|
|
||||||
nrf_rtc_prescaler_set(rtc, prescaler);
|
nrf_rtc_prescaler_set(rtc, prescaler);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <drivers/led_strip.h>
|
#include <drivers/led_strip.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define LOG_LEVEL CONFIG_LED_STRIP_LOG_LEVEL
|
#define LOG_LEVEL CONFIG_LED_STRIP_LOG_LEVEL
|
||||||
|
@ -17,8 +16,7 @@ LOG_MODULE_REGISTER(ws2812b_sw);
|
||||||
#include <drivers/gpio.h>
|
#include <drivers/gpio.h>
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#include <drivers/clock_control.h>
|
#include <drivers/clock_control.h>
|
||||||
|
#include <drivers/clock_control/nrf_clock_control.h>
|
||||||
#define BLOCKING ((void *)1)
|
|
||||||
|
|
||||||
static int send_buf(u8_t *buf, size_t len)
|
static int send_buf(u8_t *buf, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -32,7 +30,7 @@ static int send_buf(u8_t *buf, size_t len)
|
||||||
*/
|
*/
|
||||||
u32_t i = 0U;
|
u32_t i = 0U;
|
||||||
|
|
||||||
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
if (!clock) {
|
if (!clock) {
|
||||||
LOG_ERR("Unable to get HF clock");
|
LOG_ERR("Unable to get HF clock");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -41,7 +39,7 @@ static int send_buf(u8_t *buf, size_t len)
|
||||||
/* The inline assembly further below is designed to work only with
|
/* The inline assembly further below is designed to work only with
|
||||||
* the 16 MHz clock enabled.
|
* the 16 MHz clock enabled.
|
||||||
*/
|
*/
|
||||||
clock_control_on(clock, BLOCKING);
|
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
|
|
||||||
while (len--) {
|
while (len--) {
|
||||||
|
@ -92,7 +90,7 @@ static int send_buf(u8_t *buf, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
clock_control_off(clock, NULL);
|
clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#include <drivers/sensor.h>
|
#include <drivers/sensor.h>
|
||||||
#include <drivers/clock_control.h>
|
#include <drivers/clock_control.h>
|
||||||
|
#include <drivers/clock_control/nrf_clock_control.h>
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
#include <hal/nrf_temp.h>
|
#include <hal/nrf_temp.h>
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ LOG_MODULE_REGISTER(temp_nrf5, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
struct temp_nrf5_data {
|
struct temp_nrf5_data {
|
||||||
struct k_sem device_sync_sem;
|
struct k_sem device_sync_sem;
|
||||||
s32_t sample;
|
s32_t sample;
|
||||||
struct device *hfclk_dev;
|
struct device *clk_dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void hfclk_on_callback(struct device *dev, void *user_data)
|
static void hfclk_on_callback(struct device *dev, void *user_data)
|
||||||
|
@ -40,7 +41,7 @@ static int temp_nrf5_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Error if before sensor initialized */
|
/* Error if before sensor initialized */
|
||||||
if (data->hfclk_dev == NULL) {
|
if (data->clk_dev == NULL) {
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,12 +49,13 @@ static int temp_nrf5_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = clock_control_async_on(data->hfclk_dev, NULL, &clk_data);
|
r = clock_control_async_on(data->clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF,
|
||||||
|
&clk_data);
|
||||||
__ASSERT_NO_MSG(!r);
|
__ASSERT_NO_MSG(!r);
|
||||||
|
|
||||||
k_sem_take(&data->device_sync_sem, K_FOREVER);
|
k_sem_take(&data->device_sync_sem, K_FOREVER);
|
||||||
|
|
||||||
r = clock_control_off(data->hfclk_dev, 0);
|
r = clock_control_off(data->clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
__ASSERT_NO_MSG(!r);
|
__ASSERT_NO_MSG(!r);
|
||||||
|
|
||||||
data->sample = nrf_temp_result_get(NRF_TEMP);
|
data->sample = nrf_temp_result_get(NRF_TEMP);
|
||||||
|
@ -106,10 +108,10 @@ static int temp_nrf5_init(struct device *dev)
|
||||||
|
|
||||||
LOG_DBG("");
|
LOG_DBG("");
|
||||||
|
|
||||||
/* A null hfclk_dev indicates sensor has not been initialized */
|
/* A null clk_dev indicates sensor has not been initialized */
|
||||||
data->hfclk_dev =
|
data->clk_dev =
|
||||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
__ASSERT_NO_MSG(data->hfclk_dev);
|
__ASSERT_NO_MSG(data->clk_dev);
|
||||||
|
|
||||||
k_sem_init(&data->device_sync_sem, 0, UINT_MAX);
|
k_sem_init(&data->device_sync_sem, 0, UINT_MAX);
|
||||||
IRQ_CONNECT(
|
IRQ_CONNECT(
|
||||||
|
|
|
@ -83,12 +83,12 @@ int z_clock_driver_init(struct device *device)
|
||||||
|
|
||||||
ARG_UNUSED(device);
|
ARG_UNUSED(device);
|
||||||
|
|
||||||
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
if (!clock) {
|
if (!clock) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_control_on(clock, NULL);
|
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
|
|
||||||
/* TODO: replace with counter driver to access RTC */
|
/* TODO: replace with counter driver to access RTC */
|
||||||
nrf_rtc_prescaler_set(RTC, 0);
|
nrf_rtc_prescaler_set(RTC, 0);
|
||||||
|
|
|
@ -536,7 +536,7 @@ static int hf_clock_enable(bool on, bool blocking)
|
||||||
struct device *clock;
|
struct device *clock;
|
||||||
static bool clock_requested;
|
static bool clock_requested;
|
||||||
|
|
||||||
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
if (!clock) {
|
if (!clock) {
|
||||||
LOG_ERR("NRF HF Clock device not found!");
|
LOG_ERR("NRF HF Clock device not found!");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -547,9 +547,10 @@ static int hf_clock_enable(bool on, bool blocking)
|
||||||
/* Do not request HFCLK multiple times. */
|
/* Do not request HFCLK multiple times. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ret = clock_control_on(clock, NULL);
|
ret = clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
while (blocking &&
|
while (blocking &&
|
||||||
clock_control_get_status(clock, NULL) !=
|
clock_control_get_status(clock,
|
||||||
|
CLOCK_CONTROL_NRF_SUBSYS_HF) !=
|
||||||
CLOCK_CONTROL_STATUS_ON) {
|
CLOCK_CONTROL_STATUS_ON) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -559,7 +560,7 @@ static int hf_clock_enable(bool on, bool blocking)
|
||||||
*/
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ret = clock_control_off(clock, NULL);
|
ret = clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret && (blocking || (ret != -EINPROGRESS))) {
|
if (ret && (blocking || (ret != -EINPROGRESS))) {
|
||||||
|
|
|
@ -10,7 +10,23 @@
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#include <hal/nrf_clock.h>
|
#include <hal/nrf_clock.h>
|
||||||
|
|
||||||
/* TODO: move all these to clock_control.h ? */
|
/** @brief Clocks handled by the CLOCK peripheral.
|
||||||
|
*
|
||||||
|
* Enum shall be used as a sys argument in clock_control API.
|
||||||
|
*/
|
||||||
|
enum clock_control_nrf_type {
|
||||||
|
CLOCK_CONTROL_NRF_TYPE_HFCLK,
|
||||||
|
CLOCK_CONTROL_NRF_TYPE_LFCLK,
|
||||||
|
CLOCK_CONTROL_NRF_TYPE_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Define can be used with clock control API instead of enum directly to
|
||||||
|
* increase code readability.
|
||||||
|
*/
|
||||||
|
#define CLOCK_CONTROL_NRF_SUBSYS_HF \
|
||||||
|
((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_HFCLK)
|
||||||
|
#define CLOCK_CONTROL_NRF_SUBSYS_LF \
|
||||||
|
((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_LFCLK)
|
||||||
|
|
||||||
/* Define 32KHz clock source */
|
/* Define 32KHz clock source */
|
||||||
#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC
|
#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC
|
||||||
|
|
|
@ -4935,7 +4935,7 @@ static inline void isr_radio_state_close(void)
|
||||||
|
|
||||||
event_inactive(0, 0, 0, NULL);
|
event_inactive(0, 0, 0, NULL);
|
||||||
|
|
||||||
err = clock_control_off(_radio.hf_clock, NULL);
|
err = clock_control_off(_radio.hf_clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
DEBUG_RADIO_XTAL(0);
|
DEBUG_RADIO_XTAL(0);
|
||||||
}
|
}
|
||||||
|
@ -5216,7 +5216,7 @@ static void mayfly_xtal_start(void *params)
|
||||||
ARG_UNUSED(params);
|
ARG_UNUSED(params);
|
||||||
|
|
||||||
/* turn on 16MHz clock, non-blocking mode. */
|
/* turn on 16MHz clock, non-blocking mode. */
|
||||||
err = clock_control_on(_radio.hf_clock, NULL);
|
err = clock_control_on(_radio.hf_clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
LL_ASSERT(!err || (err == -EINPROGRESS));
|
LL_ASSERT(!err || (err == -EINPROGRESS));
|
||||||
|
|
||||||
DEBUG_RADIO_XTAL(1);
|
DEBUG_RADIO_XTAL(1);
|
||||||
|
@ -5247,7 +5247,7 @@ static void mayfly_xtal_stop(void *params)
|
||||||
|
|
||||||
ARG_UNUSED(params);
|
ARG_UNUSED(params);
|
||||||
|
|
||||||
err = clock_control_off(_radio.hf_clock, NULL);
|
err = clock_control_off(_radio.hf_clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
DEBUG_RADIO_XTAL(0);
|
DEBUG_RADIO_XTAL(0);
|
||||||
}
|
}
|
||||||
|
@ -5264,12 +5264,12 @@ static void k32src_wait(void)
|
||||||
}
|
}
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
struct device *lf_clock = device_get_binding(
|
struct device *clock = device_get_binding(
|
||||||
DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
|
|
||||||
LL_ASSERT(lf_clock);
|
LL_ASSERT(clock);
|
||||||
|
|
||||||
while (clock_control_on(lf_clock, (void *)CLOCK_CONTROL_NRF_K32SRC)) {
|
while (clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_LF)) {
|
||||||
DEBUG_CPU_SLEEP(1);
|
DEBUG_CPU_SLEEP(1);
|
||||||
cpu_sleep();
|
cpu_sleep();
|
||||||
DEBUG_CPU_SLEEP(0);
|
DEBUG_CPU_SLEEP(0);
|
||||||
|
|
|
@ -118,19 +118,18 @@ static void swi5_nrf5_isr(void *arg)
|
||||||
|
|
||||||
int ll_init(struct k_sem *sem_rx)
|
int ll_init(struct k_sem *sem_rx)
|
||||||
{
|
{
|
||||||
struct device *clk_k32;
|
struct device *clk;
|
||||||
struct device *clk_m16;
|
|
||||||
struct device *entropy;
|
struct device *entropy;
|
||||||
u32_t err;
|
u32_t err;
|
||||||
|
|
||||||
sem_recv = sem_rx;
|
sem_recv = sem_rx;
|
||||||
|
|
||||||
clk_k32 = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
clk = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
if (!clk_k32) {
|
if (!clk) {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_control_on(clk_k32, NULL);
|
clock_control_on(clk, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
|
|
||||||
entropy = device_get_binding(CONFIG_ENTROPY_NAME);
|
entropy = device_get_binding(CONFIG_ENTROPY_NAME);
|
||||||
if (!entropy) {
|
if (!entropy) {
|
||||||
|
@ -156,12 +155,7 @@ int ll_init(struct k_sem *sem_rx)
|
||||||
hal_ticker_instance0_trigger_set);
|
hal_ticker_instance0_trigger_set);
|
||||||
LL_ASSERT(!err);
|
LL_ASSERT(!err);
|
||||||
|
|
||||||
clk_m16 = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
err = radio_init(clk, CLOCK_CONTROL_NRF_K32SRC_ACCURACY, entropy,
|
||||||
if (!clk_m16) {
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = radio_init(clk_m16, CLOCK_CONTROL_NRF_K32SRC_ACCURACY, entropy,
|
|
||||||
RADIO_CONNECTION_CONTEXT_MAX,
|
RADIO_CONNECTION_CONTEXT_MAX,
|
||||||
RADIO_PACKET_COUNT_RX_MAX,
|
RADIO_PACKET_COUNT_RX_MAX,
|
||||||
RADIO_PACKET_COUNT_TX_MAX,
|
RADIO_PACKET_COUNT_TX_MAX,
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <drivers/clock_control.h>
|
#include <drivers/clock_control.h>
|
||||||
|
#include <drivers/clock_control/nrf_clock_control.h>
|
||||||
|
|
||||||
#include "hal/cpu.h"
|
#include "hal/cpu.h"
|
||||||
#include "hal/cntr.h"
|
#include "hal/cntr.h"
|
||||||
|
@ -310,7 +311,7 @@ u32_t ll_test_rx(u8_t chan, u8_t phy, u8_t mod_idx)
|
||||||
|
|
||||||
u32_t ll_test_end(u16_t *num_rx)
|
u32_t ll_test_end(u16_t *num_rx)
|
||||||
{
|
{
|
||||||
struct device *hf_clock;
|
struct device *clock;
|
||||||
u8_t ack;
|
u8_t ack;
|
||||||
|
|
||||||
if (!started) {
|
if (!started) {
|
||||||
|
@ -337,8 +338,8 @@ u32_t ll_test_end(u16_t *num_rx)
|
||||||
radio_tmr_stop();
|
radio_tmr_stop();
|
||||||
|
|
||||||
/* Release resources acquired for Radio */
|
/* Release resources acquired for Radio */
|
||||||
hf_clock = radio_hf_clock_get();
|
clock = radio_hf_clock_get();
|
||||||
clock_control_off(hf_clock, NULL);
|
clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
|
|
||||||
/* Stop coarse timer */
|
/* Stop coarse timer */
|
||||||
cntr_stop();
|
cntr_stop();
|
||||||
|
|
|
@ -48,7 +48,7 @@ static struct {
|
||||||
} event;
|
} event;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
struct device *clk_hf;
|
struct device *clk;
|
||||||
} lll;
|
} lll;
|
||||||
|
|
||||||
/* Entropy device */
|
/* Entropy device */
|
||||||
|
@ -127,7 +127,7 @@ static void swi_ull_low_nrf5_isr(void *arg)
|
||||||
|
|
||||||
int lll_init(void)
|
int lll_init(void)
|
||||||
{
|
{
|
||||||
struct device *clk_k32;
|
struct device *clk;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Get reference to entropy device */
|
/* Get reference to entropy device */
|
||||||
|
@ -140,19 +140,15 @@ int lll_init(void)
|
||||||
event.curr.abort_cb = NULL;
|
event.curr.abort_cb = NULL;
|
||||||
|
|
||||||
/* Initialize LF CLK */
|
/* Initialize LF CLK */
|
||||||
clk_k32 = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
clk = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
if (!clk_k32) {
|
if (!clk) {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_control_on(clk_k32, NULL);
|
clock_control_on(clk, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
|
|
||||||
/* Initialize HF CLK */
|
/* Initialize HF CLK */
|
||||||
lll.clk_hf =
|
lll.clk = clk;
|
||||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
|
||||||
if (!lll.clk_hf) {
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = init_reset();
|
err = init_reset();
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -321,7 +317,7 @@ int lll_clk_on(void)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* turn on radio clock in non-blocking mode. */
|
/* turn on radio clock in non-blocking mode. */
|
||||||
err = clock_control_on(lll.clk_hf, NULL);
|
err = clock_control_on(lll.clk, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
if (!err || err == -EINPROGRESS) {
|
if (!err || err == -EINPROGRESS) {
|
||||||
DEBUG_RADIO_XTAL(1);
|
DEBUG_RADIO_XTAL(1);
|
||||||
}
|
}
|
||||||
|
@ -334,9 +330,9 @@ int lll_clk_on_wait(void)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* turn on radio clock in blocking mode. */
|
/* turn on radio clock in blocking mode. */
|
||||||
err = clock_control_on(lll.clk_hf, NULL);
|
err = clock_control_on(lll.clk, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
|
|
||||||
while (clock_control_get_status(lll.clk_hf, NULL) !=
|
while (clock_control_get_status(lll.clk, CLOCK_CONTROL_NRF_SUBSYS_HF) !=
|
||||||
CLOCK_CONTROL_STATUS_ON) {
|
CLOCK_CONTROL_STATUS_ON) {
|
||||||
k_cpu_idle();
|
k_cpu_idle();
|
||||||
}
|
}
|
||||||
|
@ -351,7 +347,7 @@ int lll_clk_off(void)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* turn off radio clock in non-blocking mode. */
|
/* turn off radio clock in non-blocking mode. */
|
||||||
err = clock_control_off(lll.clk_hf, NULL);
|
err = clock_control_off(lll.clk, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
DEBUG_RADIO_XTAL(0);
|
DEBUG_RADIO_XTAL(0);
|
||||||
} else if (err == -EBUSY) {
|
} else if (err == -EBUSY) {
|
||||||
|
|
|
@ -24,13 +24,13 @@ void lll_clock_wait(void)
|
||||||
}
|
}
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
struct device *lf_clock = device_get_binding(
|
struct device *clock =
|
||||||
DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
|
|
||||||
LL_ASSERT(lf_clock);
|
LL_ASSERT(clock);
|
||||||
|
|
||||||
clock_control_on(lf_clock, NULL);
|
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
while (clock_control_get_status(lf_clock, NULL) !=
|
while (clock_control_get_status(clock, CLOCK_CONTROL_NRF_SUBSYS_LF) !=
|
||||||
CLOCK_CONTROL_STATUS_ON) {
|
CLOCK_CONTROL_STATUS_ON) {
|
||||||
DEBUG_CPU_SLEEP(1);
|
DEBUG_CPU_SLEEP(1);
|
||||||
k_cpu_idle();
|
k_cpu_idle();
|
||||||
|
|
|
@ -42,7 +42,7 @@ static struct {
|
||||||
} event;
|
} event;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
struct device *clk_hf;
|
struct device *clk;
|
||||||
} lll;
|
} lll;
|
||||||
|
|
||||||
/* Entropy device */
|
/* Entropy device */
|
||||||
|
@ -125,7 +125,7 @@ int lll_init(void)
|
||||||
event.curr.abort_cb = NULL;
|
event.curr.abort_cb = NULL;
|
||||||
|
|
||||||
/* Initialize HF CLK */
|
/* Initialize HF CLK */
|
||||||
lll.clk_hf = NULL;
|
lll.clk = NULL;
|
||||||
|
|
||||||
err = init_reset();
|
err = init_reset();
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
|
@ -12,61 +12,90 @@ LOG_MODULE_REGISTER(test);
|
||||||
#include <drivers/clock_control/nrf_clock_control.h>
|
#include <drivers/clock_control/nrf_clock_control.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct device_subsys_data {
|
||||||
|
clock_control_subsys_t subsys;
|
||||||
|
u32_t startup_us;
|
||||||
|
};
|
||||||
|
|
||||||
struct device_data {
|
struct device_data {
|
||||||
const char *name;
|
const char *name;
|
||||||
u32_t startup_us;
|
const struct device_subsys_data *subsys_data;
|
||||||
|
u32_t subsys_cnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct device_data devices[] = {
|
static const struct device_data devices[] = {
|
||||||
#ifdef DT_INST_0_NORDIC_NRF_CLOCK_LABEL
|
#ifdef DT_INST_0_NORDIC_NRF_CLOCK_LABEL
|
||||||
{
|
{
|
||||||
.name = DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M",
|
.name = DT_INST_0_NORDIC_NRF_CLOCK_LABEL,
|
||||||
.startup_us = IS_ENABLED(CONFIG_SOC_SERIES_NRF91X) ? 3000 : 400
|
.subsys_data = (const struct device_subsys_data[]){
|
||||||
},
|
{
|
||||||
|
.subsys = CLOCK_CONTROL_NRF_SUBSYS_HF,
|
||||||
{
|
.startup_us =
|
||||||
.name = DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K",
|
IS_ENABLED(CONFIG_SOC_SERIES_NRF91X) ?
|
||||||
.startup_us = (CLOCK_CONTROL_NRF_K32SRC == NRF_CLOCK_LFCLK_RC) ?
|
3000 : 400
|
||||||
1000 : 300000
|
},
|
||||||
|
{
|
||||||
|
.subsys = CLOCK_CONTROL_NRF_SUBSYS_LF,
|
||||||
|
.startup_us = (CLOCK_CONTROL_NRF_K32SRC ==
|
||||||
|
NRF_CLOCK_LFCLK_RC) ? 1000 : 300000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.subsys_cnt = CLOCK_CONTROL_NRF_TYPE_COUNT
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef void (*test_func_t)(const char *dev_name, u32_t startup_us);
|
typedef void (*test_func_t)(const char *dev_name,
|
||||||
|
clock_control_subsys_t subsys,
|
||||||
|
u32_t startup_us);
|
||||||
|
|
||||||
typedef bool (*test_capability_check_t)(const char *dev_name);
|
typedef bool (*test_capability_check_t)(const char *dev_name,
|
||||||
|
clock_control_subsys_t subsys);
|
||||||
|
|
||||||
static void setup_instance(const char *dev_name)
|
static void setup_instance(const char *dev_name, clock_control_subsys_t subsys)
|
||||||
{
|
{
|
||||||
struct device *dev = device_get_binding(dev_name);
|
struct device *dev = device_get_binding(dev_name);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
k_busy_wait(1000);
|
k_busy_wait(1000);
|
||||||
do {
|
do {
|
||||||
err = clock_control_off(dev, 0);
|
err = clock_control_off(dev, subsys);
|
||||||
} while (err == 0);
|
} while (err == 0);
|
||||||
LOG_INF("setup done");
|
LOG_INF("setup done");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tear_down_instance(const char *dev_name)
|
static void tear_down_instance(const char *dev_name,
|
||||||
|
clock_control_subsys_t subsys)
|
||||||
{
|
{
|
||||||
struct device *dev = device_get_binding(dev_name);
|
struct device *dev = device_get_binding(dev_name);
|
||||||
|
|
||||||
clock_control_on(dev, NULL);
|
clock_control_on(dev, subsys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_with_single_instance(const char *dev_name,
|
||||||
|
clock_control_subsys_t subsys,
|
||||||
|
u32_t startup_time,
|
||||||
|
test_func_t func,
|
||||||
|
test_capability_check_t capability_check)
|
||||||
|
{
|
||||||
|
if ((capability_check == NULL) || capability_check(dev_name, subsys)) {
|
||||||
|
setup_instance(dev_name, subsys);
|
||||||
|
func(dev_name, subsys, startup_time);
|
||||||
|
tear_down_instance(dev_name, subsys);
|
||||||
|
/* Allow logs to be printed. */
|
||||||
|
k_sleep(K_MSEC(100));
|
||||||
|
}
|
||||||
|
}
|
||||||
static void test_all_instances(test_func_t func,
|
static void test_all_instances(test_func_t func,
|
||||||
test_capability_check_t capability_check)
|
test_capability_check_t capability_check)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ARRAY_SIZE(devices); i++) {
|
for (size_t i = 0; i < ARRAY_SIZE(devices); i++) {
|
||||||
if ((capability_check == NULL) ||
|
for (size_t j = 0; j < devices[i].subsys_cnt; j++) {
|
||||||
capability_check(devices[i].name)) {
|
test_with_single_instance(devices[i].name,
|
||||||
setup_instance(devices[i].name);
|
devices[i].subsys_data[j].subsys,
|
||||||
func(devices[i].name, devices[i].startup_us);
|
devices[i].subsys_data[j].startup_us,
|
||||||
tear_down_instance(devices[i].name);
|
func, capability_check);
|
||||||
/* Allow logs to be printed. */
|
|
||||||
k_sleep(K_MSEC(100));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +103,9 @@ static void test_all_instances(test_func_t func,
|
||||||
/*
|
/*
|
||||||
* Basic test for checking correctness of getting clock status.
|
* Basic test for checking correctness of getting clock status.
|
||||||
*/
|
*/
|
||||||
static void test_on_off_status_instance(const char *dev_name, u32_t startup_us)
|
static void test_on_off_status_instance(const char *dev_name,
|
||||||
|
clock_control_subsys_t subsys,
|
||||||
|
u32_t startup_us)
|
||||||
{
|
{
|
||||||
struct device *dev = device_get_binding(dev_name);
|
struct device *dev = device_get_binding(dev_name);
|
||||||
enum clock_control_status status;
|
enum clock_control_status status;
|
||||||
|
@ -82,29 +113,29 @@ static void test_on_off_status_instance(const char *dev_name, u32_t startup_us)
|
||||||
|
|
||||||
zassert_true(dev != NULL, "%s: Unknown device", dev_name);
|
zassert_true(dev != NULL, "%s: Unknown device", dev_name);
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
|
|
||||||
err = clock_control_on(dev, NULL);
|
err = clock_control_on(dev, subsys);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_true((status == CLOCK_CONTROL_STATUS_STARTING) ||
|
zassert_true((status == CLOCK_CONTROL_STATUS_STARTING) ||
|
||||||
(status == CLOCK_CONTROL_STATUS_ON),
|
(status == CLOCK_CONTROL_STATUS_ON),
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
k_busy_wait(startup_us);
|
k_busy_wait(startup_us);
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_equal(CLOCK_CONTROL_STATUS_ON, status,
|
zassert_equal(CLOCK_CONTROL_STATUS_ON, status,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
err = clock_control_off(dev, 0);
|
err = clock_control_off(dev, subsys);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
}
|
}
|
||||||
|
@ -118,37 +149,39 @@ static void test_on_off_status(void)
|
||||||
* Test validates that if number of enabling requests matches disabling requests
|
* Test validates that if number of enabling requests matches disabling requests
|
||||||
* then clock is disabled.
|
* then clock is disabled.
|
||||||
*/
|
*/
|
||||||
static void test_multiple_users_instance(const char *dev_name, u32_t startup_us)
|
static void test_multiple_users_instance(const char *dev_name,
|
||||||
|
clock_control_subsys_t subsys,
|
||||||
|
u32_t startup_us)
|
||||||
{
|
{
|
||||||
struct device *dev = device_get_binding(dev_name);
|
struct device *dev = device_get_binding(dev_name);
|
||||||
enum clock_control_status status;
|
enum clock_control_status status;
|
||||||
int users = 5;
|
int users = 5;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
for (int i = 0; i < users; i++) {
|
for (int i = 0; i < users; i++) {
|
||||||
err = clock_control_on(dev, NULL);
|
err = clock_control_on(dev, subsys);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_true((status == CLOCK_CONTROL_STATUS_STARTING) ||
|
zassert_true((status == CLOCK_CONTROL_STATUS_STARTING) ||
|
||||||
(status == CLOCK_CONTROL_STATUS_ON),
|
(status == CLOCK_CONTROL_STATUS_ON),
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
for (int i = 0; i < users; i++) {
|
for (int i = 0; i < users; i++) {
|
||||||
err = clock_control_off(dev, 0);
|
err = clock_control_off(dev, subsys);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_true(status == CLOCK_CONTROL_STATUS_OFF,
|
zassert_true(status == CLOCK_CONTROL_STATUS_OFF,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
err = clock_control_off(dev, 0);
|
err = clock_control_off(dev, subsys);
|
||||||
zassert_equal(-EALREADY, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(-EALREADY, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,15 +190,15 @@ static void test_multiple_users(void)
|
||||||
test_all_instances(test_multiple_users_instance, NULL);
|
test_all_instances(test_multiple_users_instance, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool async_capable(const char *dev_name)
|
static bool async_capable(const char *dev_name, clock_control_subsys_t subsys)
|
||||||
{
|
{
|
||||||
struct device *dev = device_get_binding(dev_name);
|
struct device *dev = device_get_binding(dev_name);
|
||||||
|
|
||||||
if (clock_control_async_on(dev, 0, NULL) != 0) {
|
if (clock_control_async_on(dev, subsys, NULL) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_control_off(dev, 0);
|
clock_control_off(dev, subsys);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +213,9 @@ static void clock_on_callback(struct device *dev, void *user_data)
|
||||||
*executed = true;
|
*executed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_async_on_instance(const char *dev_name, u32_t startup_us)
|
static void test_async_on_instance(const char *dev_name,
|
||||||
|
clock_control_subsys_t subsys,
|
||||||
|
u32_t startup_us)
|
||||||
{
|
{
|
||||||
struct device *dev = device_get_binding(dev_name);
|
struct device *dev = device_get_binding(dev_name);
|
||||||
enum clock_control_status status;
|
enum clock_control_status status;
|
||||||
|
@ -196,14 +231,14 @@ static void test_async_on_instance(const char *dev_name, u32_t startup_us)
|
||||||
.user_data = &executed2
|
.user_data = &executed2
|
||||||
};
|
};
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
err = clock_control_async_on(dev, 0, &data1);
|
err = clock_control_async_on(dev, subsys, &data1);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
|
|
||||||
err = clock_control_async_on(dev, 0, &data2);
|
err = clock_control_async_on(dev, subsys, &data2);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
|
|
||||||
/* wait for clock started. */
|
/* wait for clock started. */
|
||||||
|
@ -223,7 +258,8 @@ static void test_async_on(void)
|
||||||
* is disabled before being started then callback is never called.
|
* is disabled before being started then callback is never called.
|
||||||
*/
|
*/
|
||||||
static void test_async_on_stopped_on_instance(const char *dev_name,
|
static void test_async_on_stopped_on_instance(const char *dev_name,
|
||||||
u32_t startup_us)
|
clock_control_subsys_t subsys,
|
||||||
|
u32_t startup_us)
|
||||||
{
|
{
|
||||||
struct device *dev = device_get_binding(dev_name);
|
struct device *dev = device_get_binding(dev_name);
|
||||||
enum clock_control_status status;
|
enum clock_control_status status;
|
||||||
|
@ -235,16 +271,16 @@ static void test_async_on_stopped_on_instance(const char *dev_name,
|
||||||
.user_data = &executed1
|
.user_data = &executed1
|
||||||
};
|
};
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
/* lock to prevent clock interrupt for fast starting clocks.*/
|
/* lock to prevent clock interrupt for fast starting clocks.*/
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
err = clock_control_async_on(dev, 0, &data1);
|
err = clock_control_async_on(dev, subsys, &data1);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
|
|
||||||
err = clock_control_off(dev, 0);
|
err = clock_control_off(dev, subsys);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
@ -264,7 +300,8 @@ static void test_async_on_stopped(void)
|
||||||
* running then callback is immediate.
|
* running then callback is immediate.
|
||||||
*/
|
*/
|
||||||
static void test_immediate_cb_when_clock_on_on_instance(const char *dev_name,
|
static void test_immediate_cb_when_clock_on_on_instance(const char *dev_name,
|
||||||
u32_t startup_us)
|
clock_control_subsys_t subsys,
|
||||||
|
u32_t startup_us)
|
||||||
{
|
{
|
||||||
struct device *dev = device_get_binding(dev_name);
|
struct device *dev = device_get_binding(dev_name);
|
||||||
enum clock_control_status status;
|
enum clock_control_status status;
|
||||||
|
@ -275,21 +312,21 @@ static void test_immediate_cb_when_clock_on_on_instance(const char *dev_name,
|
||||||
.user_data = &executed1
|
.user_data = &executed1
|
||||||
};
|
};
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
err = clock_control_on(dev, NULL);
|
err = clock_control_on(dev, subsys);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
|
|
||||||
/* wait for clock started. */
|
/* wait for clock started. */
|
||||||
k_busy_wait(startup_us);
|
k_busy_wait(startup_us);
|
||||||
|
|
||||||
status = clock_control_get_status(dev, NULL);
|
status = clock_control_get_status(dev, subsys);
|
||||||
zassert_equal(CLOCK_CONTROL_STATUS_ON, status,
|
zassert_equal(CLOCK_CONTROL_STATUS_ON, status,
|
||||||
"%s: Unexpected status (%d)", dev_name, status);
|
"%s: Unexpected status (%d)", dev_name, status);
|
||||||
|
|
||||||
err = clock_control_async_on(dev, 0, &data1);
|
err = clock_control_async_on(dev, subsys, &data1);
|
||||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||||
|
|
||||||
zassert_true(executed1, "%s: Expected flag to be false", dev_name);
|
zassert_true(executed1, "%s: Expected flag to be false", dev_name);
|
||||||
|
|
|
@ -18,12 +18,12 @@ LOG_MODULE_REGISTER(test);
|
||||||
#error "Expected 250ms calibration period"
|
#error "Expected 250ms calibration period"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void turn_off_clock(struct device *dev)
|
static void turn_off_clock(struct device *dev, clock_control_subsys_t subsys)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
err = clock_control_off(dev, 0);
|
err = clock_control_off(dev, subsys);
|
||||||
} while (err == 0);
|
} while (err == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +38,8 @@ static void lfclk_started_cb(struct device *dev, void *user_data)
|
||||||
*/
|
*/
|
||||||
static void test_clock_calibration(void)
|
static void test_clock_calibration(void)
|
||||||
{
|
{
|
||||||
struct device *hfclk_dev =
|
struct device *clk_dev =
|
||||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
struct device *lfclk_dev =
|
|
||||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
|
||||||
volatile bool started = false;
|
volatile bool started = false;
|
||||||
struct clock_control_async_data lfclk_data = {
|
struct clock_control_async_data lfclk_data = {
|
||||||
.cb = lfclk_started_cb,
|
.cb = lfclk_started_cb,
|
||||||
|
@ -51,13 +49,14 @@ static void test_clock_calibration(void)
|
||||||
u32_t cnt = 0;
|
u32_t cnt = 0;
|
||||||
u32_t max_cnt = 1000;
|
u32_t max_cnt = 1000;
|
||||||
|
|
||||||
turn_off_clock(hfclk_dev);
|
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
turn_off_clock(lfclk_dev);
|
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
|
|
||||||
/* In case calibration needs to be completed. */
|
/* In case calibration needs to be completed. */
|
||||||
k_busy_wait(100000);
|
k_busy_wait(100000);
|
||||||
|
|
||||||
clock_control_async_on(lfclk_dev, NULL, &lfclk_data);
|
clock_control_async_on(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF,
|
||||||
|
&lfclk_data);
|
||||||
|
|
||||||
while (started == false) {
|
while (started == false) {
|
||||||
}
|
}
|
||||||
|
@ -70,7 +69,7 @@ static void test_clock_calibration(void)
|
||||||
cnt++;
|
cnt++;
|
||||||
if (cnt == max_cnt) {
|
if (cnt == max_cnt) {
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
clock_control_off(lfclk_dev, NULL);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
zassert_true(false, "");
|
zassert_true(false, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +78,7 @@ static void test_clock_calibration(void)
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
|
||||||
while (clock_control_get_status(hfclk_dev, NULL)
|
while (clock_control_get_status(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF)
|
||||||
!= CLOCK_CONTROL_STATUS_ON) {
|
!= CLOCK_CONTROL_STATUS_ON) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,14 +89,15 @@ static void test_clock_calibration(void)
|
||||||
cnt++;
|
cnt++;
|
||||||
if (cnt == max_cnt) {
|
if (cnt == max_cnt) {
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
clock_control_off(lfclk_dev, NULL);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
zassert_true(false, "");
|
zassert_true(false, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
|
||||||
zassert_equal(clock_control_get_status(hfclk_dev, NULL),
|
zassert_equal(clock_control_get_status(
|
||||||
|
clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF),
|
||||||
CLOCK_CONTROL_STATUS_OFF,
|
CLOCK_CONTROL_STATUS_OFF,
|
||||||
"Expected hfclk off after calibration.");
|
"Expected hfclk off after calibration.");
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ static void test_clock_calibration(void)
|
||||||
cnt++;
|
cnt++;
|
||||||
if (cnt == max_cnt) {
|
if (cnt == max_cnt) {
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
clock_control_off(lfclk_dev, NULL);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
zassert_true(false, "");
|
zassert_true(false, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ static void test_clock_calibration(void)
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
|
||||||
clock_control_off(lfclk_dev, NULL);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test checks that when calibration is active then LF clock is not stopped.
|
/* Test checks that when calibration is active then LF clock is not stopped.
|
||||||
|
@ -127,10 +127,8 @@ static void test_clock_calibration(void)
|
||||||
*/
|
*/
|
||||||
static void test_stopping_when_calibration(void)
|
static void test_stopping_when_calibration(void)
|
||||||
{
|
{
|
||||||
struct device *hfclk_dev =
|
struct device *clk_dev =
|
||||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
struct device *lfclk_dev =
|
|
||||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
|
||||||
volatile bool started = false;
|
volatile bool started = false;
|
||||||
struct clock_control_async_data lfclk_data = {
|
struct clock_control_async_data lfclk_data = {
|
||||||
.cb = lfclk_started_cb,
|
.cb = lfclk_started_cb,
|
||||||
|
@ -140,13 +138,14 @@ static void test_stopping_when_calibration(void)
|
||||||
u32_t cnt = 0;
|
u32_t cnt = 0;
|
||||||
u32_t max_cnt = 1000;
|
u32_t max_cnt = 1000;
|
||||||
|
|
||||||
turn_off_clock(hfclk_dev);
|
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
turn_off_clock(lfclk_dev);
|
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
|
|
||||||
/* In case calibration needs to be completed. */
|
/* In case calibration needs to be completed. */
|
||||||
k_busy_wait(100000);
|
k_busy_wait(100000);
|
||||||
|
|
||||||
clock_control_async_on(lfclk_dev, NULL, &lfclk_data);
|
clock_control_async_on(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF,
|
||||||
|
&lfclk_data);
|
||||||
|
|
||||||
while (started == false) {
|
while (started == false) {
|
||||||
}
|
}
|
||||||
|
@ -162,7 +161,7 @@ static void test_stopping_when_calibration(void)
|
||||||
cnt++;
|
cnt++;
|
||||||
if (cnt == max_cnt) {
|
if (cnt == max_cnt) {
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
clock_control_off(lfclk_dev, NULL);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
zassert_true(false, "");
|
zassert_true(false, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,13 +170,13 @@ static void test_stopping_when_calibration(void)
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
|
||||||
while (clock_control_get_status(hfclk_dev, NULL)
|
while (clock_control_get_status(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF)
|
||||||
!= CLOCK_CONTROL_STATUS_ON) {
|
!= CLOCK_CONTROL_STATUS_ON) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calibration started */
|
/* calibration started */
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
clock_control_off(lfclk_dev, NULL);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
|
|
||||||
zassert_true(nrf_clock_lf_is_running(NRF_CLOCK),
|
zassert_true(nrf_clock_lf_is_running(NRF_CLOCK),
|
||||||
"Expected LF still on");
|
"Expected LF still on");
|
||||||
|
@ -187,7 +186,7 @@ static void test_stopping_when_calibration(void)
|
||||||
cnt++;
|
cnt++;
|
||||||
if (cnt == max_cnt) {
|
if (cnt == max_cnt) {
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
clock_control_off(lfclk_dev, NULL);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
zassert_true(false, "");
|
zassert_true(false, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +198,7 @@ static void test_stopping_when_calibration(void)
|
||||||
|
|
||||||
zassert_false(nrf_clock_lf_is_running(NRF_CLOCK), "Expected LF off");
|
zassert_false(nrf_clock_lf_is_running(NRF_CLOCK), "Expected LF off");
|
||||||
|
|
||||||
clock_control_off(lfclk_dev, NULL);
|
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32_t pend_on_next_calibration(void)
|
static u32_t pend_on_next_calibration(void)
|
||||||
|
@ -219,10 +218,8 @@ static u32_t pend_on_next_calibration(void)
|
||||||
|
|
||||||
static void test_clock_calibration_force(void)
|
static void test_clock_calibration_force(void)
|
||||||
{
|
{
|
||||||
struct device *hfclk_dev =
|
struct device *clk_dev =
|
||||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||||
struct device *lfclk_dev =
|
|
||||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
|
||||||
volatile bool started = false;
|
volatile bool started = false;
|
||||||
struct clock_control_async_data lfclk_data = {
|
struct clock_control_async_data lfclk_data = {
|
||||||
.cb = lfclk_started_cb,
|
.cb = lfclk_started_cb,
|
||||||
|
@ -231,13 +228,14 @@ static void test_clock_calibration_force(void)
|
||||||
u32_t cnt = 0;
|
u32_t cnt = 0;
|
||||||
u32_t period;
|
u32_t period;
|
||||||
|
|
||||||
turn_off_clock(hfclk_dev);
|
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||||
turn_off_clock(lfclk_dev);
|
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
|
|
||||||
/* In case calibration needs to be completed. */
|
/* In case calibration needs to be completed. */
|
||||||
k_busy_wait(100000);
|
k_busy_wait(100000);
|
||||||
|
|
||||||
clock_control_async_on(lfclk_dev, NULL, &lfclk_data);
|
clock_control_async_on(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF,
|
||||||
|
&lfclk_data);
|
||||||
|
|
||||||
while (started == false) {
|
while (started == false) {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue