Skip to content

Commit f4da9b9

Browse files
cmark85kartben
authored andcommitted
drivers: sensor: Add sensor clock API support
This commit introduces a new Sensor Clock API, enabling the retrieval of cycle counts and conversion to nanoseconds based on the system or external clock. The API includes: - `sensor_clock_get_cycles()` to get the current cycle count from the sensor clock. - `sensor_clock_cycles_to_ns()` to convert cycles to nanoseconds using the clock's frequency. The implementation supports both system clocks and external clocks defined in the device tree, making the sensor clock integration more flexible for various sensor use cases. Signed-off-by: Mark Chen <[email protected]>
1 parent 7c57fec commit f4da9b9

31 files changed

+558
-22
lines changed

doc/releases/release-notes-4.1.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,33 @@ Drivers and Sensors
242242

243243
* Sensors
244244

245+
* Sensor Clock
246+
247+
* The asynchronous sensor API now supports external clock sources. To use an external clock source
248+
with the asynchronous sensor API, the following configurations are required:
249+
250+
* Enable one of the Kconfig options:
251+
:kconfig:option:`CONFIG_SENSOR_CLOCK_COUNTER`,
252+
:kconfig:option:`CONFIG_SENSOR_CLOCK_RTC`, or
253+
:kconfig:option:`CONFIG_SENSOR_CLOCK_SYSTEM`.
254+
255+
* If not using the system clock, define the ``zephyr,sensor-clock`` property in the device tree to specify
256+
the external clock source.
257+
258+
A typical configuration in the device tree structure is as follows:
259+
260+
.. code-block:: devicetree
261+
262+
/ {
263+
chosen {
264+
zephyr,sensor-clock = &timer0;
265+
};
266+
};
267+
268+
&timer0 {
269+
status = "okay";
270+
};
271+
245272
* Serial
246273

247274
* SPI

drivers/sensor/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,15 @@ zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL sensor_shell.c)
7474
zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL_STREAM sensor_shell_stream.c)
7575
zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL_BATTERY shell_battery.c)
7676
zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API sensor_decoders_init.c default_rtio_sensor.c)
77+
78+
dt_has_chosen(has_zephyr_sensor_clock PROPERTY "zephyr,sensor-clock")
79+
80+
if(CONFIG_SENSOR_CLOCK_RTC OR CONFIG_SENSOR_CLOCK_COUNTER)
81+
if(has_zephyr_sensor_clock)
82+
zephyr_library_sources(sensor_clock_external.c)
83+
else()
84+
message(FATAL_ERROR "Sensor clock type (RTC or Counter) is selected, but no zephyr,sensor-clock is defined in the device tree.")
85+
endif()
86+
elseif(CONFIG_SENSOR_CLOCK_SYSTEM)
87+
zephyr_library_sources(sensor_clock_sys.c)
88+
endif()

drivers/sensor/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ config SENSOR_SHELL_MAX_TRIGGER_DEVICES
8282
config SENSOR_INFO
8383
bool "Sensor Info iterable section"
8484

85+
source "drivers/sensor/Kconfig.sensor_clock"
86+
8587
comment "Device Drivers"
8688

8789
# zephyr-keep-sorted-start

drivers/sensor/Kconfig.sensor_clock

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Sensor clock configuration options
2+
# Copyright(c) 2024 Cienet
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
config SENSOR_CLOCK
6+
bool
7+
default y if SENSOR_ASYNC_API
8+
help
9+
Configure the sensor clock source for the system.
10+
11+
if SENSOR_CLOCK
12+
13+
choice
14+
prompt "Sensor clock type"
15+
default SENSOR_CLOCK_SYSTEM
16+
help
17+
Select the clock source to be used for sensor timing.
18+
19+
config SENSOR_CLOCK_SYSTEM
20+
bool "Use the system counter for sensor time"
21+
22+
config SENSOR_CLOCK_COUNTER
23+
bool "Use a counter device/API for sensor time"
24+
25+
config SENSOR_CLOCK_RTC
26+
bool "Use an RTC device/API for sensor time"
27+
28+
endchoice
29+
30+
endif # SENSOR_CLOCK

drivers/sensor/adi/adxl345/adxl345_stream.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <zephyr/logging/log.h>
88
#include <zephyr/drivers/sensor.h>
9-
9+
#include <zephyr/drivers/sensor_clock.h>
1010
#include "adxl345.h"
1111

