summaryrefslogtreecommitdiff
path: root/src/portable
diff options
context:
space:
mode:
authorReinhard Panhuber <[email protected]>2020-09-04 16:23:39 +0200
committerReinhard Panhuber <[email protected]>2020-09-04 16:23:39 +0200
commit12562fc966e2c653de3f856afd7384063641dd80 (patch)
treed48b7bb3cb273cfbd1db04f75346dd107b4ec336 /src/portable
parent338e96fa826b2e2bbb6fb489456202e9e4ec4fe2 (diff)
parent10d5dac9137adfd6c14d96e1079f08447eacd9d8 (diff)
Merge remote-tracking branch 'upstream/master' into uac2
Diffstat (limited to 'src/portable')
-rw-r--r--src/portable/microchip/samd/dcd_samd.c5
-rw-r--r--src/portable/st/synopsys/dcd_synopsys.c38
2 files changed, 34 insertions, 9 deletions
diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c
index d0cc8560a..f1dca88a5 100644
--- a/src/portable/microchip/samd/dcd_samd.c
+++ b/src/portable/microchip/samd/dcd_samd.c
@@ -27,7 +27,8 @@
#include "tusb_option.h"
#if TUSB_OPT_DEVICE_ENABLED && \
- (CFG_TUSB_MCU == OPT_MCU_SAMD21 || CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X)
+ (CFG_TUSB_MCU == OPT_MCU_SAMD11 || CFG_TUSB_MCU == OPT_MCU_SAMD21 || \
+ CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X)
#include "sam.h"
#include "device/dcd.h"
@@ -113,7 +114,7 @@ void dcd_int_disable(uint8_t rhport)
NVIC_DisableIRQ(USB_0_IRQn);
}
-#elif CFG_TUSB_MCU == OPT_MCU_SAMD21
+#elif CFG_TUSB_MCU == OPT_MCU_SAMD11 || CFG_TUSB_MCU == OPT_MCU_SAMD21
void dcd_int_enable(uint8_t rhport)
{
diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c
index 56d606717..d1f24916c 100644
--- a/src/portable/st/synopsys/dcd_synopsys.c
+++ b/src/portable/st/synopsys/dcd_synopsys.c
@@ -750,9 +750,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
return true;
}
-// TODO: The logic for STALLing and disabling an endpoint is very similar
-// (send STALL versus NAK handshakes back). Refactor into resuable function.
-void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
+static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall)
{
(void) rhport;
@@ -767,14 +765,14 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
if(dir == TUSB_DIR_IN) {
// Only disable currently enabled non-control endpoint
if ( (epnum == 0) || !(in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPENA) ){
- in_ep[epnum].DIEPCTL |= (USB_OTG_DIEPCTL_SNAK | USB_OTG_DIEPCTL_STALL);
+ in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK | (stall ? USB_OTG_DIEPCTL_STALL : 0);
} else {
// Stop transmitting packets and NAK IN xfers.
in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_INEPNE) == 0);
// Disable the endpoint.
- in_ep[epnum].DIEPCTL |= (USB_OTG_DIEPCTL_STALL | USB_OTG_DIEPCTL_EPDIS);
+ in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPDIS | (stall ? USB_OTG_DIEPCTL_STALL : 0);
while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_EPDISD_Msk) == 0);
in_ep[epnum].DIEPINT = USB_OTG_DIEPINT_EPDISD;
}
@@ -786,7 +784,7 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
} else {
// Only disable currently enabled non-control endpoint
if ( (epnum == 0) || !(out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPENA) ){
- out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_STALL;
+ out_ep[epnum].DOEPCTL |= stall ? USB_OTG_DOEPCTL_STALL : 0;
} else {
// Asserting GONAK is required to STALL an OUT endpoint.
// Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt
@@ -796,7 +794,7 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
while((usb_otg->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF_Msk) == 0);
// Ditto here- disable the endpoint.
- out_ep[epnum].DOEPCTL |= (USB_OTG_DOEPCTL_STALL | USB_OTG_DOEPCTL_EPDIS);
+ out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPDIS | (stall ? USB_OTG_DOEPCTL_STALL : 0);
while((out_ep[epnum].DOEPINT & USB_OTG_DOEPINT_EPDISD_Msk) == 0);
out_ep[epnum].DOEPINT = USB_OTG_DOEPINT_EPDISD;
@@ -806,6 +804,32 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
}
}
+/**
+ * Close an endpoint.
+ */
+void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
+{
+ USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
+
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ dcd_edpt_disable(rhport, ep_addr, false);
+ if (dir == TUSB_DIR_IN)
+ {
+ uint16_t const fifo_size = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXFD_Msk) >> USB_OTG_DIEPTXF_INEPTXFD_Pos;
+ uint16_t const fifo_start = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXSA_Msk) >> USB_OTG_DIEPTXF_INEPTXSA_Pos;
+ // For now only endpoint that has FIFO at the end of FIFO memory can be closed without fuss.
+ TU_ASSERT(fifo_start + fifo_size == _allocated_fifo_words,);
+ _allocated_fifo_words -= fifo_size;
+ }
+}
+
+void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
+{
+ dcd_edpt_disable(rhport, ep_addr, true);
+}
+
void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;