summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2024-05-15 16:42:15 +0700
committerGitHub <[email protected]>2024-05-15 16:42:15 +0700
commitcf532d14792411fd40ad3433fe0ce9959887ef4b (patch)
treea440d4f6cb2f9d1275dda5b22a98ecee742c3163
parent3c24ba3ff2eb5fdb4e214f668a25ed2038a847ad (diff)
parent50278211f4117079ce5eda396f68d802d9cda615 (diff)
Merge pull request #2646 from hathach/max3421-abort-xfer
Implement Max3421 hcd abort xfer
-rw-r--r--.circleci/config.yml8
-rw-r--r--.github/actions/setup_toolchain/espressif/action.yml2
-rw-r--r--.github/workflows/codeql.yml6
-rw-r--r--.github/workflows/hil_test.yml2
-rw-r--r--hw/bsp/nrf/family.cmake10
-rw-r--r--src/portable/analog/max3421/hcd_max3421.c80
6 files changed, 66 insertions, 42 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 77ab30f00..2d4532aee 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -91,7 +91,13 @@ jobs:
family: << parameters.family >>
- run:
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:
build:
diff --git a/.github/actions/setup_toolchain/espressif/action.yml b/.github/actions/setup_toolchain/espressif/action.yml
index a4c6127c6..494b7910e 100644
--- a/.github/actions/setup_toolchain/espressif/action.yml
+++ b/.github/actions/setup_toolchain/espressif/action.yml
@@ -23,7 +23,7 @@ runs:
id: cache-toolchain-espressif
with:
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
if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true'
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 1f7b60b9c..be4c2dd87 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -59,10 +59,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- - name: Install ARM GCC
- uses: carlosperate/arm-none-eabi-gcc-action@v1
+ - name: Setup Toolchain
+ uses: ./.github/actions/setup_toolchain
with:
- release: '11.2-2022.02'
+ toolchain: 'arm-gcc'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml
index adb5bf00e..39a9060a2 100644
--- a/.github/workflows/hil_test.yml
+++ b/.github/workflows/hil_test.yml
@@ -41,7 +41,7 @@ jobs:
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT
- - name: Setup ARM Toolchain
+ - name: Setup Toolchain
uses: ./.github/actions/setup_toolchain
with:
toolchain: 'arm-gcc'
diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake
index 5de69a8a3..9e86374dc 100644
--- a/hw/bsp/nrf/family.cmake
+++ b/hw/bsp/nrf/family.cmake
@@ -101,6 +101,15 @@ endfunction()
#------------------------------------
# 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)
family_configure_common(${TARGET} ${RTOS})
@@ -133,4 +142,5 @@ function(family_configure_example TARGET RTOS)
# Flashing
family_flash_jlink(${TARGET})
+# family_flash_adafruit_nrfutil(${TARGET})
endfunction()
diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c
index 4dc93d2d8..d9b8e1fc3 100644
--- a/src/portable/analog/max3421/hcd_max3421.c
+++ b/src/portable/analog/max3421/hcd_max3421.c
@@ -174,7 +174,8 @@ enum {
enum {
EP_STATE_IDLE = 0,
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
};
@@ -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_cfg = cfg->max3421;
+ _tuh_cfg.max_nak = tu_min8(_tuh_cfg.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1);
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) {
uint8_t const ep_num = tu_edpt_number(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);
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;
}
-// Abort a queued transfer. Note: it can only abort transfer that has not been started
-// Return true if a queued transfer is aborted, false if there is no transfer to abort
-bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
- (void) rhport;
- (void) dev_addr;
- (void) ep_addr;
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) {
+ uint8_t const ep_num = tu_edpt_number(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);
+ TU_VERIFY(ep);
- 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
@@ -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) {
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;
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;
@@ -829,34 +834,30 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
xfer_result_t xfer_result;
switch(hresult) {
- case HRSL_SUCCESS:
- xfer_result = XFER_RESULT_SUCCESS;
- break;
-
- case HRSL_STALL:
- xfer_result = XFER_RESULT_STALLED;
- break;
-
case HRSL_NAK:
- if (ep_num == 0) {
- // control endpoint -> retry immediately
- hxfr_write(rhport, _hcd_data.hxfr, in_isr);
+ if (ep->state == EP_STATE_ABORTING) {
+ ep->state = EP_STATE_IDLE;
} 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++;
}
+ }
- 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, in_isr);
- } else if (next_ep) {
- // 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);
- } else {
- // no more pending in this frame -> clear busy
- atomic_flag_clear(&_hcd_data.busy);
- }
+ 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, in_isr);
+ } else if (next_ep) {
+ // 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);
+ } else {
+ // no more pending in this frame -> clear busy
+ atomic_flag_clear(&_hcd_data.busy);
}
return;
@@ -864,6 +865,14 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
// occurred when initialized without any pending transfer. Skip for now
return;
+ case HRSL_SUCCESS:
+ xfer_result = XFER_RESULT_SUCCESS;
+ break;
+
+ case HRSL_STALL:
+ xfer_result = XFER_RESULT_STALLED;
+ break;
+
default:
TU_LOG3("HRSL: %02X\r\n", hrsl);
xfer_result = XFER_RESULT_FAILED;
@@ -942,9 +951,8 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
if (hirq & HIRQ_FRAME_IRQ) {
_hcd_data.frame_count++;
+ // reset all endpoints nak counter, retry with 1st pending ep.
max3421_ep_t* ep_retry = NULL;
-
- // reset all endpoints attempt counter
for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) {
max3421_ep_t* ep = &_hcd_data.ep[i];
if (ep->packet_size && ep->state > EP_STATE_ATTEMPT_1) {
@@ -1004,7 +1012,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
// clear all interrupt except SNDBAV_IRQ (never clear by us). Note RCVDAV_IRQ, HXFRDN_IRQ already clear while processing
hirq &= (uint8_t) ~HIRQ_SNDBAV_IRQ;
- if ( hirq ) {
+ if (hirq) {
hirq_write(rhport, hirq, in_isr);
}
}