1212
LOG_MODULE_DECLARE(ADXL345, CONFIG_SENSOR_LOG_LEVEL);
@@ -358,11 +358,21 @@ void adxl345_stream_irq_handler(const struct device *dev)
358358
{
359359
struct adxl345_dev_data *data = (struct adxl345_dev_data *) dev->data;
360360
const struct adxl345_dev_config *cfg = (const struct adxl345_dev_config *) dev->config;
361+
uint64_t cycles;
362+
int rc;
361363

362364
if (data->sqe == NULL) {
363365
return;
364366
}
365-
data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
367+
368+
rc = sensor_clock_get_cycles(&cycles);
369+
if (rc != 0) {
370+
LOG_ERR("Failed to get sensor clock cycles");
371+
rtio_iodev_sqe_err(data->sqe, rc);
372+
return;
373+
}
374+
375+
data->timestamp = sensor_clock_cycles_to_ns(cycles);
366376
struct rtio_sqe *write_status_addr = rtio_sqe_acquire(data->rtio_ctx);
367377
struct rtio_sqe *read_status_reg = rtio_sqe_acquire(data->rtio_ctx);
368378
struct rtio_sqe *check_status_reg = rtio_sqe_acquire(data->rtio_ctx);

drivers/sensor/adi/adxl362/adxl362_stream.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <zephyr/logging/log.h>
88
#include <zephyr/drivers/sensor.h>
9-
9+
#include <zephyr/drivers/sensor_clock.h>
1010
#include "adxl362.h"
1111

1212
LOG_MODULE_DECLARE(ADXL362, CONFIG_SENSOR_LOG_LEVEL);
@@ -384,12 +384,20 @@ static void adxl362_process_status_cb(struct rtio *r, const struct rtio_sqe *sqr
384384
void adxl362_stream_irq_handler(const struct device *dev)
385385
{
386386
struct adxl362_data *data = (struct adxl362_data *) dev->data;
387-
387+
uint64_t cycles;
388+
int rc;
388389
if (data->sqe == NULL) {
389390
return;
390391
}
391392

392-
data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
393+
rc = sensor_clock_get_cycles(&cycles);
394+
if (rc != 0) {
395+
LOG_ERR("Failed to get sensor clock cycles");
396+
rtio_iodev_sqe_err(data->sqe, rc);
397+
return;
398+
}
399+
400+
data->timestamp = sensor_clock_cycles_to_ns(cycles);
393401

394402
struct rtio_sqe *write_status_addr = rtio_sqe_acquire(data->rtio_ctx);
395403
struct rtio_sqe *read_status_reg = rtio_sqe_acquire(data->rtio_ctx);

drivers/sensor/adi/adxl367/adxl367_stream.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <zephyr/logging/log.h>
88
#include <zephyr/drivers/sensor.h>
9-
9+
#include <zephyr/drivers/sensor_clock.h>
1010
#include "adxl367.h"
1111

1212
LOG_MODULE_DECLARE(ADXL362, CONFIG_SENSOR_LOG_LEVEL);
@@ -537,12 +537,20 @@ static void adxl367_process_status_cb(struct rtio *r, const struct rtio_sqe *sqr
537537
void adxl367_stream_irq_handler(const struct device *dev)
538538
{
539539
struct adxl367_data *data = (struct adxl367_data *) dev->data;
540-
540+
uint64_t cycles;
541+
int rc;
541542
if (data->sqe == NULL) {
542543
return;
543544
}
544545

545-
data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
546+
rc = sensor_clock_get_cycles(&cycles);
547+
if (rc != 0) {
548+
LOG_ERR("Failed to get sensor clock cycles");
549+
rtio_iodev_sqe_err(data->sqe, rc);
550+
return;
551+
}
552+
553+
data->timestamp = sensor_clock_cycles_to_ns(cycles);
546554

547555
struct rtio_sqe *write_status_addr = rtio_sqe_acquire(data->rtio_ctx);
548556
struct rtio_sqe *read_status_reg = rtio_sqe_acquire(data->rtio_ctx);

drivers/sensor/adi/adxl372/adxl372_stream.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <zephyr/logging/log.h>
88
#include <zephyr/drivers/sensor.h>
9+
#include <zephyr/drivers/sensor_clock.h>
910

1011
#include "adxl372.h"
1112

@@ -424,12 +425,20 @@ static void adxl372_process_status1_cb(struct rtio *r, const struct rtio_sqe *sq
424425
void adxl372_stream_irq_handler(const struct device *dev)
425426
{
426427
struct adxl372_data *data = (struct adxl372_data *)dev->data;
427-
428+
uint64_t cycles;
429+
int rc;
428430
if (data->sqe == NULL) {
429431
return;
430432
}
431433

432-
data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
434+
rc = sensor_clock_get_cycles(&cycles);
435+
if (rc != 0) {
436+
LOG_ERR("Failed to get sensor clock cycles");
437+
rtio_iodev_sqe_err(data->sqe, rc);
438+
return;
439+
}
440+
441+
data->timestamp = sensor_clock_cycles_to_ns(cycles);
433442

434443
struct rtio_sqe *write_status_addr = rtio_sqe_acquire(data->rtio_ctx);
435444
struct rtio_sqe *read_status_reg = rtio_sqe_acquire(data->rtio_ctx);

drivers/sensor/asahi_kasei/akm09918c/akm09918c_async.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <zephyr/logging/log.h>
1010
#include <zephyr/rtio/work.h>
11+
#include <zephyr/drivers/sensor_clock.h>
1112

1213
#include "akm09918c.h"
1314

@@ -20,6 +21,7 @@ void akm09918c_submit_sync(struct rtio_iodev_sqe *iodev_sqe)
2021
struct akm09918c_data *data = dev->data;
2122
const struct sensor_chan_spec *const channels = cfg->channels;
2223
const size_t num_channels = cfg->count;
24+
uint64_t cycles;
2325
int rc;
2426

2527
/* Check if the requested channels are supported */
@@ -46,8 +48,15 @@ void akm09918c_submit_sync(struct rtio_iodev_sqe *iodev_sqe)
4648
return;
4749
}
4850

51+
rc = sensor_clock_get_cycles(&cycles);
52+
if (rc != 0) {
53+
LOG_ERR("Failed to get sensor clock cycles");
54+
rtio_iodev_sqe_err(iodev_sqe, rc);
55+
return;
56+
}
57+
4958
/* save information for the work item */
50-
data->work_ctx.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
59+
data->work_ctx.timestamp = sensor_clock_cycles_to_ns(cycles);
5160
data->work_ctx.iodev_sqe = iodev_sqe;
5261

5362
rc = k_work_schedule(&data->work_ctx.async_fetch_work, K_USEC(AKM09918C_MEASURE_TIME_US));

drivers/sensor/bosch/bma4xx/bma4xx.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <zephyr/logging/log.h>
1515
#include <zephyr/pm/device.h>
1616
#include <zephyr/rtio/work.h>
17+
#include <zephyr/drivers/sensor_clock.h>
1718

1819
LOG_MODULE_REGISTER(bma4xx, CONFIG_SENSOR_LOG_LEVEL);
1920
#include "bma4xx.h"
@@ -352,6 +353,7 @@ static void bma4xx_submit_one_shot(const struct device *dev, struct rtio_iodev_s
352353
struct bma4xx_encoded_data *edata;
353354
uint8_t *buf;
354355
uint32_t buf_len;
356+
uint64_t cycles;
355357
int rc;
356358

357359
/* Get the buffer for the frame, it may be allocated dynamically by the rtio context */
@@ -362,11 +364,18 @@ static void bma4xx_submit_one_shot(const struct device *dev, struct rtio_iodev_s
362364
return;
363365
}
364366

367+
rc = sensor_clock_get_cycles(&cycles);
368+
if (rc != 0) {
369+
LOG_ERR("Failed to get sensor clock cycles");
370+
rtio_iodev_sqe_err(iodev_sqe, rc);
371+
return;
372+
}
373+
365374
/* Prepare response */
366375
edata = (struct bma4xx_encoded_data *)buf;
367376
edata->header.is_fifo = false;
368377
edata->header.accel_fs = bma4xx->accel_fs_range;
369-
edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
378+
edata->header.timestamp = sensor_clock_cycles_to_ns(cycles);
370379
edata->has_accel = 0;
371380
edata->has_temp = 0;
372381

0 commit comments

Comments
 (0)