mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-26 17:37:05 +00:00
add tuh_max3421e_int_api(), retry control if received NAK
This commit is contained in:
parent
3ed5d6c372
commit
344932d27e
@ -28,6 +28,7 @@
|
||||
|
||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include "host/hcd.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@ -164,11 +165,15 @@ enum {
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
typedef struct {
|
||||
uint8_t xfer_type;
|
||||
uint8_t data_toggle;
|
||||
uint8_t xfer_complete;
|
||||
uint16_t packet_size;
|
||||
|
||||
struct TU_ATTR_PACKED {
|
||||
uint8_t is_iso : 1;
|
||||
uint8_t data_toggle : 1;
|
||||
uint8_t xfer_queued : 1;
|
||||
uint8_t xfer_complete : 1;
|
||||
};
|
||||
|
||||
uint16_t total_len;
|
||||
uint16_t xferred_len;
|
||||
uint8_t* buf;
|
||||
@ -176,6 +181,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
bool inited;
|
||||
atomic_bool busy; // busy transferring
|
||||
|
||||
// cached register
|
||||
uint8_t sndbc;
|
||||
@ -198,8 +204,7 @@ static max2341_data_t _hcd_data;
|
||||
|
||||
void tuh_max3421_spi_cs_api(uint8_t rhport, bool active);
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, uint8_t * rx_buf, size_t rx_len);
|
||||
|
||||
//void tuh_max3421e_int_enable(uint8_t rhport, bool enabled);
|
||||
void tuh_max3421e_int_api(uint8_t rhport, bool enabled);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
@ -348,6 +353,9 @@ tusb_speed_t handle_connect_irq(uint8_t rhport) {
|
||||
bool hcd_init(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
|
||||
TU_LOG2_INT(sizeof(hcd_ep_t));
|
||||
TU_LOG2_INT(sizeof(max2341_data_t));
|
||||
|
||||
tu_memclr(&_hcd_data, sizeof(_hcd_data));
|
||||
|
||||
// full duplex, interrupt negative edge
|
||||
@ -382,12 +390,12 @@ bool hcd_init(uint8_t rhport) {
|
||||
|
||||
// Enable USB interrupt
|
||||
void hcd_int_enable (uint8_t rhport) {
|
||||
(void) rhport;
|
||||
tuh_max3421e_int_api(rhport, true);
|
||||
}
|
||||
|
||||
// Disable USB interrupt
|
||||
void hcd_int_disable(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
tuh_max3421e_int_api(rhport, false);
|
||||
}
|
||||
|
||||
// Get frame number (1ms)
|
||||
@ -447,17 +455,20 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) {
|
||||
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) {
|
||||
(void) rhport;
|
||||
(void) dev_addr;
|
||||
(void) ep_desc;
|
||||
|
||||
uint8_t ep_num = tu_edpt_number(ep_desc->bEndpointAddress);
|
||||
uint8_t ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress);
|
||||
|
||||
_hcd_data.ep[ep_num][ep_dir].packet_size = tu_edpt_packet_size(ep_desc);
|
||||
hcd_ep_t * ep = &_hcd_data.ep[ep_num][ep_dir];
|
||||
|
||||
ep->packet_size = tu_edpt_packet_size(ep_desc);
|
||||
|
||||
if (ep_desc->bEndpointAddress == 0) {
|
||||
_hcd_data.ep[ep_num][1].packet_size = tu_edpt_packet_size(ep_desc);
|
||||
_hcd_data.ep[0][1].packet_size = ep->packet_size;
|
||||
}
|
||||
|
||||
ep->is_iso = (TUSB_XFER_ISOCHRONOUS == ep_desc->bmAttributes.xfer) ? 1 : 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -474,11 +485,13 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf
|
||||
ep->total_len = buflen;
|
||||
ep->xferred_len = 0;
|
||||
ep->xfer_complete = 0;
|
||||
ep->xfer_queued = 1;
|
||||
|
||||
peraddr_write(daddr);
|
||||
|
||||
uint8_t hctl = 0;
|
||||
uint8_t hxfr = ep_num;
|
||||
|
||||
if ( ep_num == 0 ) {
|
||||
ep->data_toggle = 1;
|
||||
if ( buffer == NULL || buflen == 0 ) {
|
||||
@ -488,7 +501,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf
|
||||
hxfr_write(hxfr);
|
||||
return true;
|
||||
}
|
||||
} else if ( ep->xfer_type == TUSB_XFER_ISOCHRONOUS ) {
|
||||
} else if ( ep->is_iso ) {
|
||||
hxfr |= HXFR_ISO;
|
||||
}
|
||||
|
||||
@ -551,11 +564,13 @@ static void handle_xfer_done(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
|
||||
uint8_t const hrsl = reg_read(HRSL_ADDR);
|
||||
uint8_t const result = hrsl & HRSL_RESULT_MASK;
|
||||
uint8_t const hresult = hrsl & HRSL_RESULT_MASK;
|
||||
uint8_t ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
||||
|
||||
xfer_result_t xfer_result;
|
||||
|
||||
TU_LOG3("HRSL: %02X\r\n", hrsl);
|
||||
switch(result) {
|
||||
//TU_LOG3("HRSL: %02X\r\n", hrsl);
|
||||
switch(hresult) {
|
||||
case HRSL_SUCCESS:
|
||||
xfer_result = XFER_RESULT_SUCCESS;
|
||||
break;
|
||||
@ -568,21 +583,26 @@ static void handle_xfer_done(uint8_t rhport) {
|
||||
// occurred when initialized without any pending transfer. Skip for now
|
||||
return;
|
||||
|
||||
case HRSL_NAK:
|
||||
// NAK on control, retry immediately
|
||||
if (ep_num == 0) hxfr_write(_hcd_data.hxfr);
|
||||
return;
|
||||
|
||||
default:
|
||||
xfer_result = XFER_RESULT_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
||||
uint8_t const xfer_type = _hcd_data.hxfr & 0xf0;
|
||||
uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0;
|
||||
|
||||
if ( (xfer_type & HXFR_SETUP) || (xfer_type & HXFR_OUT_NIN) ) {
|
||||
if ( (hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN) ) {
|
||||
// SETUP or OUT transfer
|
||||
hcd_ep_t *ep = &_hcd_data.ep[ep_num][0];
|
||||
uint8_t xact_len;
|
||||
if (xfer_type & HXFR_SETUP) {
|
||||
|
||||
if ( hxfr_type & HXFR_SETUP) {
|
||||
xact_len = 8;
|
||||
} else if ( xfer_type & HXFR_HS ) {
|
||||
} else if ( hxfr_type & HXFR_HS ) {
|
||||
xact_len = 0;
|
||||
} else {
|
||||
xact_len = _hcd_data.sndbc;
|
||||
@ -599,7 +619,7 @@ static void handle_xfer_done(uint8_t rhport) {
|
||||
// IN transfer: fifo data is already received in RCVDAV IRQ
|
||||
hcd_ep_t *ep = &_hcd_data.ep[ep_num][1];
|
||||
|
||||
if ( xfer_type & HXFR_HS ) {
|
||||
if ( hxfr_type & HXFR_HS ) {
|
||||
ep->xfer_complete = 1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user