-
Notifications
You must be signed in to change notification settings - Fork 2k
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
cpu/rpx0xx: add periph_usbus support #20817
base: master
Are you sure you want to change the base?
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.
At first glance, you're missing NVIC_EnableIRQ(USBCTRL_IRQ_IRQn);
.
I used a debugger and check the PLL configuration. It looks fine but I really think some bits are missing (currently 0) like VBUS_DETECTED and SPEED in SIE_STATUS register.
cpu/rpx0xx/periph/usbdev.c
Outdated
io_reg_atomic_set(&USBCTRL_REGS->MAIN_CTRL, | ||
USBCTRL_REGS_MAIN_CTRL_CONTROLLER_EN_Msk); | ||
io_reg_atomic_set(&USBCTRL_REGS->USB_MUXING, | ||
USBCTRL_REGS_USB_MUXING_TO_PHY_Msk); |
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.
RP2040 datasheet also add USBCTRL_REGS_USB_MUXING_SOFTCON_Msk
.
- you should add
io_reg_atomic_set(&USBCTRL_REGS->USB_PWR,
USBCTRL_REGS_USB_PWR_VBUS_DETECT_Msk
| USBCTRL_REGS_USB_PWR_VBUS_DETECT_OVERRIDE_EN_Msk);
With these changes, I can now receive the setup request from the host. Its interrupt is fired but never served by |
} | ||
if (USBCTRL_REGS->INTS) { | ||
/* Device specific interrupt */ | ||
_disable_irq(); |
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.
Disabling all IRQs here will have the side effect to also clear INTS register.
So when USBUS call its ESR callback, it doesn't process any IRQs as INTS is 0.
Depending on the interruption's source, you may need to clear this register either here or in usbdev_esr
I already wondered how to handle setup packets. |
Added a fixup with your suggestions @dylad, and improved handling of I had no time to test further yet. Maybe tomorrow I can also check my packet flow. |
Now the setup requests are recognized by usbus, but control flow is still garbage. |
From what I can tell this is normal. |
cpu/rpx0xx/periph/usbdev.c
Outdated
USBCTRL_DPRAM_EP0_IN_BUFFER_CONTROL_FULL_0_Pos, | ||
buf_filled_bit); | ||
_ep_buf_ctrl_reg_write(ep->num, ep->dir, | ||
USBCTRL_DPRAM_EP0_IN_BUFFER_CONTROL_AVAILABLE_0_Pos, | ||
USBCTRL_DPRAM_EP0_IN_BUFFER_CONTROL_AVAILABLE_0_Msk); |
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 seems to me that you're also missing to set (at least) the length field in the Buffer Control register of the endpoint which might explain why the host didn't get the response of the first setup request.
If set to 0, hardware will try to transfer 0 bytes to the host which is obviously wrong.
Wow, I guess I misread the data sheet here... Some tinkering today did not work so far, but I have an idea for solving that. Sadly I have not time over the weekend. Might take me some time to figure that out. |
Still garbage, unfortunately. But I have found a few bugs. I might simply have a race condition between the setup request handling and data packet handling. Not sure how to handle that with usbus. The USB controller treats setup request differently from normal data, which makes it difficult to hand over to usbus. Maybe my endpoint initialization is not correct, too. |
I'll see if I can find some times this weekend to help you with that. |
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'm having a bad time trying to understand the PID stuff on this IP.
For setup request, TinyUSB and the standalone example from raspberry PI tell that we must answer the setup request on PID 1 but there is no such reference in the datasheet.
cpu/rpx0xx/periph/usbdev.c
Outdated
_ep_buf_ctrl_reg_write(ep->num, ep->dir, | ||
USBCTRL_DPRAM_EP0_IN_BUFFER_CONTROL_FULL_0_Msk, | ||
buf_filled_bit); | ||
_ep_buf_ctrl_reg_write(ep->num, ep->dir, | ||
USBCTRL_DPRAM_EP0_IN_BUFFER_CONTROL_AVAILABLE_0_Msk, | ||
USBCTRL_DPRAM_EP0_IN_BUFFER_CONTROL_AVAILABLE_0_Msk); | ||
_ep_buf_ctrl_reg_write(ep->num, ep->dir, len, | ||
USBCTRL_DPRAM_EP0_IN_BUFFER_CONTROL_LENGTH_0_Msk); |
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.
Let's try to use a variable and write the whole config at once instead.
Moreover, the datasheet states that the AVAILABLE bit should be set AFTER the rest of the configuration in this register. If USB PLL is running at 48 MHz which is our case IIRC. 3 nop instructions are needed before setting the available bit.
I have made some progress based on @dylad 's comments. I think I figured out the usb controller more or less. I get the setup requests and some control flow afterwards. However, I totally misunderstood how RIOT's usbus works and there is is still a problem. It seems I do not receive any packets and the control flow looks wrong. |
2639284
to
8d3b3e3
Compare
Contribution description
This is a WIP contribution to add USB support for the rpx0xx MCU.
Testing procedure
The code is in a quite early stage. It compiles with
examples/usbus_minimal
, but it hangs somewhere quite early in the initialization. I will debug it as we go, please do not look all to deeply into it yet.With this PR I primarily want to clarify some question I have regarding the USB stack.
Issues/PRs references
#15822 is for RPx0xx feature tracking.