diff options
| author | hathach <[email protected]> | 2023-09-27 11:30:18 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2023-09-27 11:30:18 +0700 |
| commit | 2f6592de7f94851cfcca411242398c5da7b792de (patch) | |
| tree | a4ada29d56d78d27b03ca42ae2ce558c6484472b /src | |
| parent | f6ca86c3ddeaec18f52b15f1065a5c9eea210c00 (diff) | |
update max3421 to have hcd_int_handler_ext()
Diffstat (limited to 'src')
| -rw-r--r-- | src/host/hcd.h | 3 | ||||
| -rw-r--r-- | src/portable/analog/max3421/hcd_max3421.c | 62 |
2 files changed, 35 insertions, 30 deletions
diff --git a/src/host/hcd.h b/src/host/hcd.h index e25b20ea3..a2d4da85d 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -133,6 +133,9 @@ bool hcd_init(uint8_t rhport); // Interrupt Handler void hcd_int_handler(uint8_t rhport); +// Interrupt Hanndler (extended version) +void hcd_int_handler_ext(uint8_t rhport, bool in_isr); + // Enable USB interrupt void hcd_int_enable (uint8_t rhport); diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 3f6747404..652a971ee 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -428,8 +428,8 @@ bool hcd_init(uint8_t rhport) { reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false); // V1 is 0x01, V2 is 0x12, V3 is 0x13 - // uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); - // TU_LOG2_HEX(revision); + uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); + TU_LOG2_HEX(revision); // reset reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); @@ -693,9 +693,7 @@ static void handle_connect_irq(uint8_t rhport, bool in_isr) { // port reset anyway, this will help to stable bus signal for next connection reg_write(rhport, HCTL_ADDR, HCTL_BUSRST, in_isr); - hcd_event_device_remove(rhport, in_isr); - reg_write(rhport, HCTL_ADDR, 0, in_isr); break; @@ -721,13 +719,12 @@ static void handle_connect_irq(uint8_t rhport, bool in_isr) { free_ep(daddr); hcd_event_device_attach(rhport, in_isr); - break; } } } -static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl) { +static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl, bool in_isr) { uint8_t const ep_addr = tu_edpt_addr(ep->ep_num, ep->ep_dir); // save data toggle @@ -738,20 +735,20 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re } ep->xfer_pending = 0; - hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, true); + hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, in_isr); // Find next pending endpoint max3421_ep_t *next_ep = find_next_pending_ep(ep); if (next_ep) { - xact_inout(rhport, next_ep, true, true); + xact_inout(rhport, next_ep, true, in_isr); }else { // no more pending atomic_flag_clear(&_hcd_data.busy); } } -static void handle_xfer_done(uint8_t rhport) { - uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, true); +static void handle_xfer_done(uint8_t rhport, bool in_isr) { + uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); uint8_t const hresult = hrsl & HRSL_RESULT_MASK; uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; @@ -774,17 +771,17 @@ static void handle_xfer_done(uint8_t rhport) { case HRSL_NAK: if (ep_num == 0) { // NAK on control, retry immediately - hxfr_write(rhport, _hcd_data.hxfr, true); + hxfr_write(rhport, _hcd_data.hxfr, in_isr); }else { // NAK on non-control, find next pending to switch max3421_ep_t *next_ep = find_next_pending_ep(ep); if (ep == next_ep) { // this endpoint is only one pending, retry immediately - hxfr_write(rhport, _hcd_data.hxfr, true); + hxfr_write(rhport, _hcd_data.hxfr, in_isr); }else 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, true); + xact_inout(rhport, next_ep, true, in_isr); }else { TU_ASSERT(false,); } @@ -802,7 +799,7 @@ static void handle_xfer_done(uint8_t rhport) { } if (xfer_result != XFER_RESULT_SUCCESS) { - xfer_complete_isr(rhport, ep, xfer_result, hrsl); + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); return; } @@ -814,10 +811,10 @@ static void handle_xfer_done(uint8_t rhport) { // short packet or all bytes transferred if ( ep->xfer_complete ) { - xfer_complete_isr(rhport, ep, xfer_result, hrsl); + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); }else { // more to transfer - hxfr_write(rhport, _hcd_data.hxfr, true); + hxfr_write(rhport, _hcd_data.hxfr, in_isr); } } else { // SETUP or OUT transfer @@ -835,10 +832,10 @@ static void handle_xfer_done(uint8_t rhport) { ep->buf += xact_len; if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { - xfer_complete_isr(rhport, ep, xfer_result, hrsl); + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); } else { // more to transfer - xact_out(rhport, ep, false, true); + xact_out(rhport, ep, false, in_isr); } } } @@ -862,9 +859,9 @@ void print_hirq(uint8_t hirq) { #define print_hirq(hirq) #endif -// Interrupt Handler -void hcd_int_handler(uint8_t rhport) { - uint8_t hirq = reg_read(rhport, HIRQ_ADDR, true) & _hcd_data.hien; +// Interrupt handler (extended) +void hcd_int_handler_ext(uint8_t rhport, bool in_isr) { + uint8_t hirq = reg_read(rhport, HIRQ_ADDR, in_isr) & _hcd_data.hien; if (!hirq) return; // print_hirq(hirq); @@ -873,7 +870,7 @@ void hcd_int_handler(uint8_t rhport) { } if (hirq & HIRQ_CONDET_IRQ) { - handle_connect_irq(rhport, true); + handle_connect_irq(rhport, in_isr); } // queue more transfer in handle_xfer_done() can cause hirq to be set again while external IRQ may not catch and/or @@ -886,17 +883,17 @@ void hcd_int_handler(uint8_t rhport) { // RCVDAV_IRQ can trigger 2 times (dual buffered) while ( hirq & HIRQ_RCVDAV_IRQ ) { - uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, true); + uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr); xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len); if ( xact_len ) { - fifo_read(rhport, ep->buf, xact_len, true); + fifo_read(rhport, ep->buf, xact_len, in_isr); ep->buf += xact_len; ep->xferred_len += xact_len; } // ack RCVDVAV IRQ - hirq_write(rhport, HIRQ_RCVDAV_IRQ, true); - hirq = reg_read(rhport, HIRQ_ADDR, true); + hirq_write(rhport, HIRQ_RCVDAV_IRQ, in_isr); + hirq = reg_read(rhport, HIRQ_ADDR, in_isr); } if ( xact_len < ep->packet_size || ep->xferred_len >= ep->total_len ) { @@ -905,18 +902,23 @@ void hcd_int_handler(uint8_t rhport) { } if ( hirq & HIRQ_HXFRDN_IRQ ) { - hirq_write(rhport, HIRQ_HXFRDN_IRQ, true); - handle_xfer_done(rhport); + hirq_write(rhport, HIRQ_HXFRDN_IRQ, in_isr); + handle_xfer_done(rhport, in_isr); } - hirq = reg_read(rhport, HIRQ_ADDR, true); + hirq = reg_read(rhport, HIRQ_ADDR, in_isr); } // clear all interrupt except SNDBAV_IRQ (never clear by us). Note RCVDAV_IRQ, HXFRDN_IRQ already clear while processing hirq &= ~HIRQ_SNDBAV_IRQ; if ( hirq ) { - hirq_write(rhport, hirq, true); + hirq_write(rhport, hirq, in_isr); } } +// Interrupt Handler +void hcd_int_handler(uint8_t rhport) { + hcd_int_handler_ext(rhport, true); +} + #endif |
