-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HID SOF interrupt support #2180
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the reason to add sof callback to hid driver ? Could you explain why this is needed.
Hi hathach, ive added in the SOF callback to the HID driver specifically for fast mouse response and minimum latency. I've put it here since I would like to use tinyUSB to follow the current fastest open-source mouse firmware on the market in terms of click latency (after razer) https://github.com/zaunkoenig-firmware/m2k-firmware/blob/main/mouse/Src/main.c you can see here they wait for a SOF interrupt before starting the routine and getting data from the sensor/buttons then send it out. Since there is only 125us frame time between packets at 8khz polling rate. Edit: |
I'll chime in, as I've worked on high performance firmware for input devices before. I do see usefulness in a SOF interrupt, we can use it to assemble the HID packets at the very last second to minimize latency (Yes it is a very small latency gain, but the latency is there nonetheless), that said the vast majority of use cases will not need this so I think it might make sense to gate it behind a configuration option. Honestly a SOF interrupt could be useful as a configurable option for all drivers, but that's beyond the scope of this PR. |
This would be very useful. Working on a gamepad at the moment and this would help a ton with reducing latency at lower interval inputs. |
I would assume the GP2040-CE firmware would also benefit as well. Pretty sure the GP2040-CE is also one of the fastest on the market already since it uses the 2 cores of the RP2040 which is cool. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
@Rocky04 I don't understand where you are trying to get, please be concise, and avoid massive information dumps and rambling like you are doing, it's hard to parse to parse without the context of what you're thinking, also try to reach a conclusion, ideally something actionable, right now you're just wasting everyone's time. I think you're suggesting that the SOF interrupts not reliable, and you're right, that's a given some architectures don't even implement it... but I fail to realize why that matters here, perhaps we can't use to assemble a packet just in time, you can still use it as synchronizing signal, even if like you are mentioning it's not guaranteed to be within a defined interval, either way all of that is out of the scope of the PR. What is being suggested here is to simply expose the SOF interrupt to "user-space", it is implementation defined what is to be done with it, it is not something the class driver or other core functionality would rely on. You also seem to be confusing the USB specification domain with the implementations, this is about the SOF interrupt, which is not part of the USB specification, and is completely tied to the USB core architecture (the implementation). No offense, but I'm going to mark your comments as off topic |
This comment was marked as off-topic.
This comment was marked as off-topic.
@Xelus22 The added code from you in the I created an example PR #2213 which implements a general SOF callback independent from the class device driver. Edit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My complains as a review...
(void) rhport; | ||
tud_hid_sof_cb(frame_count); | ||
} | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A function executed directly in a synchron manner isn't a callback. Meaning don't put a "_cb" in an "_isr" because these names refer to different things.
In this function only code should be placed which needs to be executed inside the interrupt service routine right after when the start of frame occurred.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a callback because it's a configurable function defined by the user, not because of how it is called
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are naming conventions for a reason. So people who read a function name have an expectation what the function does. Messing around with that only causes issues. It has nothing to do if it's configurable or not. The word callback itself refers to an inverted direction.
Just have a look at the other TinyUSB callbacks, like tud_mount_cb()
. The event for it is invoked (but the function isn't executed) in the ISR. It's later called asynchron in the main loop from tud_task()
. But audiod_sof_isr()
on the other hand is executed in the ISR. So the "_cb" functions are executed in the main loop and the "_isr" functions within the interrupt service routine and these are two different things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You cant just make up conventions
https://en.m.wikipedia.org/wiki/Callback_(computer_programming)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the way how it used here in this repro. Feel free to prove me wrong by pointing to a TinyUSB standard function referred as callback in its name which isn't called indirectly in the main loop. Would be appreciated...
Don't get me wrong, it's technical a callback in a general sense but not in the context of this repro. Here there is a distinction.
driver->sof(event.rhport, event.sof.frame_count); | ||
} | ||
} | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the callback should be executed but instead the ISR function is executed a second time.
@@ -119,7 +119,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = | |||
.open = hidd_open, | |||
.control_xfer_cb = hidd_control_xfer_cb, | |||
.xfer_cb = hidd_xfer_cb, | |||
.sof = NULL | |||
.sof = hidd_sof_isr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assigned ISR function at this place gets called here:
Line 1132 in cfe8ca3
driver->sof(event->rhport, event->sof.frame_count); |
@@ -118,6 +118,8 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); | |||
// Note: For composite reports, report[0] is report ID | |||
TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); | |||
|
|||
// Invoked when received SOF interrupt | |||
TU_ATTR_WEAK void tud_hid_sof_cb(uint32_t frame_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a callback it should be invoked in the ISR due to the SOF event and called here:
Line 599 in cfe8ca3
case DCD_EVENT_SOF: |
This is better, you should make extra effort from the start.
I agree, I made the same suggestion.
This is precisely what I noted as being an implementation detail.
It's not contrary, I made no mention of "HID specific" or "general callback", just that this is about exposing the SOF, and you seemed to be talking about firmware implementation details.
Ok.
This is not twitter, I did not give my thoughts, I asked you to explain yourself better because I could make nothing of it. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
late response as usual, seems like there is a bit of heated dicussion in this issue, I hope we are still cool and don't take that personal.
Thank you for explanation, my take on this is we should use generic SOF. I did actually add API for generic SOF previously when doing audio sof for feedback. Though I back out on generic API since there is no usage back then https://github.com/hathach/tinyusb/pull/1381/files#diff-290e049d139d4c4ba09224b43d2f53d2ea705c59ba979c3881143be80d5402deR91 Maybe it is good time to re-add it. |
@hathach If that is supposed to be controlled by the individual implementation why is there one already present just for audio? |
I just removed that in one of follow-up PR along with other managing code, forgot which one. Yeah, we can re-add that generic code to enable SOF void tud_sof_isr_set(tud_sof_isr_t sof_isr); Though, maybe we should continue to use the weak, named callback. I forgot why I went with dynamic function pointer last time (which is not consistent with other driver callback). I will re-evalate this later. Sum up we could add SOF callback, just not under the name of HID since HID isn't required SOF to function properly like audio feedback. |
I would prefer to have both, a more general SOF callback which is weak and executed by Edit: So I think the SOF ISR function of the driver should be set dynamically. So for this only that function need to be re-added. |
The issue right now with setting the function pointer for a driver specific SOF callback (here used in a common sense), which is executed within the ISR, is that this would need to know to which driver it should be applied in the case multiple configurations are used. The driver name is only present on a debug level so that can't be used. Because of this I think it would be better to let it as is so that the SOF ISR is purely driver related. Meaning if that behavior should be changed or controlled that should only be possible by using a vendor defined driver. For that the SOF ISR should be opened up just for that. Here is a draft for this #2220. |
I used to think of deferred SOF, but from last work with audio feedback. I am not quite sure if we still need that. what is point of SOF where is not invoked in the start of frame, other transferred is probably completed by the time callback is invoked in thread context. Until we really need it, we won't add it.
sof_isr in usbd driver is only available for driver that can be managed by usbd, e.g audio with feedback enpoint is enabled, sof is enabled, and disable along with the interface. I don't see the point to add sof_isr for vendor. Vendor manage SOF in application and should use the generic tud_sof_enable() |
I'm not really sure what you mean... For me there are two places, executed a bit later in the main loop via a general callback and directly as fast as possible when the MCU handles the SOF interrupt via a specific driver callback for specific things. I don't get why you mentioning I also think a vendor defined driver should have full control and so I don't see any reason why the SOF ISR should not be exposed for Edit: |
not all thing we thought might be needed will be added though. Only thing that we are sure people will use. I don't see the point to calculate start of SOF ISR with SOF_CB. When you need SOF_ISR, you need it because you have to do something on-time, otherwise something else will break. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should only add sof_isr that can be auto managed (on/off when needed) to class driver e.g audio with feedback enpoint on/off along with its audio streaming interface.
Since HID does not need it to function properly (thing breaks with audio if not), we can add an generic sof cb in isr for this purpose for app to turn it on and off when it wants. You don't need to make any changes for this PR. I remembered added that sometime ago (then reverted), I could try to re-add it when possible. Thank you for brining up this PR and issue.
Hi, I'm really sorry to revive this issue but I tought it might be a good place to figure out what the current status on a generic SOF callback is? Aplogies if I missed anyhting, but I couldn't relaly find any information on this. |
Thanks for everyone's effort. Generic user land SOF support has been merged in #2213. One can use |
Describe the PR
Adds HID SOF support.
Additional context
Tested and working on CH32V307Questions
hidd_sof_isr
orhidd_sof_cb
? (usedisr
since the audio one uses that too)uint8_t rhport
intohidd_sof_isr
?