Merge pull request #2646 from hathach/max3421-abort-xfer
Implement Max3421 hcd abort xfer
This commit is contained in:
@@ -91,7 +91,13 @@ jobs:
|
|||||||
family: << parameters.family >>
|
family: << parameters.family >>
|
||||||
- run:
|
- run:
|
||||||
name: Build
|
name: Build
|
||||||
command: python tools/build.py -s << parameters.build-system >> --toolchain clang << parameters.family >>
|
command: |
|
||||||
|
# Only build one board per family for non PRs i.e commit to master
|
||||||
|
ONE_PER_FAMILY=""
|
||||||
|
if [ -z "$CIRCLE_PULL_REQUEST" ]; then
|
||||||
|
ONE_PER_FAMILY="--one-per-family"
|
||||||
|
fi
|
||||||
|
python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> --toolchain clang << parameters.family >>
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
build:
|
build:
|
||||||
|
@@ -23,7 +23,7 @@ runs:
|
|||||||
id: cache-toolchain-espressif
|
id: cache-toolchain-espressif
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.set-docker-image.outputs.DOCKER_IMAGE }}
|
path: ${{ steps.set-docker-image.outputs.DOCKER_IMAGE }}
|
||||||
key: ${{ runner.os }}-${{ inputs.toolchain }}-${{ inputs.toolchain_url }}
|
key: ${{ inputs.toolchain }}-${{ inputs.toolchain_url }}
|
||||||
|
|
||||||
- name: Pull and Save Docker Image
|
- name: Pull and Save Docker Image
|
||||||
if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true'
|
if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true'
|
||||||
|
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@@ -59,10 +59,10 @@ jobs:
|
|||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install ARM GCC
|
- name: Setup Toolchain
|
||||||
uses: carlosperate/arm-none-eabi-gcc-action@v1
|
uses: ./.github/actions/setup_toolchain
|
||||||
with:
|
with:
|
||||||
release: '11.2-2022.02'
|
toolchain: 'arm-gcc'
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
|
2
.github/workflows/hil_test.yml
vendored
2
.github/workflows/hil_test.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
|||||||
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV
|
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV
|
||||||
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT
|
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Setup ARM Toolchain
|
- name: Setup Toolchain
|
||||||
uses: ./.github/actions/setup_toolchain
|
uses: ./.github/actions/setup_toolchain
|
||||||
with:
|
with:
|
||||||
toolchain: 'arm-gcc'
|
toolchain: 'arm-gcc'
|
||||||
|
@@ -101,6 +101,15 @@ endfunction()
|
|||||||
#------------------------------------
|
#------------------------------------
|
||||||
# Functions
|
# Functions
|
||||||
#------------------------------------
|
#------------------------------------
|
||||||
|
|
||||||
|
#function(family_flash_adafruit_nrfutil TARGET)
|
||||||
|
# add_custom_target(${TARGET}-adafruit-nrfutil
|
||||||
|
# DEPENDS ${TARGET}
|
||||||
|
# COMMAND adafruit-nrfutil --verbose dfu serial --package $^ -p /dev/ttyACM0 -b 115200 --singlebank --touch 1200
|
||||||
|
# )
|
||||||
|
#endfunction()
|
||||||
|
|
||||||
|
|
||||||
function(family_configure_example TARGET RTOS)
|
function(family_configure_example TARGET RTOS)
|
||||||
family_configure_common(${TARGET} ${RTOS})
|
family_configure_common(${TARGET} ${RTOS})
|
||||||
|
|
||||||
@@ -133,4 +142,5 @@ function(family_configure_example TARGET RTOS)
|
|||||||
|
|
||||||
# Flashing
|
# Flashing
|
||||||
family_flash_jlink(${TARGET})
|
family_flash_jlink(${TARGET})
|
||||||
|
# family_flash_adafruit_nrfutil(${TARGET})
|
||||||
endfunction()
|
endfunction()
|
||||||
|
@@ -174,7 +174,8 @@ enum {
|
|||||||
enum {
|
enum {
|
||||||
EP_STATE_IDLE = 0,
|
EP_STATE_IDLE = 0,
|
||||||
EP_STATE_COMPLETE = 1,
|
EP_STATE_COMPLETE = 1,
|
||||||
EP_STATE_ATTEMPT_1 = 2, // pending 1st attempt
|
EP_STATE_ABORTING = 2,
|
||||||
|
EP_STATE_ATTEMPT_1 = 3, // pending 1st attempt
|
||||||
EP_STATE_ATTEMPT_MAX = 15
|
EP_STATE_ATTEMPT_MAX = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -459,6 +460,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
|
|||||||
|
|
||||||
tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param;
|
tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param;
|
||||||
_tuh_cfg = cfg->max3421;
|
_tuh_cfg = cfg->max3421;
|
||||||
|
_tuh_cfg.max_nak = tu_min8(_tuh_cfg.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,7 +680,6 @@ static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool
|
|||||||
bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) {
|
bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) {
|
||||||
uint8_t const ep_num = tu_edpt_number(ep_addr);
|
uint8_t const ep_num = tu_edpt_number(ep_addr);
|
||||||
uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr);
|
uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir);
|
max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir);
|
||||||
TU_VERIFY(ep);
|
TU_VERIFY(ep);
|
||||||
|
|
||||||
@@ -702,14 +703,19 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abort a queued transfer. Note: it can only abort transfer that has not been started
|
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) {
|
||||||
// Return true if a queued transfer is aborted, false if there is no transfer to abort
|
uint8_t const ep_num = tu_edpt_number(ep_addr);
|
||||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr);
|
||||||
(void) rhport;
|
max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir);
|
||||||
(void) dev_addr;
|
TU_VERIFY(ep);
|
||||||
(void) ep_addr;
|
|
||||||
|
|
||||||
return false;
|
if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) {
|
||||||
|
hcd_int_disable(rhport);
|
||||||
|
ep->state = EP_STATE_ABORTING;
|
||||||
|
hcd_int_enable(rhport);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked
|
// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked
|
||||||
@@ -819,7 +825,6 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re
|
|||||||
static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
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 hrsl = reg_read(rhport, HRSL_ADDR, in_isr);
|
||||||
uint8_t const hresult = hrsl & HRSL_RESULT_MASK;
|
uint8_t const hresult = hrsl & HRSL_RESULT_MASK;
|
||||||
|
|
||||||
uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
||||||
uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0;
|
uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0;
|
||||||
uint8_t const ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1;
|
uint8_t const ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1;
|
||||||
@@ -829,41 +834,45 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
|||||||
|
|
||||||
xfer_result_t xfer_result;
|
xfer_result_t xfer_result;
|
||||||
switch(hresult) {
|
switch(hresult) {
|
||||||
case HRSL_SUCCESS:
|
|
||||||
xfer_result = XFER_RESULT_SUCCESS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HRSL_STALL:
|
|
||||||
xfer_result = XFER_RESULT_STALLED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HRSL_NAK:
|
case HRSL_NAK:
|
||||||
if (ep_num == 0) {
|
if (ep->state == EP_STATE_ABORTING) {
|
||||||
// control endpoint -> retry immediately
|
ep->state = EP_STATE_IDLE;
|
||||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
|
||||||
} else {
|
} else {
|
||||||
if (ep->state < EP_STATE_ATTEMPT_MAX) {
|
if (ep_num == 0) {
|
||||||
|
// control endpoint -> retry immediately and return
|
||||||
|
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||||
|
return;
|
||||||
|
} else if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) {
|
||||||
ep->state++;
|
ep->state++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
max3421_ep_t * next_ep = find_next_pending_ep(ep);
|
max3421_ep_t * next_ep = find_next_pending_ep(ep);
|
||||||
if (ep == next_ep) {
|
if (ep == next_ep) {
|
||||||
// this endpoint is only one pending -> retry immediately
|
// this endpoint is only one pending -> retry immediately
|
||||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||||
} else if (next_ep) {
|
} else if (next_ep) {
|
||||||
// switch to next pending endpoint TODO could have issue with double buffered if not clear previously out data
|
// switch to next pending endpoint
|
||||||
|
// TODO could have issue with double buffered if not clear previously out data
|
||||||
xact_generic(rhport, next_ep, true, in_isr);
|
xact_generic(rhport, next_ep, true, in_isr);
|
||||||
} else {
|
} else {
|
||||||
// no more pending in this frame -> clear busy
|
// no more pending in this frame -> clear busy
|
||||||
atomic_flag_clear(&_hcd_data.busy);
|
atomic_flag_clear(&_hcd_data.busy);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case HRSL_BAD_REQ:
|
case HRSL_BAD_REQ:
|
||||||
// occurred when initialized without any pending transfer. Skip for now
|
// occurred when initialized without any pending transfer. Skip for now
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case HRSL_SUCCESS:
|
||||||
|
xfer_result = XFER_RESULT_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HRSL_STALL:
|
||||||
|
xfer_result = XFER_RESULT_STALLED;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TU_LOG3("HRSL: %02X\r\n", hrsl);
|
TU_LOG3("HRSL: %02X\r\n", hrsl);
|
||||||
xfer_result = XFER_RESULT_FAILED;
|
xfer_result = XFER_RESULT_FAILED;
|
||||||
@@ -942,9 +951,8 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
|||||||
if (hirq & HIRQ_FRAME_IRQ) {
|
if (hirq & HIRQ_FRAME_IRQ) {
|
||||||
_hcd_data.frame_count++;
|
_hcd_data.frame_count++;
|
||||||
|
|
||||||
|
// reset all endpoints nak counter, retry with 1st pending ep.
|
||||||
max3421_ep_t* ep_retry = NULL;
|
max3421_ep_t* ep_retry = NULL;
|
||||||
|
|
||||||
// reset all endpoints attempt counter
|
|
||||||
for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) {
|
for (size_t i = 0; 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->packet_size && ep->state > EP_STATE_ATTEMPT_1) {
|
if (ep->packet_size && ep->state > EP_STATE_ATTEMPT_1) {
|
||||||
|
Reference in New Issue
Block a user