* [Q] Frequency & duty cycle measurement?
@ 2025-01-21 15:19 Csókás Bence
2025-01-21 17:45 ` David Lechner
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Csókás Bence @ 2025-01-21 15:19 UTC (permalink / raw)
To: linux-iio, linux-kernel@vger.kernel.org, linux-arm-kernel,
timestamp
Cc: William Breathitt Gray, Jonathan Cameron, Lars-Peter Clausen,
Daniel Lezcano, Thomas Gleixner, Dipen Patel
Hi all,
we want to measure the frequency and duty cycle of a signal (relating to
power consumption) using a hardware timer in our SoC (Microchip
SAMA5D2). The hardware is capable of taking a snapshot of the timer
value into another dedicated register pair (RA, RB) on the
rising/falling edges, and a small `devmem`-based userspace utility was
created as a working PoC. Now we want to move to a "proper" kernelspace
solution.
However, none of the existing drivers seem to be able to do this; the
closest was `drivers/counter/microchip-tcb-capture.c`, but that only
seems to count one type of edge (rising/falling), and cannot give us the
time between them, which would be needed for duty cycle calculation. The
only other driver I could find was
`drivers/clocksource/timer-atmel-tcb.c`, which again seems incapable of
such measurements. Therefore, a new module will probably be needed; the
question then becomes: which API to implement.
As `microchip-tcb-capture.c` uses the Generic Counter Interface, that
was obviously a first stop. However, from what I could see, you can only
represent (1) the number of times an edge has been encountered, and (2)
rotary encodings (quadrature and direction-step decoders); and not the
time between edges.
IIO_ALTVOLTAGE and IIO_CHAN_INFO_FREQUENCY/_PHASE also seemed promising
(although the lack of IIO_CHAN_INFO_DUTY_CYCLE already posed a problem),
until I saw that all current drivers are frequency *generators*, and not
measurers, the latter seems to be completely unimplemented.
The only other contender I could find was the Hardware Timestamping
Engine (HTE), but again, it's not clear whether (1) the API is even
capable of relaying duty cycle information to userspace and (2) if it
is, how would one go about implementing it.
It is also entirely possible I missed a driver or API that could handle
this better, if so, please don't keep it to yourselves.
So, how could one go about implementing such a driver?
Bence
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Q] Frequency & duty cycle measurement?
2025-01-21 15:19 [Q] Frequency & duty cycle measurement? Csókás Bence
@ 2025-01-21 17:45 ` David Lechner
2025-01-27 15:00 ` William Breathitt Gray
2025-02-19 22:32 ` Dipen Patel
2 siblings, 0 replies; 9+ messages in thread
From: David Lechner @ 2025-01-21 17:45 UTC (permalink / raw)
To: Csókás Bence, linux-iio, linux-kernel@vger.kernel.org,
linux-arm-kernel, timestamp
Cc: William Breathitt Gray, Jonathan Cameron, Lars-Peter Clausen,
Daniel Lezcano, Thomas Gleixner, Dipen Patel
On 1/21/25 9:19 AM, Csókás Bence wrote:
> Hi all,
>
> we want to measure the frequency and duty cycle of a signal (relating to power consumption) using a hardware timer in our SoC (Microchip SAMA5D2). The hardware is capable of taking a snapshot of the timer value into another dedicated register pair (RA, RB) on the rising/falling edges, and a small `devmem`-based userspace utility was created as a working PoC. Now we want to move to a "proper" kernelspace solution.
>
> However, none of the existing drivers seem to be able to do this; the closest was `drivers/counter/microchip-tcb-capture.c`, but that only seems to count one type of edge (rising/falling), and cannot give us the time between them, which would be needed for duty cycle calculation. The only other driver I could find was `drivers/clocksource/timer-atmel-tcb.c`, which again seems incapable of such measurements. Therefore, a new module will probably be needed; the question then becomes: which API to implement.
>
> As `microchip-tcb-capture.c` uses the Generic Counter Interface, that was obviously a first stop. However, from what I could see, you can only represent (1) the number of times an edge has been encountered, and (2) rotary encodings (quadrature and direction-step decoders); and not the time between edges.
You might find some interesting reading at [1]. A few years ago, I started
adding support for an "edge capture unit" and timer on the TI EQEP quadrature
encoder driver in the counter subsystem. I never found time to keep working on
that to get it merged, but I've actually been looking at it again just last
week. It sounds quite similar, but I didn't consider the possibility of looking
at the duty cycle, only the rate.
[1]: https://lore.kernel.org/linux-iio/20211017013343.3385923-1-david@lechnology.com/
>
> IIO_ALTVOLTAGE and IIO_CHAN_INFO_FREQUENCY/_PHASE also seemed promising (although the lack of IIO_CHAN_INFO_DUTY_CYCLE already posed a problem), until I saw that all current drivers are frequency *generators*, and not measurers, the latter seems to be completely unimplemented.
A similar case came up somewhat recently [2] where it was suggested to add
IIO_FREQUENCY to be able to measure a clock frequency [3].
[2]: https://lore.kernel.org/linux-iio/20240624173105.909554-1-jbrunet@baylibre.com/
[3]: https://lore.kernel.org/linux-iio/20240629204025.683b1b69@jic23-huawei/
>
> The only other contender I could find was the Hardware Timestamping Engine (HTE), but again, it's not clear whether (1) the API is even capable of relaying duty cycle information to userspace and (2) if it is, how would one go about implementing it.
>
> It is also entirely possible I missed a driver or API that could handle this better, if so, please don't keep it to yourselves.
In the PWM subsystem, there is pwm_capture() which allows measuring period and
duty cycle, so could be exactly what you are looking for.
>
> So, how could one go about implementing such a driver?
>
> Bence
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Q] Frequency & duty cycle measurement?
2025-01-21 15:19 [Q] Frequency & duty cycle measurement? Csókás Bence
2025-01-21 17:45 ` David Lechner
@ 2025-01-27 15:00 ` William Breathitt Gray
2025-01-30 13:59 ` Csókás Bence
2025-02-19 22:32 ` Dipen Patel
2 siblings, 1 reply; 9+ messages in thread
From: William Breathitt Gray @ 2025-01-27 15:00 UTC (permalink / raw)
To: Csókás Bence
Cc: linux-iio, linux-kernel@vger.kernel.org, linux-arm-kernel,
timestamp, Jonathan Cameron, Lars-Peter Clausen, Daniel Lezcano,
Thomas Gleixner, Dipen Patel, dlechner
[-- Attachment #1: Type: text/plain, Size: 6196 bytes --]
On Tue, Jan 21, 2025 at 04:19:27PM +0100, Csókás Bence wrote:
> Hi all,
>
> we want to measure the frequency and duty cycle of a signal (relating to
> power consumption) using a hardware timer in our SoC (Microchip SAMA5D2).
> The hardware is capable of taking a snapshot of the timer value into another
> dedicated register pair (RA, RB) on the rising/falling edges, and a small
> `devmem`-based userspace utility was created as a working PoC. Now we want
> to move to a "proper" kernelspace solution.
>
> However, none of the existing drivers seem to be able to do this; the
> closest was `drivers/counter/microchip-tcb-capture.c`, but that only seems
> to count one type of edge (rising/falling), and cannot give us the time
> between them, which would be needed for duty cycle calculation. The only
> other driver I could find was `drivers/clocksource/timer-atmel-tcb.c`, which
> again seems incapable of such measurements. Therefore, a new module will
> probably be needed; the question then becomes: which API to implement.
>
> As `microchip-tcb-capture.c` uses the Generic Counter Interface, that was
> obviously a first stop. However, from what I could see, you can only
> represent (1) the number of times an edge has been encountered, and (2)
> rotary encodings (quadrature and direction-step decoders); and not the time
> between edges.
>
> IIO_ALTVOLTAGE and IIO_CHAN_INFO_FREQUENCY/_PHASE also seemed promising
> (although the lack of IIO_CHAN_INFO_DUTY_CYCLE already posed a problem),
> until I saw that all current drivers are frequency *generators*, and not
> measurers, the latter seems to be completely unimplemented.
>
> The only other contender I could find was the Hardware Timestamping Engine
> (HTE), but again, it's not clear whether (1) the API is even capable of
> relaying duty cycle information to userspace and (2) if it is, how would one
> go about implementing it.
>
> It is also entirely possible I missed a driver or API that could handle this
> better, if so, please don't keep it to yourselves.
>
> So, how could one go about implementing such a driver?
>
> Bence
Hi Bence,
You could use the Counter chrdev interface to get frequency of counter
events such as rising/falling edges, as well as associating timer values
and snapshots. Do you get an interrupt on each timer snapshot, or is it
just a circular array buffer that gets filled until your purge it? The
implementation might look something like the following.
In the kernel driver, you would push a counter event for each capture; I
assume your hardware issues an interrupt each time a rising/falling edge
occurs:
static irqreturn_t sama5d2_isr(int irq, void *dev_id)
{
struct counter_device *counter = dev_id;
counter_push_event(counter, COUNTER_EVENT_CAPTURE, 0);
return IRQ_HANDLED;
}
In the userspace application, you would setup a Counter "watch" to
collect each desired timer value on the respective Counter events; I
assume RA and RB are Count 0 and Count 1 respectively, but if they
represent something else please let me know:
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 type: Capture */
.event = COUNTER_EVENT_CAPTURE,
/* Device event channel 0 */
.channel = 0,
},
{
/* Component data: Count 1 count */
.component.type = COUNTER_COMPONENT_COUNT,
.component.scope = COUNTER_SCOPE_COUNT,
.component.parent = 1,
/* Event type: Capture */
.event = COUNTER_EVENT_CAPTURE,
/* Device event channel 0 */
.channel = 0,
},
};
...
int main(void)
{
int fd;
int i;
unsigned long long delta_ts, delta_ra, delta_rb;
double ra_frequency, rb_frequency, rb_ra;
struct counter_event first_capture[2], second_capture[2];
/* Open Counter chrdev */
fd = open("/dev/counter0", O_RDWR);
for (i = 0; i < 2; i++) {
/* Register all Counter watches */
ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + i);
}
/* Start collecting Counter events */
ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
for (;;) {
/* Read first Counter event capture */
read(fd, first_capture, sizeof(first_capture));
/* Read second Counter event capture */
read(fd, second_capture, sizeof(second_capture));
/* Within each capture, timestamp is the same so only
* first element of each capture needs to be compared */
delta_ts = second_capture[0].timestamp - first_capture[0].timestamp;
/* Compute deltas of timer register pair RA and RB.
delta_ra = second_capture[0].value - first_capture[0].value;
delta_rb = second_capture[1].value - first_capture[1].value;
ra_frequency = (double)delta_ra / delta_ts;
rb_frequency = (double)delta_rb / delta_ts;
rb_ra = (double)delta_rb / delta_ra;
printf("RA frequency: %ld\n"
"RB frequency: %ld\n"
"RB per RA: %ld\n"
ra_frequency, rb_frequency, rb_ra);
}
return 0;
}
If RA and RB are provided as a memory buffer on your device, you can
instead expose them via DEFINE_COUNTER_ARRAY_CAPTURE() such as the
ti-ecap-capture driver does, then perform your userspace computations
by utilizing those respective "capture" array attribute values (via
chrdev like the example above or alternatively via sysfs).
Do you think this design would work for your needs?
William Breathitt Gray
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Q] Frequency & duty cycle measurement?
2025-01-27 15:00 ` William Breathitt Gray
@ 2025-01-30 13:59 ` Csókás Bence
2025-02-04 23:37 ` William Breathitt Gray
0 siblings, 1 reply; 9+ messages in thread
From: Csókás Bence @ 2025-01-30 13:59 UTC (permalink / raw)
To: William Breathitt Gray
Cc: linux-iio, linux-kernel@vger.kernel.org, linux-arm-kernel,
timestamp, Jonathan Cameron, Lars-Peter Clausen, Daniel Lezcano,
Thomas Gleixner, Dipen Patel, dlechner
Hi William,
On 2025. 01. 27. 16:00, William Breathitt Gray wrote:
> In the userspace application, you would setup a Counter "watch" to
> collect each desired timer value on the respective Counter events; I
> assume RA and RB are Count 0 and Count 1 respectively, but if they
> represent something else please let me know:
>
> 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 type: Capture */
> .event = COUNTER_EVENT_CAPTURE,
> /* Device event channel 0 */
> .channel = 0,
> },
> {
> /* Component data: Count 1 count */
> .component.type = COUNTER_COMPONENT_COUNT,
> .component.scope = COUNTER_SCOPE_COUNT,
> .component.parent = 1,
> /* Event type: Capture */
> .event = COUNTER_EVENT_CAPTURE,
> /* Device event channel 0 */
> .channel = 0,
> },
> };
> ...
> int main(void)
> {
> int fd;
> int i;
> unsigned long long delta_ts, delta_ra, delta_rb;
> double ra_frequency, rb_frequency, rb_ra;
> struct counter_event first_capture[2], second_capture[2];
>
> /* Open Counter chrdev */
> fd = open("/dev/counter0", O_RDWR);
>
> for (i = 0; i < 2; i++) {
> /* Register all Counter watches */
> ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + i);
> }
> /* Start collecting Counter events */
> ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
>
> for (;;) {
> /* Read first Counter event capture */
> read(fd, first_capture, sizeof(first_capture));
> /* Read second Counter event capture */
> read(fd, second_capture, sizeof(second_capture));
>
> /* Within each capture, timestamp is the same so only
> * first element of each capture needs to be compared */
> delta_ts = second_capture[0].timestamp - first_capture[0].timestamp;
> /* Compute deltas of timer register pair RA and RB.
> delta_ra = second_capture[0].value - first_capture[0].value;
> delta_rb = second_capture[1].value - first_capture[1].value;
>
> ra_frequency = (double)delta_ra / delta_ts;
> rb_frequency = (double)delta_rb / delta_ts;
> rb_ra = (double)delta_rb / delta_ra;
>
> printf("RA frequency: %ld\n"
> "RB frequency: %ld\n"
> "RB per RA: %ld\n"
> ra_frequency, rb_frequency, rb_ra);
> }
>
> return 0;
> }
>
> If RA and RB are provided as a memory buffer on your device, you can
> instead expose them via DEFINE_COUNTER_ARRAY_CAPTURE() such as the
> ti-ecap-capture driver does, then perform your userspace computations
> by utilizing those respective "capture" array attribute values (via
> chrdev like the example above or alternatively via sysfs).
Thanks for your extensive explanation! With
DEFINE_COUNTER_ARRAY_CAPTURE() I was able to expose RA and RB as
`/sys/bus/counter/devices/counter0/count0/capture{0,1}`, and could
verify that by replacing `devmem` calls with read()-reopen(), our PoC
code still works. Now I want to use the chardev interface, but I
couldn't find how to set up the watches appropriately. So far I have:
{
.component.type = COUNTER_COMPONENT_EXTENSION,
// also tried COUNTER_COMPONENT_COUNT
.component.scope = COUNTER_SCOPE_COUNT,
.component.parent = 0,
.component.id = X, // also tried this instead:
// .channel = X,
.event = COUNTER_EVENT_CAPTURE,
},
However, with this, the first read() never comes back.
Bence
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Q] Frequency & duty cycle measurement?
2025-01-30 13:59 ` Csókás Bence
@ 2025-02-04 23:37 ` William Breathitt Gray
2025-02-05 9:30 ` Csókás Bence
0 siblings, 1 reply; 9+ messages in thread
From: William Breathitt Gray @ 2025-02-04 23:37 UTC (permalink / raw)
To: Csókás Bence
Cc: linux-iio, linux-kernel@vger.kernel.org, linux-arm-kernel,
timestamp, Jonathan Cameron, Lars-Peter Clausen, Daniel Lezcano,
Thomas Gleixner, Dipen Patel, dlechner
[-- Attachment #1: Type: text/plain, Size: 3751 bytes --]
On Thu, Jan 30, 2025 at 02:59:20PM +0100, Csókás Bence wrote:
> Hi William,
>
> On 2025. 01. 27. 16:00, William Breathitt Gray wrote:
> > If RA and RB are provided as a memory buffer on your device, you can
> > instead expose them via DEFINE_COUNTER_ARRAY_CAPTURE() such as the
> > ti-ecap-capture driver does, then perform your userspace computations
> > by utilizing those respective "capture" array attribute values (via
> > chrdev like the example above or alternatively via sysfs).
>
> Thanks for your extensive explanation! With DEFINE_COUNTER_ARRAY_CAPTURE() I
> was able to expose RA and RB as
> `/sys/bus/counter/devices/counter0/count0/capture{0,1}`, and could verify
> that by replacing `devmem` calls with read()-reopen(), our PoC code still
> works. Now I want to use the chardev interface, but I couldn't find how to
> set up the watches appropriately. So far I have:
>
> {
> .component.type = COUNTER_COMPONENT_EXTENSION,
> // also tried COUNTER_COMPONENT_COUNT
> .component.scope = COUNTER_SCOPE_COUNT,
> .component.parent = 0,
> .component.id = X, // also tried this instead:
> // .channel = X,
> .event = COUNTER_EVENT_CAPTURE,
> },
>
> However, with this, the first read() never comes back.
>
> Bence
Hi Bence,
Are you still having trouble with this? Is "X" the
capture{0,1}_component_id value?
I apologize, the Generic Counter character device interface is
underdocumented so it can be a bit confusing at first; I'll submit a
patch improving the documentation later this cycle when I get a chance.
For now, let's walk through how to create an appropriate Counter watch
for the capture extension components you have.
The first step is to decide which event we'll monitor and on which
channel: we want to monitor Capture events so that's
COUNTER_EVENT_CAPTURE, and we want event channel 0 (n.b. 0 because
that's the channel parameter value passed to counter_push_event() in the
driver).
The next step is to choose the components you wish to watch: Count 0's
capture0 and capture1 extensions. So type is COUNTER_COMPONENT_EXTENSION
because we want to watch extensions, scope is COUNTER_SCOPE_COUNT
because we want Count extensions, and parent is 0 because we want
Count 0's Count extensions.
Finally, we need to set the component id for each extension. You get a
particular component's id by reading the respective *_component_id sysfs
attribute: so for capture{0,1} you would read capture{0,1}_component_id
respectively. These component id values potentially can change with
future driver updates, so for robustness your userspace application
should read the respective *_component_id sysfs attribute itself rather
than hardcoding the component id in the Counter watch.
However, for the sake of simplicity in this example, I'll assume the
component ids are 42 and 43 respectively for capture0 and capture1. That
gives us the following two watches:
{
.component.type = COUNTER_COMPONENT_EXTENSION,
.component.scope = COUNTER_SCOPE_COUNT,
.component.parent = 0,
.component.id = 42,
.event = COUNTER_EVENT_CAPTURE,
.channel = 0,
},
{
.component.type = COUNTER_COMPONENT_EXTENSION,
.component.scope = COUNTER_SCOPE_COUNT,
.component.parent = 0,
.component.id = 43,
.event = COUNTER_EVENT_CAPTURE,
.channel = 0,
},
Does this resolve your chardev read issue? If you're still having
troubling, just let me know and we can troubleshoot further to figure
out what's going on.
William Breathitt Gray
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Q] Frequency & duty cycle measurement?
2025-02-04 23:37 ` William Breathitt Gray
@ 2025-02-05 9:30 ` Csókás Bence
2025-02-05 9:58 ` Csókás Bence
0 siblings, 1 reply; 9+ messages in thread
From: Csókás Bence @ 2025-02-05 9:30 UTC (permalink / raw)
To: William Breathitt Gray
Cc: linux-iio, linux-kernel@vger.kernel.org, linux-arm-kernel,
timestamp, Jonathan Cameron, Lars-Peter Clausen, Daniel Lezcano,
Thomas Gleixner, Dipen Patel, dlechner
Hi,
On 2025. 02. 05. 0:37, William Breathitt Gray wrote:
> Are you still having trouble with this? Is "X" the
> capture{0,1}_component_id value?
X is 0/1 from `/sys/bus/counter/devices/counter0/count0/capture{0,1}`,
which is also equal to the respective `capture{0,1}_component_id`, since
I don't have any other counters. I checked that beforehand.
> I apologize, the Generic Counter character device interface is
> underdocumented so it can be a bit confusing at first; I'll submit a
> patch improving the documentation later this cycle when I get a chance.
> For now, let's walk through how to create an appropriate Counter watch
> for the capture extension components you have.
After much tinkering and reading of the `counter-chrdev.c` code, I now
see *something*, although it's much slower to make a measurement than
the sysfs `reopen()` hack.
> The first step is to decide which event we'll monitor and on which
> channel: we want to monitor Capture events so that's
> COUNTER_EVENT_CAPTURE, and we want event channel 0 (n.b. 0 because
> that's the channel parameter value passed to counter_push_event() in the
> driver).
>
> The next step is to choose the components you wish to watch: Count 0's
> capture0 and capture1 extensions. So type is COUNTER_COMPONENT_EXTENSION
> because we want to watch extensions, scope is COUNTER_SCOPE_COUNT
> because we want Count extensions, and parent is 0 because we want
> Count 0's Count extensions.
>
> Finally, we need to set the component id for each extension. You get a
> particular component's id by reading the respective *_component_id sysfs
> attribute: so for capture{0,1} you would read capture{0,1}_component_id
> respectively. These component id values potentially can change with
> future driver updates, so for robustness your userspace application
> should read the respective *_component_id sysfs attribute itself rather
> than hardcoding the component id in the Counter watch.
>
> However, for the sake of simplicity in this example, I'll assume the
> component ids are 42 and 43 respectively for capture0 and capture1. That
> gives us the following two watches:
>
> {
> .component.type = COUNTER_COMPONENT_EXTENSION,
> .component.scope = COUNTER_SCOPE_COUNT,
> .component.parent = 0,
> .component.id = 42,
> .event = COUNTER_EVENT_CAPTURE,
> .channel = 0,
> },
> {
> .component.type = COUNTER_COMPONENT_EXTENSION,
> .component.scope = COUNTER_SCOPE_COUNT,
> .component.parent = 0,
> .component.id = 43,
> .event = COUNTER_EVENT_CAPTURE,
> .channel = 0,
> },
>
> Does this resolve your chardev read issue? If you're still having
> troubling, just let me know and we can troubleshoot further to figure
> out what's going on.
I had no success using `channel = 0`, only data from `capture0` comes
back. If I set both `channel` AND `component.id` to X, then I start to
see similar values than what I get from reading sysfs. (For now I
hard-coded all values; I agree that the correct way would be to read
component IDs from sysfs, but this is still a PoC...)
Did I do something wrong in implementing the driver maybe? (See the
submitted patches.) And any idea as to why I might be seeing the slowdown?
Bence
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Q] Frequency & duty cycle measurement?
2025-02-05 9:30 ` Csókás Bence
@ 2025-02-05 9:58 ` Csókás Bence
0 siblings, 0 replies; 9+ messages in thread
From: Csókás Bence @ 2025-02-05 9:58 UTC (permalink / raw)
To: William Breathitt Gray
Cc: linux-iio, linux-kernel@vger.kernel.org, linux-arm-kernel,
timestamp, Jonathan Cameron, Lars-Peter Clausen, Daniel Lezcano,
Thomas Gleixner, Dipen Patel, dlechner
Hi,
On 2025. 02. 05. 10:30, Csókás Bence wrote:
> Hi,
>
> On 2025. 02. 05. 0:37, William Breathitt Gray wrote:
>> The first step is to decide which event we'll monitor and on which
>> channel: we want to monitor Capture events so that's
>> COUNTER_EVENT_CAPTURE, and we want event channel 0 (n.b. 0 because
>> that's the channel parameter value passed to counter_push_event() in the
>> driver).
Ah, I push 0 and 1 for the two interrupts... So that's why `channel` has
to be 0 and 1 as well. Does it make sense to do it this way, or should I
push on event channel 0 always?
> I had no success using `channel = 0`, only data from `capture0` comes
> back. If I set both `channel` AND `component.id` to X, then I start to
> see similar values than what I get from reading sysfs. (For now I
> hard-coded all values; I agree that the correct way would be to read
> component IDs from sysfs, but this is still a PoC...)
>
> Did I do something wrong in implementing the driver maybe? (See the
> submitted patches.) And any idea as to why I might be seeing the slowdown?
The slowdown is still a mystery though...
Bence
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Q] Frequency & duty cycle measurement?
2025-01-21 15:19 [Q] Frequency & duty cycle measurement? Csókás Bence
2025-01-21 17:45 ` David Lechner
2025-01-27 15:00 ` William Breathitt Gray
@ 2025-02-19 22:32 ` Dipen Patel
2025-02-26 13:56 ` Csókás Bence
2 siblings, 1 reply; 9+ messages in thread
From: Dipen Patel @ 2025-02-19 22:32 UTC (permalink / raw)
To: Csókás Bence, linux-iio, linux-kernel@vger.kernel.org,
linux-arm-kernel, timestamp
Cc: William Breathitt Gray, Jonathan Cameron, Lars-Peter Clausen,
Daniel Lezcano, Thomas Gleixner
On 1/21/25 7:19 AM, Csókás Bence wrote:
> he hardware is capable of taking a snapshot of the timer value into another
> dedicated register pair (RA, RB) on the rising/falling edges, and a small
> `devmem`-based userspace utility was created as a working PoC
I am late to the party :) Seems above statement looks lot like what HTE
subsystem is doing. Right now, only userspace path is through the gpiolib
due to usage that time was limited to GPIOs. However, we can extend HTE to meet
this scenario.
Thanks,
Best Regards,
Dipen Patel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Q] Frequency & duty cycle measurement?
2025-02-19 22:32 ` Dipen Patel
@ 2025-02-26 13:56 ` Csókás Bence
0 siblings, 0 replies; 9+ messages in thread
From: Csókás Bence @ 2025-02-26 13:56 UTC (permalink / raw)
To: Dipen Patel, linux-iio, linux-kernel@vger.kernel.org,
linux-arm-kernel, timestamp
Cc: William Breathitt Gray, Jonathan Cameron, Lars-Peter Clausen,
Daniel Lezcano, Thomas Gleixner
Hi,
On 2025. 02. 19. 23:32, Dipen Patel wrote:
> On 1/21/25 7:19 AM, Csókás Bence wrote:
>> he hardware is capable of taking a snapshot of the timer value into another
>> dedicated register pair (RA, RB) on the rising/falling edges, and a small
>> `devmem`-based userspace utility was created as a working PoC
> I am late to the party :) Seems above statement looks lot like what HTE
> subsystem is doing. Right now, only userspace path is through the gpiolib
> due to usage that time was limited to GPIOs. However, we can extend HTE to meet
> this scenario.
Yes, I had the same impression. But since there was already a driver for
this block in the counter subsystem, it was easier to extend that to our
use case.
> Thanks,
> Best Regards,
> Dipen Patel
>
Bence
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-02-26 13:56 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-21 15:19 [Q] Frequency & duty cycle measurement? Csókás Bence
2025-01-21 17:45 ` David Lechner
2025-01-27 15:00 ` William Breathitt Gray
2025-01-30 13:59 ` Csókás Bence
2025-02-04 23:37 ` William Breathitt Gray
2025-02-05 9:30 ` Csókás Bence
2025-02-05 9:58 ` Csókás Bence
2025-02-19 22:32 ` Dipen Patel
2025-02-26 13:56 ` Csókás Bence
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).