|
From: Kustaa N. <ea...@ea...> - 2024-06-09 06:56:11
|
Hi, This is NOT libusb problem but I hope it is ok to try to fish for some help here: I have a problem with my hobby project USB HID device, described more in more detail here: https://forum.microchip.com/s/topic/a5CV40000001UVVMA2/t396565 The problem is rare but it is guaranteed to happen if let the system run for day(s). I try to be brief and specific here. The device enumerates fine and the HID descriptors are fetched and all that initial stuff works. I only use EP2 to talk to the device, I only send and received 64 byte reports. On the host side (Linux/Raspberry Pi) the communication is with standard file system write/poll/read calls. When it fails I the read polls always timeout. Re-opening the device restores normal communication. Question: am I correct that apart from possible renumeration my device firmware cannot know if the device handle is closed or opened on the host side? On the device side all the communication happens in main loop which is very simple, see below. My question is if it is ok to just rely on the assumption that when ever the SIE in the MCU signals for the EP2 that the buffer is available not owned by the firmware there is a new output report (out EP) or I can fill in the buffer with next input report (in EP)? Or do I need to gather for some other situations? I have assumed that the USB SIE takes care of the communication up to the transfer level, transmitting, re-transmitting and ACKing as necessary or NACK:in if my main loop has not have time processes the previous transfer. Is this correct? I do have an interrupt service that handles all the EP0 control stuff. But once the communication with the EP2 has started I should not see any of that stuff anyway unless the device gets enumerated? I copied this behavior plus ten years ago from some code which I cannot re-call and I'm now questioning every assumption. wbr Kusti The main loop: while (1) { if (!(ep2_o.STAT & UOWN)) { // new data from host, so process it ... read output report from the USB RAM // turn the buffer over to SIE so we can get more data ep2_o.CNT = 64; if (ep2_o.STAT & DTS) ep2_o.STAT = DTSEN; else ep2_o.STAT = DTS | DTSEN; ep2_o.STAT |= UOWN; } if (!(ep2_i.STAT & UOWN)) { // we own the USB buffer, so update data going to the host ... write data for the input report to the USB RAM // turn the buffer over to the SIE so the host will pick it up ep2_i.CNT = 64; if (ep2_i.STAT & DTS) ep2_i.STAT = DTSEN; else ep2_i.STAT = DTS | DTSEN; ep2_i.STAT |= UOWN; } } |