Skip to content
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

Isochronous IN (TX) without double-buffer #59

Closed
Seneral opened this issue Jun 20, 2020 · 4 comments
Closed

Isochronous IN (TX) without double-buffer #59

Seneral opened this issue Jun 20, 2020 · 4 comments

Comments

@Seneral
Copy link

Seneral commented Jun 20, 2020

I am using the STMF103 to implement a 50 to 300 byte transfer every 10 to 25ms to a host PC.
Currently, isochronous transfers have to be double-buffered - however since the PMA is limited to 512bytes on the STMF103, this means the isochronous packet size is in turn limited to less than 256bytes.
For my case, together with control ep, I could only have one double-buffered isochronous ep with a packet size of 224bytes if my understanding is correct.
While my design is flexible, I would prefer one large transfer over multiple smaller ones, mostly due to latency, so one larger buffer is preferrable to me. Since I'm only sending at max every 10ms I do not expect to need the second buffer.
Would it be possible to change this behaviour or is this a hardware limitation?
Currently I'm still in the phase where I don't need the bigger transfers, but I'd be interested to know for the future.

@dmitrystu
Copy link
Owner

AFAIK ISO EP double buffering for the F103 and similar USBFS can't be disabled due to hardware design. Anyway, let me check the docs.

@dmitrystu
Copy link
Owner

Yes. See RM008 Section 23.4.4 "Isochronous transfers"

@Seneral
Copy link
Author

Seneral commented Jun 22, 2020

Thank you for pointing me in the right direction. Seems clear that it is not intended to be used using a single buffer, and any possible solution will be non-standard.

However, for future reference, I might try these two things:

  1. Set TX_0 and TX_1 to the same packet buffers, without any other additional action taken. Hardware toggle of DTOG should have no effect then, however behaviour might be undefined
  2. Set one adress field to a small separate buffer and then manually toggle DTOG when I'm ready to send again, unless I want it to it shouldn't have to do anything with the small buffer

Will comment when I did try, but probably won't do for at least a few months.

@Seneral Seneral closed this as completed Jun 22, 2020
@Seneral
Copy link
Author

Seneral commented Jun 24, 2020

I have a related followup, not sure if it is an issues per se though.
The TX pma buffers are not cleared after an isochronous IN transfer has been completed, resulting in the same data being send 2 frames afterwards if you do not explicitly overwrite the PMA. I adressed this by a usbd_ep_write(usbd, ep, NULL, 0); call in the isochronous TX callback. Since all it needs to do is reset the PMA buffer count COUNTn_TX_x, this works as well:

if (!(*reg & USB_EP_DTOG_TX)) {
	tbl->tx1.cnt = 0;
} else {
	tbl->tx0.cnt = 0;
}

Since the TX callback is fired right when the DTOG is toggled (according to RM008), the usb driver user shouldn't have had the chance to write to the buffer yet, so I think this is a safe addition to the libusb_stm32 core (for isochronous transfers IN). This results in only the isochronous transfer immediately after a usbd_ep_write call to send the data, as expected.

On an unrelated note, I would think that a WCID example might be helpful. I recently implemented it and while it didn't take terribly long, it's simple copy-paste code that would be nice to have as an example, since I assume many people will be using WinUSB for windows. There are only two requests to cover and some custom data structures. If you want, I can create a simple example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants