Tool/software:
We are using the eqep driver from ti-processor-sdk-linux-rt-am64xx-evm-11.00.09.04. We would like to get count values using the char driver, sysfs access is too slow. Using the attached code we are able to read the events for overflow and underflow. How can we get the count value using a simple read of the character device?
// SPDX-License-Identifier: GPL-2.0-only /* Counter - example userspace application * * The userspace application opens /dev/counter0, configures the * COUNTER_EVENT_INDEX event channel 0 to gather Count 0 count and Count * 1 count, and prints out the data as it becomes available on the * character device node. * * Copyright (C) 2021 William Breathitt Gray * * Modified to work with TI EQEP device driver for AM64 SDK 11.00.09.04 * Only channel 0 and count 0 exist on this device. * * Copyright (C) 2025 Sick Inc. */ #include <errno.h> #include <fcntl.h> #include <linux/counter.h> #include <stdio.h> #include <string.h> #include <sys/ioctl.h> #include <unistd.h> // valid events: // COUNTER_EVENT_OVERFLOW // COUNTER_EVENT_UNDERFLOW // and maybe // COUNTER_EVENT_DIRECTION_CHANGE // COUNTER_EVENT_TIMEOUT static const char * const counter_event_type_name[] = { "COUNTER_EVENT_OVERFLOW", "COUNTER_EVENT_UNDERFLOW", "COUNTER_EVENT_OVERFLOW_UNDERFLOW", "COUNTER_EVENT_THRESHOLD", "COUNTER_EVENT_INDEX", "COUNTER_EVENT_CHANGE_OF_STATE", "COUNTER_EVENT_CAPTURE", "COUNTER_EVENT_DIRECTION_CHANGE", }; static struct counter_watch watches[2] = { { /* Component data: Count 0 count */ .component.type = COUNTER_COMPONENT_COUNT, .component.scope = COUNTER_SCOPE_COUNT, .component.parent = 0, .event = COUNTER_EVENT_OVERFLOW, /* Device event channel 0 */ .channel = 0, }, { /* Component data: Count 1 count */ .component.type = COUNTER_COMPONENT_COUNT, .component.scope = COUNTER_SCOPE_COUNT, .component.parent = 0, .event = COUNTER_EVENT_UNDERFLOW, /* Device event channel 0 */ .channel = 0, }, }; int main(void) { int fd; int ret; int i; struct counter_event event_data; printf("counter example\n"); fd = open("/dev/counter0", O_RDWR); if (fd == -1) { perror("Unable to open /dev/counter0"); return 1; } for (i = 0; i < 2; i++) { ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + i); if (ret == -1) { fprintf(stderr, "Error adding watches[%d]: %s\n", i, strerror(errno)); return 1; } } ret = ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL); if (ret == -1) { perror("Error enabling events"); return 1; } for (;;) { ret = read(fd, &event_data, sizeof(event_data)); if (ret == -1) { perror("Failed to read event data"); return 1; } if (ret != sizeof(event_data)) { fprintf(stderr, "Failed to read event data\n"); return -EIO; } printf("Timestamp: %llu\tData: %llu\t event: %s\tch: %d\n", event_data.timestamp, event_data.value, counter_event_type_name[event_data.watch.event], event_data.watch.channel); } return 0; }