Skip to content

Commit

Permalink
rp2040: usb: fix usb_lld_get_status functions
Browse files Browse the repository at this point in the history
This fixes the USB endpoint get status functions; previously the
(wrong) assumptions were the following:

* `active` was toggled depending on whether a transaction was currently
  ongoing on the endpoint e.g., if the endpoint is "busy." What is  
  actually requested is if this endpoint is enabled at all. Therefore,
  we check the `enabled` flag in the endpoint control register.
* `stalled` was toggled by the device itself, although this property is
  completely controlled by the host via the SET and CLEAR feature
  requests. Therefore, we check the `stalled` flag in the endpoint
  buffer control register.
  • Loading branch information
KarlK90 committed Nov 25, 2023
1 parent fb67e50 commit 1a1bbe6
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 62 deletions.
58 changes: 12 additions & 46 deletions os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,7 @@ static uint16_t usb_buffer_next_offset(USBDriver *usbp, uint16_t size, bool is_d
*/
static void reset_ep0(USBDriver *usbp) {
usbp->epc[0]->out_state->next_pid = 1U;
usbp->epc[0]->out_state->active = false;
usbp->epc[0]->out_state->stalled = false;
usbp->epc[0]->in_state->next_pid = 1U;
usbp->epc[0]->in_state->active = false;
usbp->epc[0]->in_state->stalled = false;
}

/**
Expand All @@ -161,8 +157,6 @@ uint32_t usb_prepare_out_ep_buffer(USBDriver *usbp, usbep_t ep, uint8_t buffer_i
const USBEndpointConfig *epcp = usbp->epc[ep];
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;

oesp->active = true;

/* PID */
buf_ctrl |= oesp->next_pid ? USB_BUFFER_BUFFER0_DATA_PID : 0;
oesp->next_pid ^= 1U;
Expand Down Expand Up @@ -223,8 +217,6 @@ static uint32_t usb_prepare_in_ep_buffer(USBDriver *usbp, usbep_t ep, uint8_t bu
const USBEndpointConfig *epcp = usbp->epc[ep];
USBInEndpointState *iesp = usbp->epc[ep]->in_state;

iesp->active = true;

/* txsize - txlast gives size of data to be sent but not yet in the buffer */
buf_len = epcp->in_maxsize < iesp->txsize - iesp->txlast ?
epcp->in_maxsize : iesp->txsize - iesp->txlast;
Expand Down Expand Up @@ -321,9 +313,6 @@ static void usb_serve_endpoint(USBDriver *usbp, usbep_t ep, bool is_in) {
} else {
/* Transfer complete */
_usb_isr_invoke_in_cb(usbp, ep);

iesp->active = false;
iesp->stalled = false;
}
} else {
/* OUT endpoint */
Expand All @@ -342,9 +331,6 @@ static void usb_serve_endpoint(USBDriver *usbp, usbep_t ep, bool is_in) {

/* Short packet or all packetes have been received. */
if (oesp->rxpkts == 0 || n < epcp->out_maxsize) {
oesp->active = false;
oesp->stalled = false;

/* Transifer complete */
_usb_isr_invoke_out_cb(usbp, ep);
} else {
Expand Down Expand Up @@ -611,22 +597,16 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
epcp->in_state->hw_buf = (uint8_t *)&USB_DPSRAM->EP0BUF0;
epcp->in_state->buf_size = 64;
epcp->in_state->next_pid = 0U;
epcp->in_state->active = false;
epcp->in_state->stalled = false;
epcp->out_state->hw_buf = (uint8_t *)&USB_DPSRAM->EP0BUF0;
epcp->out_state->buf_size = 64;
epcp->out_state->next_pid = 0U;
epcp->out_state->active = false;
epcp->out_state->stalled = false;
USB->SET.SIECTRL = USB_EP_BUFFER_IRQ_EN;
return;
}

if (epcp->in_state) {
buf_ctrl = 0U;
BUF_CTRL(ep).IN = buf_ctrl;
epcp->in_state->active = false;
epcp->in_state->stalled = false;
epcp->in_state->next_pid = 0U;

if (epcp->ep_mode == USB_EP_MODE_TYPE_ISOC) {
Expand All @@ -646,8 +626,6 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
if (epcp->out_state) {
buf_ctrl = 0U;
BUF_CTRL(ep).OUT = buf_ctrl;
epcp->out_state->active = false;
epcp->out_state->stalled = false;
epcp->out_state->next_pid = 0U;

if (epcp->ep_mode == USB_EP_MODE_TYPE_ISOC) {
Expand Down Expand Up @@ -692,14 +670,11 @@ void usb_lld_disable_endpoints(USBDriver *usbp) {
* @notapi
*/
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
USBOutEndpointState *out_state = usbp->epc[ep]->out_state;

if (out_state) {
if (out_state->active) {
return EP_STATUS_ACTIVE;
} else if (out_state->stalled) {
return EP_STATUS_STALLED;
}
if (BUF_CTRL(ep).OUT & USB_BUFFER_STALL) {
return EP_STATUS_STALLED;
}
if (EP_CTRL(ep).OUT & USB_EP_EN) {
return EP_STATUS_ACTIVE;
}
return EP_STATUS_DISABLED;
}
Expand All @@ -717,14 +692,11 @@ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
* @notapi
*/
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
USBInEndpointState *in_state = usbp->epc[ep]->in_state;

if (in_state) {
if (in_state->active) {
return EP_STATUS_ACTIVE;
} else if (in_state->stalled) {
return EP_STATUS_STALLED;
}
if (BUF_CTRL(ep).IN & USB_BUFFER_STALL) {
return EP_STATUS_STALLED;
}
if (EP_CTRL(ep).IN & USB_EP_EN) {
return EP_STATUS_ACTIVE;
}
return EP_STATUS_DISABLED;
}
Expand Down Expand Up @@ -802,8 +774,6 @@ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
USB->SET.EPSTALLARM = USB_EP_STALL_ARM_EP0_OUT;
}
BUF_CTRL(ep).OUT |= USB_BUFFER_STALL;
usbp->epc[ep]->out_state->stalled = true;
usbp->epc[ep]->out_state->next_pid = 0U;
}

/**
Expand All @@ -819,8 +789,6 @@ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
USB->SET.EPSTALLARM = USB_EP_STALL_ARM_EP0_IN;
}
BUF_CTRL(ep).IN |= USB_BUFFER_STALL;
usbp->epc[ep]->in_state->stalled = true;
usbp->epc[ep]->in_state->next_pid = 0U;
}

/**
Expand All @@ -835,8 +803,7 @@ void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
if (ep > 0) {
BUF_CTRL(ep).OUT &= ~USB_BUFFER_STALL;
}

usbp->epc[ep]->out_state->stalled = false;
usbp->epc[ep]->out_state->next_pid = 0U;
}

/**
Expand All @@ -851,8 +818,7 @@ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
if (ep > 0) {
BUF_CTRL(ep).IN &= ~USB_BUFFER_STALL;
}

usbp->epc[ep]->in_state->stalled = false;
usbp->epc[ep]->in_state->next_pid = 0U;
}

#endif /* HAL_USE_USB == TRUE */
Expand Down
16 changes: 0 additions & 16 deletions os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,6 @@ typedef struct {
* @brief Size of the last transmitted packet.
*/
size_t txlast;
/**
* @brief Endpoint is active.
*/
bool active;
/**
* @brief Endpoint is stalled.
*/
bool stalled;
/**
* @brief Data PID used by next transfer.
*/
Expand Down Expand Up @@ -180,14 +172,6 @@ typedef struct {
* @brief Number of packets to receive.
*/
uint16_t rxpkts;
/**
* @brief Endpoint is active.
*/
bool active;
/**
* @brief Endpoint is stalled.
*/
bool stalled;
/**
* @brief Data PID used by next transfer.
*/
Expand Down

0 comments on commit 1a1bbe6

Please sign in to comment.