Skip to content

Commit 173e047

Browse files
committed
samples: hid-keyboard: use sample to measure SOF event latency
The keyboard sample is quite simple and there is not much happening outside of the USB controller activity, use it to measure the latency since the SOF interrupt. This approach only works with UDC drivers that update the frame number on the SOF interrupt. Signed-off-by: Johann Fischer <[email protected]>
1 parent 5b87409 commit 173e047

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

samples/subsys/usb/hid-keyboard/prj.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CONFIG_USBD_LOG_LEVEL_WRN=y
66
CONFIG_USBD_HID_LOG_LEVEL_WRN=y
77
CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y
88
CONFIG_SAMPLE_USBD_PID=0x0007
9-
CONFIG_SAMPLE_USBD_REMOTE_WAKEUP=y
9+
CONFIG_SAMPLE_USBD_REMOTE_WAKEUP=n
1010

1111
CONFIG_GPIO=y
1212
CONFIG_INPUT=y

samples/subsys/usb/hid-keyboard/src/main.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@
1212
#include <zephyr/input/input.h>
1313

1414
#include <zephyr/usb/usbd.h>
15+
#include <zephyr/drivers/usb/udc.h>
1516
#include <zephyr/usb/class/usbd_hid.h>
1617

1718
#include <zephyr/logging/log.h>
1819
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
1920

21+
#if CONFIG_UDC_ENABLE_SOF
22+
static const struct device *const udc_dev = DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0));
23+
#endif
24+
2025
static const uint8_t hid_report_desc[] = HID_KEYBOARD_REPORT_DESC();
2126

2227
enum kb_leds_idx {
@@ -133,6 +138,27 @@ static void kb_output_report(const struct device *dev, const uint16_t len,
133138
kb_set_report(dev, HID_REPORT_TYPE_OUTPUT, 0U, len, buf);
134139
}
135140

141+
#if CONFIG_UDC_ENABLE_SOF
142+
/*
143+
* Use it to measure the latency since the SOF interrupt. Do not blindly trust
144+
* the value unless it has been verified with e.g. an osciloscope. The value is
145+
* the best case, because in this sample not much happens outside the USB
146+
* controller activity. It only works with UDC drivers that update the frame
147+
* number on the SOF interrupt.
148+
*/
149+
static void kb_sof(const struct device *dev)
150+
{
151+
uint16_t fnumber = udc_get_frame_number(udc_dev);
152+
uint64_t stamp = udc_get_sof_stamp(udc_dev);
153+
154+
(void)gpio_pin_toggle_dt(&kb_leds[0]);
155+
if (fnumber == 1366) {
156+
LOG_INF("Time since SOF ISR %llu us",
157+
k_cyc_to_us_ceil64(k_cycle_get_64() - stamp));
158+
}
159+
}
160+
#endif
161+
136162
struct hid_device_ops kb_ops = {
137163
.iface_ready = kb_iface_ready,
138164
.get_report = kb_get_report,
@@ -141,6 +167,7 @@ struct hid_device_ops kb_ops = {
141167
.get_idle = kb_get_idle,
142168
.set_protocol = kb_set_protocol,
143169
.output_report = kb_output_report,
170+
IF_ENABLED(CONFIG_UDC_ENABLE_SOF, (.sof = kb_sof,))
144171
};
145172

146173
/* doc device msg-cb start */

0 commit comments

Comments
 (0)