Skip to content

Feat cdc python #1

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

Closed
wants to merge 8 commits into from
Closed

Conversation

linted
Copy link

@linted linted commented Jul 28, 2023

Fixed an major error in the _CS_DESC_TYPE message being sent by the CDCControlInterface. Changed to take advantage of the ring buffer found in the midi interface to implement a better read cache mechanism.

@hoihu
Copy link
Owner

hoihu commented Sep 3, 2023

Hi @linted

I'm sorry to come back late, I did not see your PR. Thanks a lot for the feedback. I guess we have corrected bugs in parallel....

I've updated my branch since (you might have seen that) and corrected some of the bugs that you also have noticed. I just now added support for set_line_coding and set_control_line so you might have a look if that beneficial for you too?

Regarding the ring buffer, I settled for just creating a bytearray each time read is called. That's horribly memory inefficent and needs to be addressed for sure. At least now it should read-in all available data from the endpoints (this wasn't the case before, as you may have figured out too)

Maybe I've overseen some of the issues you've pointed out. Would you mind to comment on the PR projectgus#2 ? I think that's better since @projectgus can also share his view.

Copy link
Owner

@hoihu hoihu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few bugs solved in the PR, thanks!

I can correct those obvious ones with reference to you. Otherwise, would be good to split the ringbuffer addition from the rest and place a separate PR.


def get_itf_descriptor(self, num_eps, itf_idx, str_idx):
# CDC needs a Interface Association Descriptor (IAD)
# first interface is zero, two interfaces in total
desc = ustruct.pack("<BBBBBBBB", 8, _ITF_ASSOCIATION_DESC_TYPE, itf_idx, 2,
_CDC_ITF_CONTROL_CLASS, _CDC_ITF_CONTROL_SUBCLASS,
_CDC_ITF_CONTROL_PROT, 0) # "IAD"
_CDC_ITF_CONTROL_PROT, 4) # "IAD"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand, this is an index to a string descriptor describing the function. Do we have a string descriptor for that? Otherwise this value is 0.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly don't remember why I made it 4, just that it worked.

@@ -59,12 +60,13 @@ def get_itf_descriptor(self, num_eps, itf_idx, str_idx):
desc += ustruct.pack("<BBBH", 5, _CS_DESC_TYPE, 0, 0x0120) # "Header"
desc += ustruct.pack("<BBBBB", 5, _CS_DESC_TYPE, 1, 0, 1) # "Call Management"
desc += ustruct.pack("<BBBB", 4, _CS_DESC_TYPE, 2, 2) # "Abstract Control"
desc += ustruct.pack("<BBBH", 5, _CS_DESC_TYPE, 6, itf_idx, 1) # "Union"
desc += ustruct.pack("<BBBBB", 5, _CS_DESC_TYPE, 6, itf_idx, itf_idx+1) # "Union"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, I corrected the itf_idx+1 already, but missed the struct pack pattern.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the big problem that fixed most things. It took me a while to realize it as well.

Comment on lines +104 to +106
if self.ep_in == None:
return
self.submit_xfer(self.ep_in, data)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

Comment on lines +93 to +96
# XXX OUT = 0x00 but is defined as 0x80?
self.ep_in = (ep_addr) | EP_IN_FLAG
self.ep_out = (ep_addr) & ~EP_IN_FLAG

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this one. As I recall, the CDC spec specifically asked for two endpoints for the data interface. So in my latest version it looks like

        self.ep_in = (ep_addr + 1) | EP_IN_FLAG
        self.ep_out = (ep_addr + 2)

Comment on lines +71 to +73
self.ep_in = (ep_addr) | EP_IN_FLAG
desc = endpoint_descriptor(self.ep_in, "interrupt", 8, 16)
return (desc, [], (self.ep_in,))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that looks good

@projectgus
Copy link

Thanks @linted for the PR and @hoihu for the heads-up.

I confess that I have my own version of this branch as a WIP as well. It has some of the same fixes, plus some deeper changes to support using the CDC as a Python stream. 🤦 That's my fault for not being more proactive about pushing it, sorry.

I'll go over these changes and see if there's anything that applies to the branch I have, but hopefully push that today or tomorrow so you can both take a look, too.

@hoihu
Copy link
Owner

hoihu commented Sep 5, 2023

@projectgus all good - I havent looked too much into supporting stream interfaces. Looking forward to the new stuff!

and yeah ChatGPT advices have to be taken with a grain of salt 😀. But to defend „him“ I actually got some decent advice when asking USB low level staff. I might have to check wireshark then for the serial_state support

@projectgus
Copy link

projectgus commented Sep 7, 2023

I've pushed where I'm up to, here: https://github.com/projectgus/micropython-lib/tree/feature/usbd_python_cdc

Although this still doesn't really work. Most of the effort I've been spending to find a memory-efficient way to buffer read and write operations to USB. I have something but I'm still not particularly happy with it.

@linted I cherry-picked one of your fixes from this branch as well, thanks!

@linted
Copy link
Author

linted commented Sep 10, 2023

Since there has been significant work on other branches, I don't think this PR needs to remain open. I'll go ahead and close it.

@linted linted closed this Sep 10, 2023
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

Successfully merging this pull request may close these issues.

3 participants