Skip to content

Commit 616e9c5

Browse files
vbrzeskiVictor Brzeski
authored andcommitted
not too broken lmao
1 parent 611d04d commit 616e9c5

File tree

1 file changed

+59
-19
lines changed

1 file changed

+59
-19
lines changed

drivers/usb/udc/udc_dwc2.c

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@ static inline bool dwc2_in_buffer_dma_mode(const struct device *dev)
225225
return IS_ENABLED(CONFIG_UDC_DWC2_DMA) && priv->bufferdma;
226226
}
227227

228+
static inline uint16_t dwc2_get_frame_number_limit(const struct device *dev) {
229+
struct udc_dwc2_data *const priv = udc_get_private(dev);
230+
231+
return (priv->enumspd == USB_DWC2_DSTS_ENUMSPD_HS3060) ?
232+
USB_DWC2_DSTS_SOFFN_LIMIT :
233+
USB_DWC2_DSTS_SOFFN_LIMIT >> 3;
234+
}
235+
228236
/* Get DOEPCTLn or DIEPCTLn register address */
229237
static mem_addr_t dwc2_get_dxepctl_reg(const struct device *dev, const uint8_t ep)
230238
{
@@ -389,16 +397,12 @@ static bool dwc2_ep_is_periodic(struct udc_ep_config *const cfg)
389397
static void dwc2_ep_next_target_frame(const struct device *dev, struct udc_ep_config *const cfg) {
390398
struct udc_dwc2_data *const priv = udc_get_private(dev);
391399
const uint8_t ep_bitmap_idx = USB_EP_GET_BITMAP_IDX(cfg->addr);
392-
uint16_t limit = USB_DWC2_DSTS_SOFFN_LIMIT;
393-
394-
if (priv->enumspd != USB_DWC2_DSTS_ENUMSPD_HS3060) {
395-
limit >>= 3;
396-
}
400+
const uint16_t limit = dwc2_get_frame_number_limit(dev);
397401

398402
priv->target_frames[ep_bitmap_idx] += cfg->interval;
399403
if (priv->target_frames[ep_bitmap_idx] > limit) {
400404
priv->target_frames[ep_bitmap_idx] &= limit;
401-
priv->target_frame_overrun_mask &= BIT(ep_bitmap_idx);
405+
priv->target_frame_overrun_mask |= BIT(ep_bitmap_idx);
402406
} else {
403407
priv->target_frame_overrun_mask &= ~BIT(ep_bitmap_idx);
404408
}
@@ -411,11 +415,7 @@ static bool dwc2_target_frame_elapsed(const struct device *dev, struct udc_ep_co
411415
const uint16_t target_frame = priv->target_frames[ep_bitmap_idx];
412416
const uint16_t current_frame = priv->sof_num;
413417
const bool frame_overrun = priv->target_frame_overrun_mask & BIT(ep_bitmap_idx);
414-
uint16_t limit = USB_DWC2_DSTS_SOFFN_LIMIT;
415-
416-
if (priv->enumspd != USB_DWC2_DSTS_ENUMSPD_HS3060) {
417-
limit >>= 3;
418-
}
418+
const uint16_t limit = dwc2_get_frame_number_limit(dev);
419419

420420
if (!frame_overrun && current_frame >= target_frame) {
421421
return true;
@@ -2256,6 +2256,10 @@ static int udc_dwc2_enable(const struct device *dev)
22562256

22572257
/* Disable soft disconnect */
22582258
sys_clear_bits((mem_addr_t)&base->dctl, USB_DWC2_DCTL_SFTDISCON);
2259+
2260+
// Disable frame number thing (out of curiousity)
2261+
// sys_clear_bits((mem_addr_t)&base->dctl, USB_DWC2_DCTL_IGNRFRMNUM);
2262+
22592263
LOG_DBG("Enable device %p", base);
22602264

22612265
return 0;
@@ -2619,6 +2623,10 @@ static inline void dwc2_handle_in_xfercompl(const struct device *dev,
26192623
return;
26202624
}
26212625

2626+
if (dwc2_ep_is_iso(ep_cfg)) {
2627+
dwc2_ep_next_target_frame(dev, ep_cfg);
2628+
}
2629+
26222630
atomic_set_bit(&priv->xfer_finished, ep_idx);
26232631
k_event_post(&priv->drv_evt, BIT(DWC2_DRV_EVT_EP_FINISHED));
26242632
}
@@ -2627,6 +2635,7 @@ static inline void dwc2_handle_in_nakintrpt(const struct device *dev,
26272635
const uint8_t ep_idx)
26282636
{
26292637
struct udc_dwc2_data *const priv = udc_get_private(dev);
2638+
struct usb_dwc2_reg *const base = dwc2_get_base(dev);
26302639
mem_addr_t diepctl_reg = dwc2_get_dxepctl_reg(dev, ep_idx | USB_EP_DIR_IN);
26312640
struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep_idx | USB_EP_DIR_IN);
26322641
const uint8_t ep_bitmap_idx = USB_EP_GET_BITMAP_IDX(ep_cfg->addr);
@@ -2638,6 +2647,7 @@ static inline void dwc2_handle_in_nakintrpt(const struct device *dev,
26382647

26392648
if (priv->target_frames[ep_bitmap_idx] == UDC_DWC2_TARGET_FRAME_INITIAL) {
26402649
priv->target_frames[ep_bitmap_idx] = priv->sof_num;
2650+
dwc2_ep_next_target_frame(dev, ep_cfg);
26412651
if (ep_cfg->interval > 1) {
26422652
diepctl = sys_read32(diepctl_reg);
26432653
if (priv->target_frames[ep_bitmap_idx] & 1) {
@@ -2650,10 +2660,22 @@ static inline void dwc2_handle_in_nakintrpt(const struct device *dev,
26502660
}
26512661
}
26522662

2653-
// TODO this holy fuck
2654-
//diepctl = sys_read32(diepctl_reg);
2655-
//if (diepctl )
2656-
dwc2_ep_next_target_frame(dev, ep_cfg);
2663+
udc_dwc2_ep_disable(dev, ep_cfg, false);
2664+
2665+
while (dwc2_target_frame_elapsed(dev, ep_cfg)) {
2666+
struct net_buf *buf = udc_buf_get(ep_cfg);
2667+
2668+
if (buf) {
2669+
if(udc_submit_ep_event(dev, buf, -ENODATA)) {
2670+
LOG_ERR("Failed to submit endpoint event");
2671+
}
2672+
}
2673+
2674+
dwc2_ep_next_target_frame(dev, ep_cfg);
2675+
priv->sof_num = usb_dwc2_get_dsts_soffn(sys_read32((mem_addr_t)&base->dsts));
2676+
}
2677+
2678+
dwc2_handle_xfer_next(dev, ep_cfg);
26572679
}
26582680

26592681
static inline void dwc2_handle_iepint(const struct device *dev)
@@ -2757,7 +2779,11 @@ static inline void dwc2_handle_out_xfercompl(const struct device *dev,
27572779
net_buf_add(buf, bcnt);
27582780
}
27592781

2760-
if (!is_iso && bcnt && (bcnt % udc_mps_ep_size(ep_cfg)) == 0 &&
2782+
if (is_iso && bcnt) {
2783+
dwc2_ep_next_target_frame(dev, ep_cfg);
2784+
}
2785+
2786+
if (bcnt && (bcnt % udc_mps_ep_size(ep_cfg)) == 0 &&
27612787
net_buf_tailroom(buf)) {
27622788
dwc2_prep_rx(dev, buf, ep_cfg);
27632789
} else {
@@ -2768,29 +2794,43 @@ static inline void dwc2_handle_out_xfercompl(const struct device *dev,
27682794

27692795
static inline void dwc2_handle_out_token_ep_disabled(const struct device *dev, const uint8_t ep_idx) {
27702796
struct udc_dwc2_data *const priv = udc_get_private(dev);
2797+
struct usb_dwc2_reg *const base = dwc2_get_base(dev);
27712798
struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, ep_idx);
27722799
const uint8_t ep_bitmap_idx = USB_EP_GET_BITMAP_IDX(ep_cfg->addr);
27732800

27742801
if (!USB_EP_DIR_IS_OUT(ep_cfg->addr) || !dwc2_ep_is_iso(ep_cfg)) {
27752802
return;
27762803
}
27772804

2778-
27792805
if (priv->target_frames[ep_bitmap_idx] == UDC_DWC2_TARGET_FRAME_INITIAL) {
27802806
priv->target_frames[ep_bitmap_idx] = priv->sof_num;
2807+
dwc2_ep_next_target_frame(dev, ep_cfg);
27812808
if (ep_cfg->interval > 1) {
27822809
mem_addr_t doepctl_reg = dwc2_get_dxepctl_reg(dev, ep_idx);
27832810
uint32_t doepctl = sys_read32(doepctl_reg);
27842811
if (priv->target_frames[ep_bitmap_idx] & 1) {
27852812
doepctl |= USB_DWC2_DEPCTL_SETODDFR;
2786-
} else {
2813+
} else {
27872814
doepctl |= USB_DWC2_DEPCTL_SETEVENFR;
27882815
}
27892816
sys_write32(doepctl, doepctl_reg);
27902817
}
27912818
}
27922819

2793-
dwc2_ep_next_target_frame(dev, ep_cfg);
2820+
while (dwc2_target_frame_elapsed(dev, ep_cfg)) {
2821+
struct net_buf *buf = udc_buf_get(ep_cfg);
2822+
2823+
if (buf) {
2824+
if(udc_submit_ep_event(dev, buf, -ENODATA)) {
2825+
LOG_ERR("Failed to submit endpoint event");
2826+
}
2827+
}
2828+
2829+
dwc2_ep_next_target_frame(dev, ep_cfg);
2830+
priv->sof_num = usb_dwc2_get_dsts_soffn(sys_read32((mem_addr_t)&base->dsts));
2831+
}
2832+
2833+
dwc2_handle_xfer_next(dev, ep_cfg);
27942834
}
27952835

27962836
static inline void dwc2_handle_oepint(const struct device *dev)

0 commit comments

Comments
 (0)