mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-25 01:43:47 +00:00
call xfer_complete_isr() when result is not successful (stalled or failed)
This commit is contained in:
parent
2a814a99af
commit
1ab488eb06
@ -31,6 +31,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _PINNUM(port, pin) ((port)*32 + (pin))
|
||||||
|
|
||||||
// LED
|
// LED
|
||||||
#define LED_PIN 28
|
#define LED_PIN 28
|
||||||
#define LED_STATE_ON 0
|
#define LED_STATE_ON 0
|
||||||
@ -43,6 +45,13 @@
|
|||||||
#define UART_RX_PIN 32
|
#define UART_RX_PIN 32
|
||||||
#define UART_TX_PIN 33
|
#define UART_TX_PIN 33
|
||||||
|
|
||||||
|
// SPI for USB host shield
|
||||||
|
#define MAX3421E_SCK_PIN _PINNUM(1, 15)
|
||||||
|
#define MAX3421E_MOSI_PIN _PINNUM(1, 13)
|
||||||
|
#define MAX3421E_MISO_PIN _PINNUM(1, 14)
|
||||||
|
#define MAX3421E_CS_PIN _PINNUM(1, 12)
|
||||||
|
#define MAX3241E_INTR_PIN _PINNUM(1, 11)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
#pragma GCC diagnostic ignored "-Wundef"
|
#pragma GCC diagnostic ignored "-Wundef"
|
||||||
|
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nrfx.h"
|
#include "nrfx.h"
|
||||||
@ -94,7 +95,7 @@ TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) {
|
|||||||
|
|
||||||
//------------- Host using MAX2341E -------------//
|
//------------- Host using MAX2341E -------------//
|
||||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
||||||
static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(0);
|
static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1);
|
||||||
|
|
||||||
void max3421e_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
void max3421e_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
||||||
if ( !(pin == MAX3241E_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO) ) return;
|
if ( !(pin == MAX3241E_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO) ) return;
|
||||||
@ -222,7 +223,8 @@ void board_init(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
||||||
// MAX3421 need 3.3v signal
|
// MAX3421 need 3.3v signal (may not be needed)
|
||||||
|
#if defined(UICR_REGOUT0_VOUT_Msk) && 0
|
||||||
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) {
|
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) {
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||||
@ -234,6 +236,7 @@ void board_init(void) {
|
|||||||
|
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// manually manage CS
|
// manually manage CS
|
||||||
nrf_gpio_cfg_output(MAX3421E_CS_PIN);
|
nrf_gpio_cfg_output(MAX3421E_CS_PIN);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#define NRFX_UARTE0_ENABLED 1
|
#define NRFX_UARTE0_ENABLED 1
|
||||||
|
|
||||||
#define NRFX_SPIM_ENABLED 1
|
#define NRFX_SPIM_ENABLED 1
|
||||||
#define NRFX_SPIM0_ENABLED 1
|
#define NRFX_SPIM1_ENABLED 1 // use SPI1 since nrf5340 share uart with spi
|
||||||
|
|
||||||
#define NRFX_PRS_ENABLED 0
|
#define NRFX_PRS_ENABLED 0
|
||||||
#define NRFX_USBREG_ENABLED 1
|
#define NRFX_USBREG_ENABLED 1
|
||||||
|
@ -390,7 +390,7 @@
|
|||||||
// External USB controller
|
// External USB controller
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#if defined(CFG_TUH_MAX3421) & CFG_TUH_MAX3421
|
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
||||||
#ifndef CFG_TUH_MAX3421_ENDPOINT_TOTAL
|
#ifndef CFG_TUH_MAX3421_ENDPOINT_TOTAL
|
||||||
#define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4*(CFG_TUH_DEVICE_MAX-1))
|
#define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4*(CFG_TUH_DEVICE_MAX-1))
|
||||||
#endif
|
#endif
|
||||||
|
@ -374,7 +374,8 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) {
|
|||||||
// starting from next endpoint
|
// starting from next endpoint
|
||||||
for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) {
|
for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) {
|
||||||
max3421_ep_t* ep = &_hcd_data.ep[i];
|
max3421_ep_t* ep = &_hcd_data.ep[i];
|
||||||
if (ep->xfer_pending) {
|
if (ep->xfer_pending && ep->packet_size) {
|
||||||
|
// TU_LOG3("next pending i = %u\n", i);
|
||||||
return ep;
|
return ep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -382,7 +383,8 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) {
|
|||||||
// wrap around including current endpoint
|
// wrap around including current endpoint
|
||||||
for (size_t i = 0; i <= idx; i++) {
|
for (size_t i = 0; i <= idx; i++) {
|
||||||
max3421_ep_t* ep = &_hcd_data.ep[i];
|
max3421_ep_t* ep = &_hcd_data.ep[i];
|
||||||
if (ep->xfer_pending) {
|
if (ep->xfer_pending && ep->packet_size) {
|
||||||
|
// TU_LOG3("next pending i = %u\n", i);
|
||||||
return ep;
|
return ep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -464,6 +466,10 @@ bool hcd_init(uint8_t rhport) {
|
|||||||
// full duplex, interrupt negative edge
|
// full duplex, interrupt negative edge
|
||||||
reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false);
|
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);
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false);
|
reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false);
|
||||||
reg_write(rhport, USBCTL_ADDR, 0, false);
|
reg_write(rhport, USBCTL_ADDR, 0, false);
|
||||||
@ -699,6 +705,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]
|
|||||||
ep->ep_dir = 0;
|
ep->ep_dir = 0;
|
||||||
ep->total_len = 8;
|
ep->total_len = 8;
|
||||||
ep->xferred_len = 0;
|
ep->xferred_len = 0;
|
||||||
|
ep->xfer_pending = 1;
|
||||||
ep->is_setup = 1;
|
ep->is_setup = 1;
|
||||||
|
|
||||||
fifo_write(rhport, SUDFIFO_ADDR, setup_packet, 8, false);
|
fifo_write(rhport, SUDFIFO_ADDR, setup_packet, 8, false);
|
||||||
@ -724,9 +731,16 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
|||||||
// Interrupt Handler
|
// Interrupt Handler
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t data_toggle) {
|
static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl) {
|
||||||
uint8_t const ep_addr = tu_edpt_addr(ep->ep_num, ep->ep_dir);
|
uint8_t const ep_addr = tu_edpt_addr(ep->ep_num, ep->ep_dir);
|
||||||
ep->data_toggle = data_toggle;
|
|
||||||
|
// save data toggle
|
||||||
|
if (ep->ep_dir) {
|
||||||
|
ep->data_toggle = (hrsl & HRSL_RCVTOGRD) ? 1 : 0;
|
||||||
|
}else {
|
||||||
|
ep->data_toggle = (hrsl & HRSL_SNDTOGRD) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
ep->xfer_pending = 0;
|
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, true);
|
||||||
|
|
||||||
@ -763,10 +777,6 @@ static void handle_xfer_done(uint8_t rhport) {
|
|||||||
xfer_result = XFER_RESULT_STALLED;
|
xfer_result = XFER_RESULT_STALLED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HRSL_BAD_REQ:
|
|
||||||
// occurred when initialized without any pending transfer. Skip for now
|
|
||||||
return;
|
|
||||||
|
|
||||||
case HRSL_NAK:
|
case HRSL_NAK:
|
||||||
if (ep_num == 0) {
|
if (ep_num == 0) {
|
||||||
// NAK on control, retry immediately
|
// NAK on control, retry immediately
|
||||||
@ -781,15 +791,26 @@ static void handle_xfer_done(uint8_t rhport) {
|
|||||||
}else if (next_ep) {
|
}else if (next_ep) {
|
||||||
// switch to next pending TODO could have issue with double buffered if not clear previously out data
|
// 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, true);
|
||||||
|
}else {
|
||||||
|
TU_ASSERT(false,);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case HRSL_BAD_REQ:
|
||||||
|
// occurred when initialized without any pending transfer. Skip for now
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
xfer_result = XFER_RESULT_FAILED;
|
xfer_result = XFER_RESULT_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xfer_result != XFER_RESULT_SUCCESS) {
|
||||||
|
xfer_complete_isr(rhport, ep, xfer_result, hrsl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ep_dir) {
|
if (ep_dir) {
|
||||||
// IN transfer: fifo data is already received in RCVDAV IRQ
|
// IN transfer: fifo data is already received in RCVDAV IRQ
|
||||||
if ( hxfr_type & HXFR_HS ) {
|
if ( hxfr_type & HXFR_HS ) {
|
||||||
@ -798,8 +819,7 @@ static void handle_xfer_done(uint8_t rhport) {
|
|||||||
|
|
||||||
// short packet or all bytes transferred
|
// short packet or all bytes transferred
|
||||||
if ( ep->xfer_complete ) {
|
if ( ep->xfer_complete ) {
|
||||||
uint8_t const dt = (hrsl & HRSL_RCVTOGRD) ? 1 : 0; // save data toggle
|
xfer_complete_isr(rhport, ep, xfer_result, hrsl);
|
||||||
xfer_complete_isr(rhport, ep, xfer_result, dt);
|
|
||||||
}else {
|
}else {
|
||||||
// more to transfer
|
// more to transfer
|
||||||
hxfr_write(rhport, _hcd_data.hxfr, true);
|
hxfr_write(rhport, _hcd_data.hxfr, true);
|
||||||
@ -820,8 +840,7 @@ static void handle_xfer_done(uint8_t rhport) {
|
|||||||
ep->buf += xact_len;
|
ep->buf += xact_len;
|
||||||
|
|
||||||
if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) {
|
if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) {
|
||||||
uint8_t const dt = (hrsl & HRSL_SNDTOGRD) ? 1 : 0; // save data toggle
|
xfer_complete_isr(rhport, ep, xfer_result, hrsl);
|
||||||
xfer_complete_isr(rhport, ep, xfer_result, dt);
|
|
||||||
} else {
|
} else {
|
||||||
// more to transfer
|
// more to transfer
|
||||||
xact_out(rhport, ep, false, true);
|
xact_out(rhport, ep, false, true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user