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);
|
||||
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* turn on clock in blocking mode. */
|
||||
clock_control_on(clock, (void *)1);
|
||||
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
|
||||
nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_1MHz);
|
||||
nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <sensor.h>
|
||||
#include <drivers/clock_control.h>
|
||||
#include "nrf_clock_calibration.h"
|
||||
#include <drivers/clock_control/nrf_clock_control.h>
|
||||
#include <hal/nrf_clock.h>
|
||||
#include <logging/log.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -49,8 +50,8 @@ static struct clock_control_async_data cal_hf_on_data = {
|
|||
.cb = cal_hf_on_callback
|
||||
};
|
||||
|
||||
static struct device *hfclk_dev; /* Handler to hfclk device. */
|
||||
static struct device *temp_sensor; /* Handler to temperature sensor device. */
|
||||
static struct device *clk_dev;
|
||||
static struct device *temp_sensor;
|
||||
|
||||
static void measure_temperature(struct k_work *work);
|
||||
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. */
|
||||
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)
|
||||
|
@ -140,7 +142,7 @@ void z_nrf_clock_calibration_init(struct device *dev)
|
|||
temp_sensor = device_get_binding(TEMP_SENSOR_NAME);
|
||||
}
|
||||
|
||||
hfclk_dev = dev;
|
||||
clk_dev = dev;
|
||||
total_cnt = 0;
|
||||
total_skips_cnt = 0;
|
||||
}
|
||||
|
@ -163,7 +165,7 @@ static void start_calibration(void)
|
|||
static void to_idle(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -180,7 +182,8 @@ static int get_temperature(s16_t *tvp)
|
|||
int rc = sensor_sample_fetch(temp_sensor);
|
||||
|
||||
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) {
|
||||
*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);
|
||||
}
|
||||
} else {
|
||||
clock_control_off(hfclk_dev, 0);
|
||||
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
|
@ -267,7 +270,7 @@ static void on_cal_done(void)
|
|||
int key = irq_lock();
|
||||
|
||||
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);
|
||||
cal_state = CAL_OFF;
|
||||
} else {
|
||||
|
@ -285,7 +288,8 @@ void z_nrf_clock_calibration_force_start(void)
|
|||
|
||||
if (cal_state == CAL_IDLE) {
|
||||
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);
|
||||
|
@ -302,7 +306,9 @@ void z_nrf_clock_calibration_isr(void)
|
|||
*/
|
||||
if (cal_state == CAL_IDLE) {
|
||||
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);
|
||||
|
||||
/* Helper logging macros which prepends device name to the log. */
|
||||
#define CLOCK_LOG(lvl, dev, ...) \
|
||||
LOG_##lvl("%s: " GET_ARG1(__VA_ARGS__), dev->config->name \
|
||||
COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__),\
|
||||
(), (, GET_ARGS_LESS_1(__VA_ARGS__))))
|
||||
#define ERR(dev, ...) CLOCK_LOG(ERR, dev, __VA_ARGS__)
|
||||
#define WRN(dev, ...) CLOCK_LOG(WRN, dev, __VA_ARGS__)
|
||||
#define INF(dev, ...) CLOCK_LOG(INF, dev, __VA_ARGS__)
|
||||
#define DBG(dev, ...) CLOCK_LOG(DBG, dev, __VA_ARGS__)
|
||||
/* Helper logging macros which prepends subsys name to the log. */
|
||||
#ifdef CONFIG_LOG
|
||||
#define CLOCK_LOG(lvl, dev, subsys, ...) \
|
||||
LOG_##lvl("%s: " GET_ARG1(__VA_ARGS__), \
|
||||
get_sub_config(dev, (enum clock_control_nrf_type)subsys)->name \
|
||||
COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__),\
|
||||
(), (, GET_ARGS_LESS_1(__VA_ARGS__))))
|
||||
#else
|
||||
#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
|
||||
* start/stop will be deferred and performed later on by handler owner.
|
||||
*/
|
||||
typedef bool (*nrf_clock_handler_t)(struct device *dev);
|
||||
|
||||
/* Clock instance structure */
|
||||
struct nrf_clock_control {
|
||||
/* Clock subsys structure */
|
||||
struct nrf_clock_control_sub_data {
|
||||
sys_slist_t list; /* List of users requesting callback */
|
||||
u8_t ref; /* Users counter */
|
||||
bool started; /* Indicated that clock is started */
|
||||
};
|
||||
|
||||
/* Clock instance static configuration */
|
||||
struct nrf_clock_control_config {
|
||||
/* Clock subsys static configuration */
|
||||
struct nrf_clock_control_sub_config {
|
||||
nrf_clock_handler_t start_handler; /* Called before start */
|
||||
nrf_clock_handler_t stop_handler; /* Called before stop */
|
||||
nrf_clock_event_t started_evt; /* Clock started event */
|
||||
nrf_clock_task_t start_tsk; /* Clock start 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
|
||||
* is cleared.
|
||||
|
@ -86,11 +105,32 @@ static void clock_irqs_enable(void)
|
|||
(0))));
|
||||
}
|
||||
|
||||
static enum clock_control_status get_status(struct device *dev,
|
||||
clock_control_subsys_t sys)
|
||||
static struct nrf_clock_control_sub_data *get_sub_data(struct device *dev,
|
||||
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) {
|
||||
return CLOCK_CONTROL_STATUS_ON;
|
||||
}
|
||||
|
@ -102,14 +142,18 @@ static enum clock_control_status get_status(struct device *dev,
|
|||
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 =
|
||||
dev->config->config_info;
|
||||
struct nrf_clock_control *data = dev->driver_data;
|
||||
enum clock_control_nrf_type type = (enum clock_control_nrf_type)subsys;
|
||||
const struct nrf_clock_control_sub_config *config;
|
||||
struct nrf_clock_control_sub_data *data;
|
||||
int err = 0;
|
||||
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();
|
||||
if (data->ref == 0) {
|
||||
err = -EALREADY;
|
||||
|
@ -119,7 +163,7 @@ static int clock_stop(struct device *dev, clock_control_subsys_t sub_system)
|
|||
if (data->ref == 0) {
|
||||
bool do_stop;
|
||||
|
||||
DBG(dev, "Stopping");
|
||||
DBG(dev, subsys, "Stopping");
|
||||
sys_slist_init(&data->list);
|
||||
|
||||
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,
|
||||
clock_control_subsys_t sub_system,
|
||||
clock_control_subsys_t subsys,
|
||||
struct clock_control_async_data *data)
|
||||
{
|
||||
const struct nrf_clock_control_config *config =
|
||||
dev->config->config_info;
|
||||
struct nrf_clock_control *clk_data = dev->driver_data;
|
||||
enum clock_control_nrf_type type = (enum clock_control_nrf_type)subsys;
|
||||
const struct nrf_clock_control_sub_config *config;
|
||||
struct nrf_clock_control_sub_data *clk_data;
|
||||
int key;
|
||||
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) ||
|
||||
((data != NULL) && (data->cb != NULL)));
|
||||
|
||||
|
@ -231,7 +279,7 @@ static int clock_async_start(struct device *dev,
|
|||
do_start = (config->start_handler) ?
|
||||
config->start_handler(dev) : true;
|
||||
if (do_start) {
|
||||
DBG(dev, "Triggering start task");
|
||||
DBG(dev, subsys, "Triggering start task");
|
||||
nrf_clock_task_trigger(NRF_CLOCK,
|
||||
config->start_tsk);
|
||||
} else {
|
||||
|
@ -243,7 +291,7 @@ static int clock_async_start(struct device *dev,
|
|||
* completed. In that case clock is still running and
|
||||
* 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);
|
||||
|
||||
static int hfclk_init(struct device *dev)
|
||||
static int clk_init(struct device *dev)
|
||||
{
|
||||
IRQ_CONNECT(DT_INST_0_NORDIC_NRF_CLOCK_IRQ_0,
|
||||
DT_INST_0_NORDIC_NRF_CLOCK_IRQ_0_PRIORITY,
|
||||
|
@ -280,17 +328,14 @@ static int hfclk_init(struct device *dev)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 = {
|
||||
.on = clock_start,
|
||||
.off = clock_stop,
|
||||
|
@ -298,48 +343,49 @@ static const struct clock_control_driver_api clock_control_api = {
|
|||
.get_status = get_status,
|
||||
};
|
||||
|
||||
static struct nrf_clock_control hfclk;
|
||||
static const struct nrf_clock_control_config hfclk_config = {
|
||||
.start_tsk = NRF_CLOCK_TASK_HFCLKSTART,
|
||||
.started_evt = NRF_CLOCK_EVENT_HFCLKSTARTED,
|
||||
.stop_tsk = NRF_CLOCK_TASK_HFCLKSTOP
|
||||
static struct nrf_clock_control_data data;
|
||||
|
||||
static const struct nrf_clock_control_config config = {
|
||||
.subsys = {
|
||||
[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,
|
||||
DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M",
|
||||
hfclk_init, &hfclk, &hfclk_config, PRE_KERNEL_1,
|
||||
DEVICE_AND_API_INIT(clock_nrf,
|
||||
DT_INST_0_NORDIC_NRF_CLOCK_LABEL,
|
||||
clk_init, &data, &config, PRE_KERNEL_1,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||
&clock_control_api);
|
||||
|
||||
|
||||
static struct nrf_clock_control lfclk;
|
||||
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)
|
||||
static void clkstarted_handle(struct device *dev,
|
||||
enum clock_control_nrf_type type)
|
||||
{
|
||||
struct nrf_clock_control_sub_data *sub_data = get_sub_data(dev, type);
|
||||
struct clock_control_async_data *async_data;
|
||||
struct nrf_clock_control *data = dev->driver_data;
|
||||
|
||||
DBG(dev, "Clock started");
|
||||
data->started = true;
|
||||
DBG(dev, type, "Clock started");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -383,29 +429,28 @@ static void usb_power_isr(void)
|
|||
void nrf_power_clock_isr(void *arg)
|
||||
{
|
||||
ARG_UNUSED(arg);
|
||||
struct device *dev = DEVICE_GET(clock_nrf);
|
||||
|
||||
if (clock_event_check_and_clean(NRF_CLOCK_EVENT_HFCLKSTARTED,
|
||||
NRF_CLOCK_INT_HF_STARTED_MASK)) {
|
||||
struct device *hfclk_dev = DEVICE_GET(clock_nrf5_m16src);
|
||||
struct nrf_clock_control *data = hfclk_dev->driver_data;
|
||||
struct nrf_clock_control_sub_data *data =
|
||||
get_sub_data(dev, CLOCK_CONTROL_NRF_TYPE_HFCLK);
|
||||
|
||||
/* Check needed due to anomaly 201:
|
||||
* HFCLKSTARTED may be generated twice.
|
||||
*/
|
||||
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,
|
||||
NRF_CLOCK_INT_LF_STARTED_MASK)) {
|
||||
struct device *lfclk_dev = DEVICE_GET(clock_nrf5_k32src);
|
||||
|
||||
if (IS_ENABLED(
|
||||
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();
|
||||
|
|
|
@ -526,12 +526,12 @@ static int init_rtc(struct device *dev, u8_t prescaler)
|
|||
NRF_RTC_Type *rtc = nrfx_config->rtc;
|
||||
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) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
clock_control_on(clock, NULL);
|
||||
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
|
||||
nrf_rtc_prescaler_set(rtc, prescaler);
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <drivers/led_strip.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_LED_STRIP_LOG_LEVEL
|
||||
|
@ -17,8 +16,7 @@ LOG_MODULE_REGISTER(ws2812b_sw);
|
|||
#include <drivers/gpio.h>
|
||||
#include <device.h>
|
||||
#include <drivers/clock_control.h>
|
||||
|
||||
#define BLOCKING ((void *)1)
|
||||
#include <drivers/clock_control/nrf_clock_control.h>
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
LOG_ERR("Unable to get HF clock");
|
||||
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 16 MHz clock enabled.
|
||||
*/
|
||||
clock_control_on(clock, BLOCKING);
|
||||
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
key = irq_lock();
|
||||
|
||||
while (len--) {
|
||||
|
@ -92,7 +90,7 @@ static int send_buf(u8_t *buf, size_t len)
|
|||
}
|
||||
|
||||
irq_unlock(key);
|
||||
clock_control_off(clock, NULL);
|
||||
clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <device.h>
|
||||
#include <drivers/sensor.h>
|
||||
#include <drivers/clock_control.h>
|
||||
#include <drivers/clock_control/nrf_clock_control.h>
|
||||
#include <logging/log.h>
|
||||
#include <hal/nrf_temp.h>
|
||||
|
||||
|
@ -22,7 +23,7 @@ LOG_MODULE_REGISTER(temp_nrf5, CONFIG_SENSOR_LOG_LEVEL);
|
|||
struct temp_nrf5_data {
|
||||
struct k_sem device_sync_sem;
|
||||
s32_t sample;
|
||||
struct device *hfclk_dev;
|
||||
struct device *clk_dev;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
/* Error if before sensor initialized */
|
||||
if (data->hfclk_dev == NULL) {
|
||||
if (data->clk_dev == NULL) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
|
@ -48,12 +49,13 @@ static int temp_nrf5_sample_fetch(struct device *dev, enum sensor_channel chan)
|
|||
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);
|
||||
|
||||
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);
|
||||
|
||||
data->sample = nrf_temp_result_get(NRF_TEMP);
|
||||
|
@ -106,10 +108,10 @@ static int temp_nrf5_init(struct device *dev)
|
|||
|
||||
LOG_DBG("");
|
||||
|
||||
/* A null hfclk_dev indicates sensor has not been initialized */
|
||||
data->hfclk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
||||
__ASSERT_NO_MSG(data->hfclk_dev);
|
||||
/* A null clk_dev indicates sensor has not been initialized */
|
||||
data->clk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||
__ASSERT_NO_MSG(data->clk_dev);
|
||||
|
||||
k_sem_init(&data->device_sync_sem, 0, UINT_MAX);
|
||||
IRQ_CONNECT(
|
||||
|
|
|
@ -83,12 +83,12 @@ int z_clock_driver_init(struct device *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) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
clock_control_on(clock, NULL);
|
||||
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
|
||||
/* TODO: replace with counter driver to access RTC */
|
||||
nrf_rtc_prescaler_set(RTC, 0);
|
||||
|
|
|
@ -536,7 +536,7 @@ static int hf_clock_enable(bool on, bool blocking)
|
|||
struct device *clock;
|
||||
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) {
|
||||
LOG_ERR("NRF HF Clock device not found!");
|
||||
return ret;
|
||||
|
@ -547,9 +547,10 @@ static int hf_clock_enable(bool on, bool blocking)
|
|||
/* Do not request HFCLK multiple times. */
|
||||
return 0;
|
||||
}
|
||||
ret = clock_control_on(clock, NULL);
|
||||
ret = clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
while (blocking &&
|
||||
clock_control_get_status(clock, NULL) !=
|
||||
clock_control_get_status(clock,
|
||||
CLOCK_CONTROL_NRF_SUBSYS_HF) !=
|
||||
CLOCK_CONTROL_STATUS_ON) {
|
||||
}
|
||||
} else {
|
||||
|
@ -559,7 +560,7 @@ static int hf_clock_enable(bool on, bool blocking)
|
|||
*/
|
||||
return 0;
|
||||
}
|
||||
ret = clock_control_off(clock, NULL);
|
||||
ret = clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
}
|
||||
|
||||
if (ret && (blocking || (ret != -EINPROGRESS))) {
|
||||
|
|
|
@ -10,7 +10,23 @@
|
|||
#include <device.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 */
|
||||
#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);
|
||||
|
||||
err = clock_control_off(_radio.hf_clock, NULL);
|
||||
err = clock_control_off(_radio.hf_clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
if (!err) {
|
||||
DEBUG_RADIO_XTAL(0);
|
||||
}
|
||||
|
@ -5216,7 +5216,7 @@ static void mayfly_xtal_start(void *params)
|
|||
ARG_UNUSED(params);
|
||||
|
||||
/* 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));
|
||||
|
||||
DEBUG_RADIO_XTAL(1);
|
||||
|
@ -5247,7 +5247,7 @@ static void mayfly_xtal_stop(void *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) {
|
||||
DEBUG_RADIO_XTAL(0);
|
||||
}
|
||||
|
@ -5264,12 +5264,12 @@ static void k32src_wait(void)
|
|||
}
|
||||
done = true;
|
||||
|
||||
struct device *lf_clock = device_get_binding(
|
||||
DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
||||
struct device *clock = device_get_binding(
|
||||
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);
|
||||
cpu_sleep();
|
||||
DEBUG_CPU_SLEEP(0);
|
||||
|
|
|
@ -118,19 +118,18 @@ static void swi5_nrf5_isr(void *arg)
|
|||
|
||||
int ll_init(struct k_sem *sem_rx)
|
||||
{
|
||||
struct device *clk_k32;
|
||||
struct device *clk_m16;
|
||||
struct device *clk;
|
||||
struct device *entropy;
|
||||
u32_t err;
|
||||
|
||||
sem_recv = sem_rx;
|
||||
|
||||
clk_k32 = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
||||
if (!clk_k32) {
|
||||
clk = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||
if (!clk) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
clock_control_on(clk_k32, NULL);
|
||||
clock_control_on(clk, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
|
||||
entropy = device_get_binding(CONFIG_ENTROPY_NAME);
|
||||
if (!entropy) {
|
||||
|
@ -156,12 +155,7 @@ int ll_init(struct k_sem *sem_rx)
|
|||
hal_ticker_instance0_trigger_set);
|
||||
LL_ASSERT(!err);
|
||||
|
||||
clk_m16 = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
||||
if (!clk_m16) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = radio_init(clk_m16, CLOCK_CONTROL_NRF_K32SRC_ACCURACY, entropy,
|
||||
err = radio_init(clk, CLOCK_CONTROL_NRF_K32SRC_ACCURACY, entropy,
|
||||
RADIO_CONNECTION_CONTEXT_MAX,
|
||||
RADIO_PACKET_COUNT_RX_MAX,
|
||||
RADIO_PACKET_COUNT_TX_MAX,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <zephyr/types.h>
|
||||
#include <soc.h>
|
||||
#include <drivers/clock_control.h>
|
||||
#include <drivers/clock_control/nrf_clock_control.h>
|
||||
|
||||
#include "hal/cpu.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)
|
||||
{
|
||||
struct device *hf_clock;
|
||||
struct device *clock;
|
||||
u8_t ack;
|
||||
|
||||
if (!started) {
|
||||
|
@ -337,8 +338,8 @@ u32_t ll_test_end(u16_t *num_rx)
|
|||
radio_tmr_stop();
|
||||
|
||||
/* Release resources acquired for Radio */
|
||||
hf_clock = radio_hf_clock_get();
|
||||
clock_control_off(hf_clock, NULL);
|
||||
clock = radio_hf_clock_get();
|
||||
clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
|
||||
/* Stop coarse timer */
|
||||
cntr_stop();
|
||||
|
|
|
@ -48,7 +48,7 @@ static struct {
|
|||
} event;
|
||||
|
||||
static struct {
|
||||
struct device *clk_hf;
|
||||
struct device *clk;
|
||||
} lll;
|
||||
|
||||
/* Entropy device */
|
||||
|
@ -127,7 +127,7 @@ static void swi_ull_low_nrf5_isr(void *arg)
|
|||
|
||||
int lll_init(void)
|
||||
{
|
||||
struct device *clk_k32;
|
||||
struct device *clk;
|
||||
int err;
|
||||
|
||||
/* Get reference to entropy device */
|
||||
|
@ -140,19 +140,15 @@ int lll_init(void)
|
|||
event.curr.abort_cb = NULL;
|
||||
|
||||
/* Initialize LF CLK */
|
||||
clk_k32 = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
||||
if (!clk_k32) {
|
||||
clk = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||
if (!clk) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
clock_control_on(clk_k32, NULL);
|
||||
clock_control_on(clk, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
|
||||
/* Initialize HF CLK */
|
||||
lll.clk_hf =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
||||
if (!lll.clk_hf) {
|
||||
return -ENODEV;
|
||||
}
|
||||
lll.clk = clk;
|
||||
|
||||
err = init_reset();
|
||||
if (err) {
|
||||
|
@ -321,7 +317,7 @@ int lll_clk_on(void)
|
|||
int err;
|
||||
|
||||
/* 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) {
|
||||
DEBUG_RADIO_XTAL(1);
|
||||
}
|
||||
|
@ -334,9 +330,9 @@ int lll_clk_on_wait(void)
|
|||
int err;
|
||||
|
||||
/* 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) {
|
||||
k_cpu_idle();
|
||||
}
|
||||
|
@ -351,7 +347,7 @@ int lll_clk_off(void)
|
|||
int err;
|
||||
|
||||
/* 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) {
|
||||
DEBUG_RADIO_XTAL(0);
|
||||
} else if (err == -EBUSY) {
|
||||
|
|
|
@ -24,13 +24,13 @@ void lll_clock_wait(void)
|
|||
}
|
||||
done = true;
|
||||
|
||||
struct device *lf_clock = device_get_binding(
|
||||
DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
||||
struct device *clock =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||
|
||||
LL_ASSERT(lf_clock);
|
||||
LL_ASSERT(clock);
|
||||
|
||||
clock_control_on(lf_clock, NULL);
|
||||
while (clock_control_get_status(lf_clock, NULL) !=
|
||||
clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
while (clock_control_get_status(clock, CLOCK_CONTROL_NRF_SUBSYS_LF) !=
|
||||
CLOCK_CONTROL_STATUS_ON) {
|
||||
DEBUG_CPU_SLEEP(1);
|
||||
k_cpu_idle();
|
||||
|
|
|
@ -42,7 +42,7 @@ static struct {
|
|||
} event;
|
||||
|
||||
static struct {
|
||||
struct device *clk_hf;
|
||||
struct device *clk;
|
||||
} lll;
|
||||
|
||||
/* Entropy device */
|
||||
|
@ -125,7 +125,7 @@ int lll_init(void)
|
|||
event.curr.abort_cb = NULL;
|
||||
|
||||
/* Initialize HF CLK */
|
||||
lll.clk_hf = NULL;
|
||||
lll.clk = NULL;
|
||||
|
||||
err = init_reset();
|
||||
if (err) {
|
||||
|
|
|
@ -12,61 +12,90 @@ LOG_MODULE_REGISTER(test);
|
|||
#include <drivers/clock_control/nrf_clock_control.h>
|
||||
#endif
|
||||
|
||||
struct device_subsys_data {
|
||||
clock_control_subsys_t subsys;
|
||||
u32_t startup_us;
|
||||
};
|
||||
|
||||
struct device_data {
|
||||
const char *name;
|
||||
u32_t startup_us;
|
||||
const struct device_subsys_data *subsys_data;
|
||||
u32_t subsys_cnt;
|
||||
};
|
||||
|
||||
static const struct device_data devices[] = {
|
||||
#ifdef DT_INST_0_NORDIC_NRF_CLOCK_LABEL
|
||||
{
|
||||
.name = DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M",
|
||||
.startup_us = IS_ENABLED(CONFIG_SOC_SERIES_NRF91X) ? 3000 : 400
|
||||
},
|
||||
|
||||
{
|
||||
.name = DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K",
|
||||
.startup_us = (CLOCK_CONTROL_NRF_K32SRC == NRF_CLOCK_LFCLK_RC) ?
|
||||
1000 : 300000
|
||||
.name = DT_INST_0_NORDIC_NRF_CLOCK_LABEL,
|
||||
.subsys_data = (const struct device_subsys_data[]){
|
||||
{
|
||||
.subsys = CLOCK_CONTROL_NRF_SUBSYS_HF,
|
||||
.startup_us =
|
||||
IS_ENABLED(CONFIG_SOC_SERIES_NRF91X) ?
|
||||
3000 : 400
|
||||
},
|
||||
{
|
||||
.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
|
||||
};
|
||||
|
||||
|
||||
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);
|
||||
int err;
|
||||
|
||||
k_busy_wait(1000);
|
||||
do {
|
||||
err = clock_control_off(dev, 0);
|
||||
err = clock_control_off(dev, subsys);
|
||||
} while (err == 0);
|
||||
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);
|
||||
|
||||
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,
|
||||
test_capability_check_t capability_check)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(devices); i++) {
|
||||
if ((capability_check == NULL) ||
|
||||
capability_check(devices[i].name)) {
|
||||
setup_instance(devices[i].name);
|
||||
func(devices[i].name, devices[i].startup_us);
|
||||
tear_down_instance(devices[i].name);
|
||||
/* Allow logs to be printed. */
|
||||
k_sleep(K_MSEC(100));
|
||||
for (size_t i = 0; i < ARRAY_SIZE(devices); i++) {
|
||||
for (size_t j = 0; j < devices[i].subsys_cnt; j++) {
|
||||
test_with_single_instance(devices[i].name,
|
||||
devices[i].subsys_data[j].subsys,
|
||||
devices[i].subsys_data[j].startup_us,
|
||||
func, capability_check);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +103,9 @@ static void test_all_instances(test_func_t func,
|
|||
/*
|
||||
* 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);
|
||||
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);
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, 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);
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_true((status == CLOCK_CONTROL_STATUS_STARTING) ||
|
||||
(status == CLOCK_CONTROL_STATUS_ON),
|
||||
"%s: Unexpected status (%d)", dev_name, status);
|
||||
|
||||
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,
|
||||
"%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);
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, 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
|
||||
* 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);
|
||||
enum clock_control_status status;
|
||||
int users = 5;
|
||||
int err;
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
||||
"%s: Unexpected status (%d)", dev_name, status);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_true((status == CLOCK_CONTROL_STATUS_STARTING) ||
|
||||
(status == CLOCK_CONTROL_STATUS_ON),
|
||||
"%s: Unexpected status (%d)", dev_name, status);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_true(status == CLOCK_CONTROL_STATUS_OFF,
|
||||
"%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);
|
||||
}
|
||||
|
||||
|
@ -157,15 +190,15 @@ static void test_multiple_users(void)
|
|||
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);
|
||||
|
||||
if (clock_control_async_on(dev, 0, NULL) != 0) {
|
||||
if (clock_control_async_on(dev, subsys, NULL) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
clock_control_off(dev, 0);
|
||||
clock_control_off(dev, subsys);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -180,7 +213,9 @@ static void clock_on_callback(struct device *dev, void *user_data)
|
|||
*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);
|
||||
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
|
||||
};
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, 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);
|
||||
|
||||
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);
|
||||
|
||||
/* wait for clock started. */
|
||||
|
@ -223,7 +258,8 @@ static void test_async_on(void)
|
|||
* is disabled before being started then callback is never called.
|
||||
*/
|
||||
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);
|
||||
enum clock_control_status status;
|
||||
|
@ -235,16 +271,16 @@ static void test_async_on_stopped_on_instance(const char *dev_name,
|
|||
.user_data = &executed1
|
||||
};
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, status,
|
||||
"%s: Unexpected status (%d)", dev_name, status);
|
||||
|
||||
/* lock to prevent clock interrupt for fast starting clocks.*/
|
||||
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);
|
||||
|
||||
err = clock_control_off(dev, 0);
|
||||
err = clock_control_off(dev, subsys);
|
||||
zassert_equal(0, err, "%s: Unexpected err (%d)", dev_name, err);
|
||||
|
||||
irq_unlock(key);
|
||||
|
@ -264,7 +300,8 @@ static void test_async_on_stopped(void)
|
|||
* running then callback is immediate.
|
||||
*/
|
||||
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);
|
||||
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
|
||||
};
|
||||
|
||||
status = clock_control_get_status(dev, NULL);
|
||||
status = clock_control_get_status(dev, subsys);
|
||||
zassert_equal(CLOCK_CONTROL_STATUS_OFF, 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);
|
||||
|
||||
/* wait for clock started. */
|
||||
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,
|
||||
"%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_true(executed1, "%s: Expected flag to be false", dev_name);
|
||||
|
|
|
@ -18,12 +18,12 @@ LOG_MODULE_REGISTER(test);
|
|||
#error "Expected 250ms calibration period"
|
||||
#endif
|
||||
|
||||
static void turn_off_clock(struct device *dev)
|
||||
static void turn_off_clock(struct device *dev, clock_control_subsys_t subsys)
|
||||
{
|
||||
int err;
|
||||
|
||||
do {
|
||||
err = clock_control_off(dev, 0);
|
||||
err = clock_control_off(dev, subsys);
|
||||
} while (err == 0);
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,8 @@ static void lfclk_started_cb(struct device *dev, void *user_data)
|
|||
*/
|
||||
static void test_clock_calibration(void)
|
||||
{
|
||||
struct device *hfclk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
||||
struct device *lfclk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
||||
struct device *clk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||
volatile bool started = false;
|
||||
struct clock_control_async_data lfclk_data = {
|
||||
.cb = lfclk_started_cb,
|
||||
|
@ -51,13 +49,14 @@ static void test_clock_calibration(void)
|
|||
u32_t cnt = 0;
|
||||
u32_t max_cnt = 1000;
|
||||
|
||||
turn_off_clock(hfclk_dev);
|
||||
turn_off_clock(lfclk_dev);
|
||||
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
|
||||
/* In case calibration needs to be completed. */
|
||||
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) {
|
||||
}
|
||||
|
@ -70,7 +69,7 @@ static void test_clock_calibration(void)
|
|||
cnt++;
|
||||
if (cnt == max_cnt) {
|
||||
irq_unlock(key);
|
||||
clock_control_off(lfclk_dev, NULL);
|
||||
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
zassert_true(false, "");
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +78,7 @@ static void test_clock_calibration(void)
|
|||
|
||||
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) {
|
||||
}
|
||||
|
||||
|
@ -90,14 +89,15 @@ static void test_clock_calibration(void)
|
|||
cnt++;
|
||||
if (cnt == max_cnt) {
|
||||
irq_unlock(key);
|
||||
clock_control_off(lfclk_dev, NULL);
|
||||
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
zassert_true(false, "");
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
"Expected hfclk off after calibration.");
|
||||
|
||||
|
@ -109,7 +109,7 @@ static void test_clock_calibration(void)
|
|||
cnt++;
|
||||
if (cnt == max_cnt) {
|
||||
irq_unlock(key);
|
||||
clock_control_off(lfclk_dev, NULL);
|
||||
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
zassert_true(false, "");
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ static void test_clock_calibration(void)
|
|||
|
||||
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.
|
||||
|
@ -127,10 +127,8 @@ static void test_clock_calibration(void)
|
|||
*/
|
||||
static void test_stopping_when_calibration(void)
|
||||
{
|
||||
struct device *hfclk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
||||
struct device *lfclk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
||||
struct device *clk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||
volatile bool started = false;
|
||||
struct clock_control_async_data lfclk_data = {
|
||||
.cb = lfclk_started_cb,
|
||||
|
@ -140,13 +138,14 @@ static void test_stopping_when_calibration(void)
|
|||
u32_t cnt = 0;
|
||||
u32_t max_cnt = 1000;
|
||||
|
||||
turn_off_clock(hfclk_dev);
|
||||
turn_off_clock(lfclk_dev);
|
||||
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
|
||||
/* In case calibration needs to be completed. */
|
||||
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) {
|
||||
}
|
||||
|
@ -162,7 +161,7 @@ static void test_stopping_when_calibration(void)
|
|||
cnt++;
|
||||
if (cnt == max_cnt) {
|
||||
irq_unlock(key);
|
||||
clock_control_off(lfclk_dev, NULL);
|
||||
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
zassert_true(false, "");
|
||||
}
|
||||
}
|
||||
|
@ -171,13 +170,13 @@ static void test_stopping_when_calibration(void)
|
|||
|
||||
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) {
|
||||
}
|
||||
|
||||
/* calibration started */
|
||||
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),
|
||||
"Expected LF still on");
|
||||
|
@ -187,7 +186,7 @@ static void test_stopping_when_calibration(void)
|
|||
cnt++;
|
||||
if (cnt == max_cnt) {
|
||||
irq_unlock(key);
|
||||
clock_control_off(lfclk_dev, NULL);
|
||||
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
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");
|
||||
|
||||
clock_control_off(lfclk_dev, NULL);
|
||||
clock_control_off(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct device *hfclk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_16M");
|
||||
struct device *lfclk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL "_32K");
|
||||
struct device *clk_dev =
|
||||
device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
|
||||
volatile bool started = false;
|
||||
struct clock_control_async_data lfclk_data = {
|
||||
.cb = lfclk_started_cb,
|
||||
|
@ -231,13 +228,14 @@ static void test_clock_calibration_force(void)
|
|||
u32_t cnt = 0;
|
||||
u32_t period;
|
||||
|
||||
turn_off_clock(hfclk_dev);
|
||||
turn_off_clock(lfclk_dev);
|
||||
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
|
||||
turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||
|
||||
/* In case calibration needs to be completed. */
|
||||
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) {
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue