summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIngHK <[email protected]>2024-03-26 08:10:32 +0100
committerIngHK <[email protected]>2024-03-26 08:12:24 +0100
commit9fdb1c1684c653426d4f616d788b329ee528110a (patch)
tree29950f3299916ac9f5f146c27c6c081f8035aefa /src
parent0cb7204e60259ca3b50c227105e8288a24347738 (diff)
draft MAX3421E NAK retry handling next frame
Diffstat (limited to 'src')
-rw-r--r--src/portable/analog/max3421/hcd_max3421.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c
index d70cf7208..d366298ea 100644
--- a/src/portable/analog/max3421/hcd_max3421.c
+++ b/src/portable/analog/max3421/hcd_max3421.c
@@ -28,6 +28,8 @@
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
+#define NAK_RETRY_HANDLING 1
+
#include <stdatomic.h>
#include "host/hcd.h"
@@ -180,6 +182,9 @@ typedef struct {
uint8_t data_toggle : 1;
uint8_t xfer_pending : 1;
uint8_t xfer_complete : 1;
+#if NAK_RETRY_HANDLING
+ uint8_t retry_pending : 1;
+#endif
};
struct TU_ATTR_PACKED {
@@ -593,7 +598,7 @@ void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
}
uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size);
- TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,);
+// TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,);
if (xact_len) {
fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr);
}
@@ -803,6 +808,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
xfer_result_t xfer_result;
switch(hresult) {
case HRSL_SUCCESS:
+// putchar('S');
xfer_result = XFER_RESULT_SUCCESS;
break;
@@ -811,6 +817,19 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
break;
case HRSL_NAK:
+// putchar('N');
+#if NAK_RETRY_HANDLING
+ ep->retry_pending = 1;
+ ep->xfer_pending = 0;
+ max3421_ep_t * next_ep = find_next_pending_ep(ep);
+ if (next_ep) {
+ // switch to next pending TODO could have issue with double buffered if not clear previously out data
+ xact_inout(rhport, next_ep, true, in_isr);
+ } else {
+ // no more pending
+ atomic_flag_clear(&_hcd_data.busy);
+ }
+#else
if (ep_num == 0) {
// NAK on control, retry immediately
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
@@ -828,6 +847,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
TU_ASSERT(false,);
}
}
+#endif
return;
case HRSL_BAD_REQ:
@@ -909,6 +929,29 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
if (hirq & HIRQ_FRAME_IRQ) {
_hcd_data.frame_count++;
+
+#if NAK_RETRY_HANDLING
+ // retry EPs
+ max3421_ep_t * next_ep = NULL;
+ for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) {
+ max3421_ep_t * ep = &_hcd_data.ep[i];
+ // set retryable EPs to pending
+ if (ep->retry_pending) {
+// putchar('R');
+ ep->xfer_pending = 1;
+ ep->retry_pending = 0;
+ if (next_ep == NULL) {
+ next_ep = &_hcd_data.ep[i];
+ }
+ }
+ }
+ // trigger 1st retryable EP
+ if (next_ep) {
+ if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) {
+ xact_inout(rhport, next_ep, true, in_isr);
+ }
+ }
+#endif
}
if (hirq & HIRQ_CONDET_IRQ) {