1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/usbdev_synopsys_dwc2: add stall functions to usbdev

This commit is contained in:
Koen Zandberg 2021-10-30 12:07:41 +02:00
parent 98c31a7d58
commit 33ba2adc68
No known key found for this signature in database
GPG Key ID: BA1718B37D79F51C

View File

@ -330,9 +330,10 @@ static uint32_t _ep0_size(size_t size)
}
/**
* @brief Disables an IN type endpoint
* @brief Disables transfers on an IN type endpoint.
*
* Endpoint is only deactivated if it was activated
* Endpoint is only deactivated if it was activated.
* The endpoint will still respond to traffic, but any transfers will be aborted
*/
static void _ep_in_disable(const dwc2_usb_otg_fshs_config_t *conf, size_t num)
{
@ -352,9 +353,10 @@ static void _ep_in_disable(const dwc2_usb_otg_fshs_config_t *conf, size_t num)
}
/**
* @brief Disables an OUT type endpoint
* @brief Disables transfers on an OUT type endpoint.
*
* Endpoint is only deactivated if it was activated
* The endpoint will still respond to traffic, but any transfers will be aborted
*/
static void _ep_out_disable(const dwc2_usb_otg_fshs_config_t *conf, size_t num)
{
@ -1148,25 +1150,58 @@ static int _usbdev_ep_get(usbdev_ep_t *ep, usbopt_ep_t opt,
return res;
}
static void _usbdev_ep0_stall(usbdev_t *usbdev)
{
dwc2_usb_otg_fshs_t *st_usbdev = (dwc2_usb_otg_fshs_t *)usbdev;
const dwc2_usb_otg_fshs_config_t *conf = st_usbdev->config;
/* Stall both directions, cleared automatically on SETUP received */
_in_regs(conf, 0)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
_out_regs(conf, 0)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
}
static void _ep_set_stall(usbdev_ep_t *ep, bool enable)
{
(void)enable;
assert(ep->num != 0);
dwc2_usb_otg_fshs_t *usbdev = (dwc2_usb_otg_fshs_t *)ep->dev;
const dwc2_usb_otg_fshs_config_t *conf = usbdev->config;
(void)enable;
if (ep->dir == USB_EP_DIR_IN) {
/* Disable first */
_ep_in_disable(conf, ep->num);
_in_regs(conf, ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
if (enable) {
if (ep->dir == USB_EP_DIR_IN) {
/* Disable first */
_ep_in_disable(conf, ep->num);
_in_regs(conf, ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
}
else {
/* Disable first */
_ep_out_disable(conf, ep->num);
_out_regs(conf, ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
}
}
else {
/* Disable first */
_ep_out_disable(conf, ep->num);
_out_regs(conf, ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
if (ep->dir == USB_EP_DIR_IN) {
/* Clear stall and set to DATA0 */
uint32_t diepctl = _in_regs(conf, ep->num)->DIEPCTL;
diepctl &= ~(USB_OTG_DIEPCTL_STALL);
diepctl |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
_in_regs(conf, ep->num)->DIEPCTL = diepctl;
}
else {
/* Clear stall and set to DATA0 */
uint32_t doepctl = _out_regs(conf, ep->num)->DOEPCTL;
doepctl &= ~(USB_OTG_DIEPCTL_STALL);
doepctl |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
_out_regs(conf, ep->num)->DOEPCTL = doepctl;
}
}
}
static void _usbdev_ep_stall(usbdev_ep_t *ep, bool enable)
{
_ep_set_stall(ep, enable);
}
static int _usbdev_ep_set(usbdev_ep_t *ep, usbopt_ep_t opt,
const void *value, size_t value_len)
{
@ -1492,7 +1527,9 @@ const usbdev_driver_t driver = {
.get = _usbdev_get,
.set = _usbdev_set,
.esr = _usbdev_esr,
.ep0_stall = _usbdev_ep0_stall,
.ep_init = _usbdev_ep_init,
.ep_stall = _usbdev_ep_stall,
.ep_get = _usbdev_ep_get,
.ep_set = _usbdev_ep_set,
.ep_esr = _usbdev_ep_esr,