From 22be079117f50c2448fbd8744c75cd59cabb7de3 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Tue, 27 Jun 2023 18:23:17 +0200 Subject: [PATCH 01/64] now ncm_device is always called from TinyUSB context (but this does actually not help) --- src/net/net_glue.c | 114 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 4 deletions(-) diff --git a/src/net/net_glue.c b/src/net/net_glue.c index 116ff122d..9c60b67d9 100755 --- a/src/net/net_glue.c +++ b/src/net/net_glue.c @@ -42,6 +42,7 @@ #include "dhserver.h" #include "tusb.h" +#include "device/usbd_pvt.h" // for usbd_defer_func #define EV_RCVFRAME_READY 1 @@ -51,7 +52,13 @@ static struct netif netif_data; /* shared between tud_network_recv_cb() and service_traffic() */ -static struct pbuf *received_frame; +static struct pbuf *received_frame = NULL; + +static uint8_t rcv_buff[4000]; +static uint16_t rcv_buff_len = 0; + +static uint8_t xmt_buff[4000]; +static uint16_t xmt_buff_len = 0; #ifndef OPT_NET_192_168 #define OPT_NET_192_168 10 @@ -82,6 +89,9 @@ static const dhcp_config_t dhcp_config = void tud_network_init_cb(void) +/** + * initialize any network state back to the beginning + */ { /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ if (received_frame != NULL) @@ -93,6 +103,13 @@ void tud_network_init_cb(void) +static void context_tinyusb_tud_network_recv_renew(void *param) +{ + tud_network_recv_renew(); +} // context_tinyusb_tud_network_recv_renew + + + static void net_glue_usb_to_lwip(void *ptr) /** * handle any packet received by tud_network_recv_cb() in context of lwIP @@ -100,20 +117,44 @@ static void net_glue_usb_to_lwip(void *ptr) { //printf("net_glue_usb_to_lwip\n"); +#if 0 if (received_frame != NULL) { ethernet_input(received_frame, &netif_data); pbuf_free(received_frame); received_frame = NULL; tud_network_recv_renew(); } +#else + if (rcv_buff_len != 0) { + struct pbuf *p = pbuf_alloc(PBUF_RAW, rcv_buff_len, PBUF_POOL); + + if (p) { + memcpy(p->payload, rcv_buff, rcv_buff_len); + ethernet_input(p, &netif_data); + pbuf_free(p); + rcv_buff_len = 0; +#if 0 + tud_network_recv_renew(); +#else + // did not change anything + usbd_defer_func(context_tinyusb_tud_network_recv_renew, NULL, false); +#endif + } + } +#endif } // net_glue_usb_to_lwip bool tud_network_recv_cb(const uint8_t *src, uint16_t size) +/** + * Copy buffer (host ->) TinyUSB -> lwIP (-> application) + * \return false if the packet buffer was not accepted + */ { //printf("!!!!!!!!!!!!!!tud_network_recv_cb(%p,%u)\n", src, size); +#if 0 /* this shouldn't happen, but if we get another packet before parsing the previous, we must signal our inability to accept it */ if (received_frame) @@ -131,12 +172,27 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) tcpip_callback_with_block(net_glue_usb_to_lwip, NULL, 0); } } +#else + if (rcv_buff_len != 0) + return false; + + if (size != 0) { + assert(size < sizeof(rcv_buff)); + memcpy(rcv_buff, src, size); + rcv_buff_len = size; + tcpip_callback_with_block(net_glue_usb_to_lwip, NULL, 0); + } +#endif return true; } // tud_network_recv_cb uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) +/** + * (application ->) lwIP -> TinyUSB (-> host) + * \return number of bytes copied + */ { //printf("!!!!!!!!!!!!!!tud_network_xmit_cb(%p,%p,%u)\n", dst, ref, arg); @@ -158,32 +214,82 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) } return len; -#else +#elif 0 struct pbuf *p = (struct pbuf *)ref; (void)arg; /* unused for this example */ return pbuf_copy_partial(p, dst, p->tot_len, 0); +#else + uint16_t r = xmt_buff_len; + memcpy(dst, xmt_buff, xmt_buff_len); + xmt_buff_len = 0; + return r; #endif } // tud_network_xmit_cb +static void conext_tinyusb_linkoutput(void *param) +{ + if ( !tud_network_can_xmit(xmt_buff_len)) { + printf("conext_tinyusb_linkoutput: sleep\n"); + vTaskDelay(pdMS_TO_TICKS(10)); + usbd_defer_func(conext_tinyusb_linkoutput, NULL, false); + } + else { + tud_network_xmit(xmt_buff, 0); + } +} // conext_tinyusb_linkoutput + + + static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) +/** + * called by lwIP to transmit data to TinyUSB + */ { (void)netif; - for (;;) { +#if 0 + // TODO: interesting: if !can_xmit, then TinyUSB does the transfer in the "background" + // but this is priority dependent. Better sleep here for a short period and then repeat. + for (;;) + { + //printf("linkoutput_fn()\n"); /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ - if (!tud_ready()) + if ( !tud_ready()) { return ERR_USE; + } /* if the network driver can accept another packet, we make it happen */ if (tud_network_can_xmit(p->tot_len)) { tud_network_xmit(p, 0 /* unused for this example */); return ERR_OK; } +// else +// return ERR_USE; +// +// tud_task(); + //printf("linkoutput_fn - sleep\n"); + vTaskDelay(pdMS_TO_TICKS(10)); + } + + return ERR_USE; +#else + if ( !tud_ready()) { + return ERR_USE; } + + if (xmt_buff_len != 0) { + return ERR_USE; + } + + xmt_buff_len = pbuf_copy_partial(p, xmt_buff, p->tot_len, 0); + usbd_defer_func(conext_tinyusb_linkoutput, NULL, false); + + return ERR_OK; +#endif } // linkoutput_fn From 48687bc529d1540f6e3ac3a6fb1cabee7fc4b256 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 09:55:31 +0200 Subject: [PATCH 02/64] disable other USB classes --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f26c217e4..4a04033fe 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,12 +24,12 @@ else() set(DEFAULT_OPT_PROBE_DEBUG_OUT 1) endif() -option(OPT_CMSIS_DAPV1 "Enable CMSIS-DAPv1" 1) -option(OPT_CMSIS_DAPV2 "Enable CMSIS-DAPv2" 1) +option(OPT_CMSIS_DAPV1 "Enable CMSIS-DAPv1" 0) +option(OPT_CMSIS_DAPV2 "Enable CMSIS-DAPv2" 0) option(OPT_TARGET_UART "Enable CDC for target UART I/O" 1) option(OPT_PROBE_DEBUG_OUT "Enable CDC for probe debug output" ${DEFAULT_OPT_PROBE_DEBUG_OUT}) option(OPT_SIGROK "Enable sigrok" 0) -option(OPT_MSC "Enable Mass Storage Device" 1) +option(OPT_MSC "Enable Mass Storage Device" 0) option(OPT_MSC_RAM_UF2 "Enable file 'RAM.UF2' on Mass Storage" 1) set(OPT_NET "NCM" CACHE STRING "Enable lwIP on the Pico via ECM/NCM/RNDIS") set(OPT_NET_192_168 14 CACHE STRING "Set the subnet of 192.168.x") From 4a4dea7298c06ae483c3647989b1915f88407ead Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 09:55:48 +0200 Subject: [PATCH 03/64] update doc --- doc/lwIP-notes.adoc | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/doc/lwIP-notes.adoc b/doc/lwIP-notes.adoc index 078747b36..5918a7e38 100755 --- a/doc/lwIP-notes.adoc +++ b/doc/lwIP-notes.adoc @@ -93,6 +93,38 @@ must be set on built). Good command line for measurement: iperf -c 192.168.14.1 -e -i 1 -l 1024 +## Testing + +Good test case is the following script: + + for MSS in 90 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1459 1460 1500; do iperf -c 192.168.14.1 -e -i 1 -l 1024 -M $MSS; sleep 10; done + +Monitor performance/errors with Wireshark. + + +## Some words about ncm_device.c and net_glue.c + +### Remarks about possible Bugs + +* not sure, but perhaps it is best to call all functions within ncm_device in the FreeRTOS + context of TinyUSB +* `wNtbOutMaxDatagrams` must be set to 1 [2023-06-27] +** iperf runs then +** Systemview still has problems +** `wNtbOutMaxDatagrams == 0` generates a lot of retries with iperf +* I guess that the *major problem* lies within handle_incoming_datagram() because it changes values + on an incoming packet although tud_network_recv_renew() is still handling the old one +* is there multicore a problem!? I have seen retries with multicore even with + `wNtbOutMaxDatagrams = 1` +* I think it is assumed, that TinyUSB and lwIP are running in the same task (but in my scenario they don't) + + +### Remarks about Functionality + +* tud_network_xmit() puts the data to be transmitted into a buffer (out of two). + After copying the contents, it tries to start transmission via ncm_start_tx() + which checks if there is an ongoing transmission + ## Log From b8b35fbcb00185d005ddd32311effda6435d16b0 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 09:56:44 +0200 Subject: [PATCH 04/64] some enhancements(?) --- src/net/net_sysview.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/net/net_sysview.c b/src/net/net_sysview.c index 76e4af68a..3e6bc7a6f 100755 --- a/src/net/net_sysview.c +++ b/src/net/net_sysview.c @@ -131,12 +131,14 @@ static void sysview_try_send(void *ctx) if (cnt != 0) { // the write has either 512 bytes (so send it) or the stream is empty (so send it as well) err = tcp_write(m_pcb_client, tx_buf, cnt, TCP_WRITE_FLAG_COPY); + //printf("sysview_try_send: %d %d\n", cnt, block_call_to_tcp_output); if (err != ERR_OK) { picoprobe_error("sysview_try_send/a: %d\n", err); sysview_close(m_pcb_client); } - if ( !block_call_to_tcp_output && tcp_sndbuf(m_pcb_client) < TCP_SND_BUF / 2) { + if ( !block_call_to_tcp_output && tcp_sndbuf(m_pcb_client) < 3 * TCP_SND_BUF / 4) { + printf("sysview_try_send: flush %d %d\n", tcp_sndbuf(m_pcb_client), 3 * TCP_SND_BUF / 4); block_call_to_tcp_output = true; tcp_output(m_pcb_client); } @@ -146,6 +148,14 @@ static void sysview_try_send(void *ctx) } } } + else { + printf("sysview_try_send: no tcp_sndbuf!!!!\n"); + if ( !block_call_to_tcp_output) { + printf("sysview_try_send: flush\n"); + block_call_to_tcp_output = true; + tcp_output(m_pcb_client); + } + } } } // sysview_try_send @@ -153,7 +163,7 @@ static void sysview_try_send(void *ctx) static err_t sysview_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len) { - //printf("sysview_sent(%p,%p,%d) %d\n", arg, tpcb, len, m_state); + printf("sysview_sent(%p,%p,%d) %d\n", arg, tpcb, len, m_state); block_call_to_tcp_output = false; @@ -248,9 +258,10 @@ static err_t sysview_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err_t sysview_poll(void *arg, struct tcp_pcb *tpcb) { - //printf("sysview_poll(%p,%p) %d\n", arg, tpcb, m_state); + printf("sysview_poll(%p,%p) %d\n", arg, tpcb, m_state); - sysview_try_send(NULL); + //sysview_try_send(NULL); + tcpip_callback_with_block(sysview_try_send, NULL, 0); return ERR_OK; } // sysview_poll @@ -281,7 +292,7 @@ uint32_t net_sysview_send(const uint8_t *buf, uint32_t cnt) * * \param buf pointer to the buffer to be sent, if NULL then remaining space in stream is returned * \param cnt number of bytes to be sent - * \return if \buf is NULL the remaining space in stream is returned, otherwise the number of bytes + * \return if \buf is NULL the remaining space in stream is returned, otherwise the number of bytes sent */ { uint32_t r = 0; From 0a84045a877a310922dd7aef8ddc6c13f8a01ce0 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 09:57:04 +0200 Subject: [PATCH 05/64] comments & renaming --- src/net/net_glue.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/net/net_glue.c b/src/net/net_glue.c index 9c60b67d9..d6a9458ca 100755 --- a/src/net/net_glue.c +++ b/src/net/net_glue.c @@ -152,7 +152,7 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) * \return false if the packet buffer was not accepted */ { - //printf("!!!!!!!!!!!!!!tud_network_recv_cb(%p,%u)\n", src, size); + //printf("tud_network_recv_cb(%p,%u)\n", src, size); #if 0 /* this shouldn't happen, but if we get another packet before @@ -190,7 +190,11 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) /** + * This does the actual copy operation into a TinyUSB buffer. + * Called by tud_network_xmit(). + * * (application ->) lwIP -> TinyUSB (-> host) + * * \return number of bytes copied */ { @@ -230,17 +234,17 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) -static void conext_tinyusb_linkoutput(void *param) +static void context_tinyusb_linkoutput(void *param) { if ( !tud_network_can_xmit(xmt_buff_len)) { - printf("conext_tinyusb_linkoutput: sleep\n"); + printf("context_tinyusb_linkoutput: sleep\n"); vTaskDelay(pdMS_TO_TICKS(10)); - usbd_defer_func(conext_tinyusb_linkoutput, NULL, false); + usbd_defer_func(context_tinyusb_linkoutput, NULL, false); } else { tud_network_xmit(xmt_buff, 0); } -} // conext_tinyusb_linkoutput +} // context_tinyusb_linkoutput @@ -286,7 +290,7 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) } xmt_buff_len = pbuf_copy_partial(p, xmt_buff, p->tot_len, 0); - usbd_defer_func(conext_tinyusb_linkoutput, NULL, false); + usbd_defer_func(context_tinyusb_linkoutput, NULL, false); return ERR_OK; #endif From 6acd73ab60463875ea40ca3af49ff4ce5c8dea37 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 10:07:13 +0200 Subject: [PATCH 06/64] own version of ncm_device --- CMakeLists.txt | 6 + src/net/tinyusb/ncm.h | 69 +++++ src/net/tinyusb/ncm_device.c | 511 +++++++++++++++++++++++++++++++++++ src/net/tinyusb/net_device.h | 118 ++++++++ 4 files changed, 704 insertions(+) create mode 100755 src/net/tinyusb/ncm.h create mode 100755 src/net/tinyusb/ncm_device.c create mode 100755 src/net/tinyusb/net_device.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a04033fe..6b2f71894 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -258,9 +258,15 @@ if(NOT OPT_NET STREQUAL "") ) if(NOT OPT_NET STREQUAL "NCM") + # !NCM target_sources(${PROJECT} PRIVATE ${PICO_TINYUSB_PATH}/lib/networking/rndis_reports.c ) + else() + # NCM: use own copy of ncm_device, original one must be outcommented + target_sources(${PROJECT} PRIVATE + src/net/tinyusb/ncm_device.c + ) endif() target_include_directories(${PROJECT} PRIVATE diff --git a/src/net/tinyusb/ncm.h b/src/net/tinyusb/ncm.h new file mode 100755 index 000000000..96ba11fbc --- /dev/null +++ b/src/net/tinyusb/ncm.h @@ -0,0 +1,69 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef _TUSB_NCM_H_ +#define _TUSB_NCM_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +// Table 4.3 Data Class Interface Protocol Codes +typedef enum +{ + NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 +} ncm_data_interface_protocol_code_t; + + +// Table 6.2 Class-Specific Request Codes for Network Control Model subclass +typedef enum +{ + NCM_SET_ETHERNET_MULTICAST_FILTERS = 0x40, + NCM_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41, + NCM_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42, + NCM_SET_ETHERNET_PACKET_FILTER = 0x43, + NCM_GET_ETHERNET_STATISTIC = 0x44, + NCM_GET_NTB_PARAMETERS = 0x80, + NCM_GET_NET_ADDRESS = 0x81, + NCM_SET_NET_ADDRESS = 0x82, + NCM_GET_NTB_FORMAT = 0x83, + NCM_SET_NTB_FORMAT = 0x84, + NCM_GET_NTB_INPUT_SIZE = 0x85, + NCM_SET_NTB_INPUT_SIZE = 0x86, + NCM_GET_MAX_DATAGRAM_SIZE = 0x87, + NCM_SET_MAX_DATAGRAM_SIZE = 0x88, + NCM_GET_CRC_MODE = 0x89, + NCM_SET_CRC_MODE = 0x8A, +} ncm_request_code_t; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c new file mode 100755 index 000000000..9e9580249 --- /dev/null +++ b/src/net/tinyusb/ncm_device.c @@ -0,0 +1,511 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + +#include "device/usbd.h" +#include "device/usbd_pvt.h" +#include "net_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +#define NTH16_SIGNATURE 0x484D434E +#define NDP16_SIGNATURE_NCM0 0x304D434E +#define NDP16_SIGNATURE_NCM1 0x314D434E + +typedef struct TU_ATTR_PACKED +{ + uint16_t wLength; + uint16_t bmNtbFormatsSupported; + uint32_t dwNtbInMaxSize; + uint16_t wNdbInDivisor; + uint16_t wNdbInPayloadRemainder; + uint16_t wNdbInAlignment; + uint16_t wReserved; + uint32_t dwNtbOutMaxSize; + uint16_t wNdbOutDivisor; + uint16_t wNdbOutPayloadRemainder; + uint16_t wNdbOutAlignment; + uint16_t wNtbOutMaxDatagrams; +} ntb_parameters_t; + +typedef struct TU_ATTR_PACKED +{ + uint32_t dwSignature; + uint16_t wHeaderLength; + uint16_t wSequence; + uint16_t wBlockLength; + uint16_t wNdpIndex; +} nth16_t; + +typedef struct TU_ATTR_PACKED +{ + uint16_t wDatagramIndex; + uint16_t wDatagramLength; +} ndp16_datagram_t; + +typedef struct TU_ATTR_PACKED +{ + uint32_t dwSignature; + uint16_t wLength; + uint16_t wNextNdpIndex; + ndp16_datagram_t datagram[]; +} ndp16_t; + +typedef union TU_ATTR_PACKED { + struct { + nth16_t nth; + ndp16_t ndp; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; +} transmit_ntb_t; + +struct ecm_notify_struct +{ + tusb_control_request_t header; + uint32_t downlink, uplink; +}; + +typedef struct +{ + uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface + uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active + + uint8_t ep_notif; + uint8_t ep_in; + uint8_t ep_out; + + const ndp16_t *ndp; + uint8_t num_datagrams, current_datagram_index; + + enum { + REPORT_SPEED, + REPORT_CONNECTED, + REPORT_DONE + } report_state; + bool report_pending; + + uint8_t current_ntb; // Index in transmit_ntb[] that is currently being filled with datagrams + uint8_t datagram_count; // Number of datagrams in transmit_ntb[current_ntb] + uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram + uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE + uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + + uint16_t nth_sequence; // Sequence number counter for transmitted NTBs + + bool transferring; + +} ncm_interface_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01, + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, + .wNdbInDivisor = 4, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 4, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 0 +}; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; + +tu_static ncm_interface_t ncm_interface; + +/* + * Set up the NTB state in ncm_interface to be ready to add datagrams. + */ +static void ncm_prepare_for_tx(void) { + ncm_interface.datagram_count = 0; + // datagrams start after all the headers + ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) + + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); +} + +/* + * If not already transmitting, start sending the current NTB to the host and swap buffers + * to start filling the other one with datagrams. + */ +static void ncm_start_tx(void) { + if (ncm_interface.transferring) { + return; + } + + transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + size_t ntb_length = ncm_interface.next_datagram_offset; + + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(nth16_t); + ntb->nth.wSequence = ncm_interface.nth_sequence++; + ntb->nth.wBlockLength = ntb_length; + ntb->nth.wNdpIndex = sizeof(nth16_t); + + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ndp16_t) + (ncm_interface.datagram_count + 1) * sizeof(ndp16_datagram_t); + ntb->ndp.wNextNdpIndex = 0; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = 0; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; + + // Kick off an endpoint transfer + usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); + ncm_interface.transferring = true; + + // Swap to the other NTB and clear it out + ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; + ncm_prepare_for_tx(); +} + +tu_static struct ecm_notify_struct ncm_notify_connected = +{ + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_NETWORK_CONNECTION, + .wValue = 1 /* Connected */, + .wLength = 0, + }, +}; + +tu_static struct ecm_notify_struct ncm_notify_speed_change = +{ + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, + .wLength = 8, + }, + .downlink = 10000000, + .uplink = 10000000, +}; + +void tud_network_recv_renew(void) +{ + if (!ncm_interface.num_datagrams) + { + usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); + return; + } + + const ndp16_t *ndp = ncm_interface.ndp; + const int i = ncm_interface.current_datagram_index; + ncm_interface.current_datagram_index++; + ncm_interface.num_datagrams--; + + tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); +} + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ + +void netd_init(void) +{ + tu_memclr(&ncm_interface, sizeof(ncm_interface)); + ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; + ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; + ncm_prepare_for_tx(); +} + +void netd_reset(uint8_t rhport) +{ + (void) rhport; + + netd_init(); +} + +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +{ + // confirm interface hasn't already been allocated + TU_ASSERT(0 == ncm_interface.ep_notif, 0); + + //------------- Management Interface -------------// + ncm_interface.itf_num = itf_desc->bInterfaceNumber; + + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const * p_desc = tu_desc_next( itf_desc ); + + // Communication Functional Descriptors + while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) + { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // notification endpoint (if any) + if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) + { + TU_ASSERT( usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0 ); + + ncm_interface.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + //------------- Data Interface -------------// + // - CDC-NCM data interface has 2 alternate settings + // - 0 : zero endpoints for inactive (default) + // - 1 : IN & OUT endpoints for transfer of NTBs + TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); + + do + { + tusb_desc_interface_t const * data_itf_desc = (tusb_desc_interface_t const *) p_desc; + TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } while((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len)); + + // Pair of endpoints + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); + + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in) ); + + drv_len += 2*sizeof(tusb_desc_endpoint_t); + + return drv_len; +} + +static void ncm_report(void) +{ + uint8_t const rhport = 0; + if (ncm_interface.report_state == REPORT_SPEED) { + ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); + ncm_interface.report_state = REPORT_CONNECTED; + ncm_interface.report_pending = true; + } else if (ncm_interface.report_state == REPORT_CONNECTED) { + ncm_notify_connected.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); + ncm_interface.report_state = REPORT_DONE; + ncm_interface.report_pending = true; + } +} + +TU_ATTR_WEAK void tud_network_link_state_cb(bool state) +{ + (void)state; +} + +// Handle class control request +// return false to stall control endpoint (e.g unsupported request) +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + if ( stage != CONTROL_STAGE_SETUP ) return true; + + switch ( request->bmRequestType_bit.type ) + { + case TUSB_REQ_TYPE_STANDARD: + switch ( request->bRequest ) + { + case TUSB_REQ_GET_INTERFACE: + { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); + + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + } + break; + + case TUSB_REQ_SET_INTERFACE: + { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + uint8_t const req_alt = (uint8_t) request->wValue; + + // Only valid for Data Interface with Alternate is either 0 or 1 + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); + + if (req_alt != ncm_interface.itf_data_alt) { + ncm_interface.itf_data_alt = req_alt; + + if (ncm_interface.itf_data_alt) { + if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { + tud_network_recv_renew(); // prepare for incoming datagrams + } + if (!ncm_interface.report_pending) { + ncm_report(); + } + } + + tud_network_link_state_cb(ncm_interface.itf_data_alt); + } + + tud_control_status(rhport, request); + } + break; + + // unsupported request + default: return false; + } + break; + + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY (ncm_interface.itf_num == request->wIndex); + + if (NCM_GET_NTB_PARAMETERS == request->bRequest) + { + tud_control_xfer(rhport, request, (void*)(uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } + + break; + + // unsupported request + default: return false; + } + + return true; +} + +static void handle_incoming_datagram(uint32_t len) +{ + uint32_t size = len; + + if (len == 0) { + return; + } + + TU_ASSERT(size >= sizeof(nth16_t), ); + + const nth16_t *hdr = (const nth16_t *)receive_ntb; + TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE, ); + TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len, ); + + const ndp16_t *ndp = (const ndp16_t *)(receive_ntb + hdr->wNdpIndex); + TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1, ); + TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len, ); + + int num_datagrams = (ndp->wLength - 12) / 4; + ncm_interface.current_datagram_index = 0; + ncm_interface.num_datagrams = 0; + ncm_interface.ndp = ndp; + for (int i = 0; i < num_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) + { + ncm_interface.num_datagrams++; + } + + tud_network_recv_renew(); +} + +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) rhport; + (void) result; + + /* new datagram receive_ntb */ + if (ep_addr == ncm_interface.ep_out ) + { + handle_incoming_datagram(xferred_bytes); + } + + /* data transmission finished */ + if (ep_addr == ncm_interface.ep_in ) + { + if (ncm_interface.transferring) { + ncm_interface.transferring = false; + } + + // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now + if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { + ncm_start_tx(); + } + } + + if (ep_addr == ncm_interface.ep_notif ) + { + ncm_interface.report_pending = false; + ncm_report(); + } + + return true; +} + +// poll network driver for its ability to accept another packet to transmit +bool tud_network_can_xmit(uint16_t size) +{ + TU_VERIFY(ncm_interface.itf_data_alt == 1); + + if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { + TU_LOG2("NTB full [by count]\r\n"); + return false; + } + + size_t next_datagram_offset = ncm_interface.next_datagram_offset; + if (next_datagram_offset + size > ncm_interface.ntb_in_size) { + TU_LOG2("ntb full [by size]\r\n"); + return false; + } + + return true; +} + +void tud_network_xmit(void *ref, uint16_t arg) +{ + transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + size_t next_datagram_offset = ncm_interface.next_datagram_offset; + + uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); + + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; + + ncm_interface.datagram_count++; + next_datagram_offset += size; + + // round up so the next datagram is aligned correctly + next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); + next_datagram_offset -= (next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); + + ncm_interface.next_datagram_offset = next_datagram_offset; + + ncm_start_tx(); +} + +#endif diff --git a/src/net/tinyusb/net_device.h b/src/net/tinyusb/net_device.h new file mode 100755 index 000000000..399916355 --- /dev/null +++ b/src/net/tinyusb/net_device.h @@ -0,0 +1,118 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Peter Lawrence + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_NET_DEVICE_H_ +#define _TUSB_NET_DEVICE_H_ + +#include "class/cdc/cdc.h" + +#if CFG_TUD_ECM_RNDIS && CFG_TUD_NCM +#error "Cannot enable both ECM_RNDIS and NCM network drivers" +#endif + +#include "ncm.h" + +/* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ +#define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +/* Maximum Transmission Unit (in bytes) of the network, including Ethernet header */ +#ifndef CFG_TUD_NET_MTU +#define CFG_TUD_NET_MTU 1514 +#endif + +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE +#define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE +#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB +#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 +#endif + +#ifndef CFG_TUD_NCM_ALIGNMENT +#define CFG_TUD_NCM_ALIGNMENT 4 +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + +// indicate to network driver that client has finished with the packet provided to network_recv_cb() +void tud_network_recv_renew(void); + +// poll network driver for its ability to accept another packet to transmit +bool tud_network_can_xmit(uint16_t size); + +// if network_can_xmit() returns true, network_xmit() can be called once +void tud_network_xmit(void *ref, uint16_t arg); + +//--------------------------------------------------------------------+ +// Application Callbacks (WEAK is optional) +//--------------------------------------------------------------------+ + +// client must provide this: return false if the packet buffer was not accepted +bool tud_network_recv_cb(const uint8_t *src, uint16_t size); + +// client must provide this: copy from network stack packet pointer to dst +uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); + +//------------- ECM/RNDIS -------------// + +// client must provide this: initialize any network state back to the beginning +void tud_network_init_cb(void); + +// client must provide this: 48-bit MAC address +// TODO removed later since it is not part of tinyusb stack +extern uint8_t tud_network_mac_address[6]; + +//------------- NCM -------------// + +// callback to client providing optional indication of internal state of network driver +void tud_network_link_state_cb(bool state); + +//--------------------------------------------------------------------+ +// INTERNAL USBD-CLASS DRIVER API +//--------------------------------------------------------------------+ +void netd_init (void); +void netd_reset (uint8_t rhport); +uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool netd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void netd_report (uint8_t *buf, uint16_t len); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_NET_DEVICE_H_ */ From 349b8163a24dd7f4f1934722ff124e7826cdb1ad Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 10:11:08 +0200 Subject: [PATCH 07/64] reformatted --- src/net/tinyusb/ncm_device.c | 632 ++++++++++++++++------------------- 1 file changed, 292 insertions(+), 340 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 9e9580249..7a9b94596 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -28,7 +28,7 @@ #include "tusb_option.h" -#if ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if 1 // ( CFG_TUD_ENABLED && CFG_TUD_NCM ) #include "device/usbd.h" #include "device/usbd_pvt.h" @@ -42,87 +42,79 @@ #define NDP16_SIGNATURE_NCM0 0x304D434E #define NDP16_SIGNATURE_NCM1 0x314D434E -typedef struct TU_ATTR_PACKED -{ - uint16_t wLength; - uint16_t bmNtbFormatsSupported; - uint32_t dwNtbInMaxSize; - uint16_t wNdbInDivisor; - uint16_t wNdbInPayloadRemainder; - uint16_t wNdbInAlignment; - uint16_t wReserved; - uint32_t dwNtbOutMaxSize; - uint16_t wNdbOutDivisor; - uint16_t wNdbOutPayloadRemainder; - uint16_t wNdbOutAlignment; - uint16_t wNtbOutMaxDatagrams; +typedef struct TU_ATTR_PACKED { + uint16_t wLength; + uint16_t bmNtbFormatsSupported; + uint32_t dwNtbInMaxSize; + uint16_t wNdbInDivisor; + uint16_t wNdbInPayloadRemainder; + uint16_t wNdbInAlignment; + uint16_t wReserved; + uint32_t dwNtbOutMaxSize; + uint16_t wNdbOutDivisor; + uint16_t wNdbOutPayloadRemainder; + uint16_t wNdbOutAlignment; + uint16_t wNtbOutMaxDatagrams; } ntb_parameters_t; -typedef struct TU_ATTR_PACKED -{ - uint32_t dwSignature; - uint16_t wHeaderLength; - uint16_t wSequence; - uint16_t wBlockLength; - uint16_t wNdpIndex; +typedef struct TU_ATTR_PACKED { + uint32_t dwSignature; + uint16_t wHeaderLength; + uint16_t wSequence; + uint16_t wBlockLength; + uint16_t wNdpIndex; } nth16_t; -typedef struct TU_ATTR_PACKED -{ - uint16_t wDatagramIndex; - uint16_t wDatagramLength; +typedef struct TU_ATTR_PACKED { + uint16_t wDatagramIndex; + uint16_t wDatagramLength; } ndp16_datagram_t; -typedef struct TU_ATTR_PACKED -{ - uint32_t dwSignature; - uint16_t wLength; - uint16_t wNextNdpIndex; - ndp16_datagram_t datagram[]; +typedef struct TU_ATTR_PACKED { + uint32_t dwSignature; + uint16_t wLength; + uint16_t wNextNdpIndex; + ndp16_datagram_t datagram[]; } ndp16_t; typedef union TU_ATTR_PACKED { - struct { - nth16_t nth; - ndp16_t ndp; - }; - uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; + struct { + nth16_t nth; + ndp16_t ndp; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; } transmit_ntb_t; -struct ecm_notify_struct -{ - tusb_control_request_t header; - uint32_t downlink, uplink; +struct ecm_notify_struct { + tusb_control_request_t header; + uint32_t downlink, uplink; }; -typedef struct -{ - uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface - uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active +typedef struct { + uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface + uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active - uint8_t ep_notif; - uint8_t ep_in; - uint8_t ep_out; + uint8_t ep_notif; + uint8_t ep_in; + uint8_t ep_out; - const ndp16_t *ndp; - uint8_t num_datagrams, current_datagram_index; + const ndp16_t *ndp; + uint8_t num_datagrams, current_datagram_index; - enum { - REPORT_SPEED, - REPORT_CONNECTED, - REPORT_DONE - } report_state; - bool report_pending; + enum { + REPORT_SPEED, REPORT_CONNECTED, REPORT_DONE + } report_state; + bool report_pending; - uint8_t current_ntb; // Index in transmit_ntb[] that is currently being filled with datagrams - uint8_t datagram_count; // Number of datagrams in transmit_ntb[current_ntb] - uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram - uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE - uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + uint8_t current_ntb; // Index in transmit_ntb[] that is currently being filled with datagrams + uint8_t datagram_count; // Number of datagrams in transmit_ntb[current_ntb] + uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram + uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE + uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB - uint16_t nth_sequence; // Sequence number counter for transmitted NTBs + uint16_t nth_sequence; // Sequence number counter for transmitted NTBs - bool transferring; + bool transferring; } ncm_interface_t; @@ -131,18 +123,18 @@ typedef struct //--------------------------------------------------------------------+ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { - .wLength = sizeof(ntb_parameters_t), - .bmNtbFormatsSupported = 0x01, - .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, - .wNdbInDivisor = 4, - .wNdbInPayloadRemainder = 0, - .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, - .wReserved = 0, - .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, - .wNdbOutDivisor = 4, + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01, + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, + .wNdbInDivisor = 4, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, - .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 0 + .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 0 }; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; @@ -155,10 +147,10 @@ tu_static ncm_interface_t ncm_interface; * Set up the NTB state in ncm_interface to be ready to add datagrams. */ static void ncm_prepare_for_tx(void) { - ncm_interface.datagram_count = 0; - // datagrams start after all the headers - ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) - + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); + ncm_interface.datagram_count = 0; + // datagrams start after all the headers + ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) + + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); } /* @@ -166,346 +158,306 @@ static void ncm_prepare_for_tx(void) { * to start filling the other one with datagrams. */ static void ncm_start_tx(void) { - if (ncm_interface.transferring) { - return; - } - - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t ntb_length = ncm_interface.next_datagram_offset; - - // Fill in NTB header - ntb->nth.dwSignature = NTH16_SIGNATURE; - ntb->nth.wHeaderLength = sizeof(nth16_t); - ntb->nth.wSequence = ncm_interface.nth_sequence++; - ntb->nth.wBlockLength = ntb_length; - ntb->nth.wNdpIndex = sizeof(nth16_t); - - // Fill in NDP16 header and terminator - ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; - ntb->ndp.wLength = sizeof(ndp16_t) + (ncm_interface.datagram_count + 1) * sizeof(ndp16_datagram_t); - ntb->ndp.wNextNdpIndex = 0; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = 0; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; - - // Kick off an endpoint transfer - usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); - ncm_interface.transferring = true; - - // Swap to the other NTB and clear it out - ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; - ncm_prepare_for_tx(); + if (ncm_interface.transferring) { + return; + } + + transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + size_t ntb_length = ncm_interface.next_datagram_offset; + + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(nth16_t); + ntb->nth.wSequence = ncm_interface.nth_sequence++; + ntb->nth.wBlockLength = ntb_length; + ntb->nth.wNdpIndex = sizeof(nth16_t); + + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ndp16_t) + (ncm_interface.datagram_count + 1) * sizeof(ndp16_datagram_t); + ntb->ndp.wNextNdpIndex = 0; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = 0; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; + + // Kick off an endpoint transfer + usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); + ncm_interface.transferring = true; + + // Swap to the other NTB and clear it out + ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; + ncm_prepare_for_tx(); } -tu_static struct ecm_notify_struct ncm_notify_connected = -{ - .header = { - .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = CDC_NOTIF_NETWORK_CONNECTION, - .wValue = 1 /* Connected */, - .wLength = 0, - }, -}; +tu_static struct ecm_notify_struct ncm_notify_connected = { .header = { .bmRequestType_bit = { .recipient = + TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = + CDC_NOTIF_NETWORK_CONNECTION, .wValue = 1 /* Connected */, .wLength = 0, }, }; -tu_static struct ecm_notify_struct ncm_notify_speed_change = -{ - .header = { - .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, - .wLength = 8, - }, - .downlink = 10000000, - .uplink = 10000000, -}; +tu_static struct ecm_notify_struct ncm_notify_speed_change = { .header = { .bmRequestType_bit = { .recipient = + TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = + CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wLength = 8, }, .downlink = 10000000, .uplink = 10000000, }; -void tud_network_recv_renew(void) -{ - if (!ncm_interface.num_datagrams) - { - usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); - return; - } +void tud_network_recv_renew(void) { + if (!ncm_interface.num_datagrams) { + usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); + return; + } - const ndp16_t *ndp = ncm_interface.ndp; - const int i = ncm_interface.current_datagram_index; - ncm_interface.current_datagram_index++; - ncm_interface.num_datagrams--; + const ndp16_t *ndp = ncm_interface.ndp; + const int i = ncm_interface.current_datagram_index; + ncm_interface.current_datagram_index++; + ncm_interface.num_datagrams--; - tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); + tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void netd_init(void) -{ - tu_memclr(&ncm_interface, sizeof(ncm_interface)); - ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; - ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; - ncm_prepare_for_tx(); +void netd_init(void) { + tu_memclr(&ncm_interface, sizeof(ncm_interface)); + ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; + ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; + ncm_prepare_for_tx(); } -void netd_reset(uint8_t rhport) -{ - (void) rhport; +void netd_reset(uint8_t rhport) { + (void) rhport; - netd_init(); + netd_init(); } -uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -{ - // confirm interface hasn't already been allocated - TU_ASSERT(0 == ncm_interface.ep_notif, 0); +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + // confirm interface hasn't already been allocated + TU_ASSERT(0 == ncm_interface.ep_notif, 0); - //------------- Management Interface -------------// - ncm_interface.itf_num = itf_desc->bInterfaceNumber; + //------------- Management Interface -------------// + ncm_interface.itf_num = itf_desc->bInterfaceNumber; - uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const * p_desc = tu_desc_next( itf_desc ); + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const *p_desc = tu_desc_next(itf_desc); - // Communication Functional Descriptors - while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) - { - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } + // Communication Functional Descriptors + while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } - // notification endpoint (if any) - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { - TU_ASSERT( usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0 ); + // notification endpoint (if any) + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { + TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const* ) p_desc), 0); - ncm_interface.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + ncm_interface.ep_notif = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } - //------------- Data Interface -------------// - // - CDC-NCM data interface has 2 alternate settings - // - 0 : zero endpoints for inactive (default) - // - 1 : IN & OUT endpoints for transfer of NTBs - TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); + //------------- Data Interface -------------// + // - CDC-NCM data interface has 2 alternate settings + // - 0 : zero endpoints for inactive (default) + // - 1 : IN & OUT endpoints for transfer of NTBs + TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); - do - { - tusb_desc_interface_t const * data_itf_desc = (tusb_desc_interface_t const *) p_desc; - TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); + do { + tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const*) p_desc; + TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } while((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len)); + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } while ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len)); - // Pair of endpoints - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); + // Pair of endpoints + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in) ); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); - drv_len += 2*sizeof(tusb_desc_endpoint_t); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); - return drv_len; + return drv_len; } -static void ncm_report(void) -{ - uint8_t const rhport = 0; - if (ncm_interface.report_state == REPORT_SPEED) { - ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); - ncm_interface.report_state = REPORT_CONNECTED; - ncm_interface.report_pending = true; - } else if (ncm_interface.report_state == REPORT_CONNECTED) { - ncm_notify_connected.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); - ncm_interface.report_state = REPORT_DONE; - ncm_interface.report_pending = true; - } +static void ncm_report(void) { + uint8_t const rhport = 0; + if (ncm_interface.report_state == REPORT_SPEED) { + ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_speed_change, + sizeof(ncm_notify_speed_change)); + ncm_interface.report_state = REPORT_CONNECTED; + ncm_interface.report_pending = true; + } + else if (ncm_interface.report_state == REPORT_CONNECTED) { + ncm_notify_connected.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_connected, sizeof(ncm_notify_connected)); + ncm_interface.report_state = REPORT_DONE; + ncm_interface.report_pending = true; + } } -TU_ATTR_WEAK void tud_network_link_state_cb(bool state) -{ - (void)state; +TU_ATTR_WEAK void tud_network_link_state_cb(bool state) { + (void) state; } // Handle class control request // return false to stall control endpoint (e.g unsupported request) -bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ - if ( stage != CONTROL_STAGE_SETUP ) return true; +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { + if (stage != CONTROL_STAGE_SETUP) + return true; - switch ( request->bmRequestType_bit.type ) - { + switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: - switch ( request->bRequest ) - { - case TUSB_REQ_GET_INTERFACE: - { - uint8_t const req_itfnum = (uint8_t) request->wIndex; - TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); - - tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); + + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); } - break; - - case TUSB_REQ_SET_INTERFACE: - { - uint8_t const req_itfnum = (uint8_t) request->wIndex; - uint8_t const req_alt = (uint8_t) request->wValue; - - // Only valid for Data Interface with Alternate is either 0 or 1 - TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); - - if (req_alt != ncm_interface.itf_data_alt) { - ncm_interface.itf_data_alt = req_alt; - - if (ncm_interface.itf_data_alt) { - if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { - tud_network_recv_renew(); // prepare for incoming datagrams - } - if (!ncm_interface.report_pending) { - ncm_report(); - } - } + break; + + case TUSB_REQ_SET_INTERFACE: { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + uint8_t const req_alt = (uint8_t) request->wValue; - tud_network_link_state_cb(ncm_interface.itf_data_alt); - } + // Only valid for Data Interface with Alternate is either 0 or 1 + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); + + if (req_alt != ncm_interface.itf_data_alt) { + ncm_interface.itf_data_alt = req_alt; + + if (ncm_interface.itf_data_alt) { + if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { + tud_network_recv_renew(); // prepare for incoming datagrams + } + if (!ncm_interface.report_pending) { + ncm_report(); + } + } + + tud_network_link_state_cb(ncm_interface.itf_data_alt); + } - tud_control_status(rhport, request); + tud_control_status(rhport, request); } - break; + break; - // unsupported request - default: return false; - } - break; + // unsupported request + default: + return false; + } + break; case TUSB_REQ_TYPE_CLASS: - TU_VERIFY (ncm_interface.itf_num == request->wIndex); + TU_VERIFY(ncm_interface.itf_num == request->wIndex); - if (NCM_GET_NTB_PARAMETERS == request->bRequest) - { - tud_control_xfer(rhport, request, (void*)(uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); - } + if (NCM_GET_NTB_PARAMETERS == request->bRequest) { + tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } - break; + break; - // unsupported request - default: return false; - } + // unsupported request + default: + return false; + } - return true; + return true; } -static void handle_incoming_datagram(uint32_t len) -{ - uint32_t size = len; +static void handle_incoming_datagram(uint32_t len) { + uint32_t size = len; - if (len == 0) { - return; - } + if (len == 0) { + return; + } - TU_ASSERT(size >= sizeof(nth16_t), ); + TU_ASSERT(size >= sizeof(nth16_t),); - const nth16_t *hdr = (const nth16_t *)receive_ntb; - TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE, ); - TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len, ); + const nth16_t *hdr = (const nth16_t*) receive_ntb; + TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE,); + TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len,); - const ndp16_t *ndp = (const ndp16_t *)(receive_ntb + hdr->wNdpIndex); - TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1, ); - TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len, ); + const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); + TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1,); + TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len,); - int num_datagrams = (ndp->wLength - 12) / 4; - ncm_interface.current_datagram_index = 0; - ncm_interface.num_datagrams = 0; - ncm_interface.ndp = ndp; - for (int i = 0; i < num_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) - { - ncm_interface.num_datagrams++; - } + int num_datagrams = (ndp->wLength - 12) / 4; + ncm_interface.current_datagram_index = 0; + ncm_interface.num_datagrams = 0; + ncm_interface.ndp = ndp; + for (int i = 0; i < num_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) { + ncm_interface.num_datagrams++; + } - tud_network_recv_renew(); + tud_network_recv_renew(); } -bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void) rhport; - (void) result; - - /* new datagram receive_ntb */ - if (ep_addr == ncm_interface.ep_out ) - { - handle_incoming_datagram(xferred_bytes); - } +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) rhport; + (void) result; - /* data transmission finished */ - if (ep_addr == ncm_interface.ep_in ) - { - if (ncm_interface.transferring) { - ncm_interface.transferring = false; + /* new datagram receive_ntb */ + if (ep_addr == ncm_interface.ep_out) { + handle_incoming_datagram(xferred_bytes); } - // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now - if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { - ncm_start_tx(); + /* data transmission finished */ + if (ep_addr == ncm_interface.ep_in) { + if (ncm_interface.transferring) { + ncm_interface.transferring = false; + } + + // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now + if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { + ncm_start_tx(); + } } - } - if (ep_addr == ncm_interface.ep_notif ) - { - ncm_interface.report_pending = false; - ncm_report(); - } + if (ep_addr == ncm_interface.ep_notif) { + ncm_interface.report_pending = false; + ncm_report(); + } - return true; + return true; } // poll network driver for its ability to accept another packet to transmit -bool tud_network_can_xmit(uint16_t size) -{ - TU_VERIFY(ncm_interface.itf_data_alt == 1); - - if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { - TU_LOG2("NTB full [by count]\r\n"); - return false; - } - - size_t next_datagram_offset = ncm_interface.next_datagram_offset; - if (next_datagram_offset + size > ncm_interface.ntb_in_size) { - TU_LOG2("ntb full [by size]\r\n"); - return false; - } - - return true; +bool tud_network_can_xmit(uint16_t size) { + TU_VERIFY(ncm_interface.itf_data_alt == 1); + + if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { + TU_LOG2("NTB full [by count]\r\n"); + return false; + } + + size_t next_datagram_offset = ncm_interface.next_datagram_offset; + if (next_datagram_offset + size > ncm_interface.ntb_in_size) { + TU_LOG2("ntb full [by size]\r\n"); + return false; + } + + return true; } -void tud_network_xmit(void *ref, uint16_t arg) -{ - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t next_datagram_offset = ncm_interface.next_datagram_offset; +void tud_network_xmit(void *ref, uint16_t arg) { + transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + size_t next_datagram_offset = ncm_interface.next_datagram_offset; - uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); + uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; - ncm_interface.datagram_count++; - next_datagram_offset += size; + ncm_interface.datagram_count++; + next_datagram_offset += size; - // round up so the next datagram is aligned correctly - next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); - next_datagram_offset -= (next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); + // round up so the next datagram is aligned correctly + next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); + next_datagram_offset -= (next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); - ncm_interface.next_datagram_offset = next_datagram_offset; + ncm_interface.next_datagram_offset = next_datagram_offset; - ncm_start_tx(); + ncm_start_tx(); } #endif From 34affa523b2e6c21109cb6535879939d496f1bef Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 10:13:21 +0200 Subject: [PATCH 08/64] current version of ncm_device with a lot of fixes(?) --- src/net/tinyusb/ncm_device.c | 344 +++++++++++++++++++++++++++-------- 1 file changed, 267 insertions(+), 77 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 7a9b94596..0313722b0 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -28,11 +28,14 @@ #include "tusb_option.h" -#if 1 // ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if 1 // ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "net_device.h" +#include + +#include "task.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -99,7 +102,8 @@ typedef struct { uint8_t ep_out; const ndp16_t *ndp; - uint8_t num_datagrams, current_datagram_index; + uint8_t rcv_datagram_num, rcv_datagram_index; + uint16_t rcv_datagram_size; enum { REPORT_SPEED, REPORT_CONNECTED, REPORT_DONE @@ -122,42 +126,45 @@ typedef struct { // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { - .wLength = sizeof(ntb_parameters_t), - .bmNtbFormatsSupported = 0x01, - .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, - .wNdbInDivisor = 4, - .wNdbInPayloadRemainder = 0, - .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, - .wReserved = 0, - .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, - .wNdbOutDivisor = 4, - .wNdbOutPayloadRemainder = 0, - .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 0 -}; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { .wLength = + sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE+400, .wNdbInDivisor = 4, .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, .wReserved = 0, .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 16 // 0=no limit + }; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; tu_static ncm_interface_t ncm_interface; -/* +static void ncm_prepare_for_tx(void) +/** * Set up the NTB state in ncm_interface to be ready to add datagrams. + * + * \pre + * \a ncm_interface.current_ntb must be set correctly */ -static void ncm_prepare_for_tx(void) { +{ + //printf("ncm_prepare_for_tx()\n"); ncm_interface.datagram_count = 0; // datagrams start after all the headers - ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) - + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); + ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) + + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); + memset(transmit_ntb + ncm_interface.current_ntb, 0, sizeof(transmit_ntb_t)); } /* * If not already transmitting, start sending the current NTB to the host and swap buffers * to start filling the other one with datagrams. */ -static void ncm_start_tx(void) { +static void ncm_start_tx(void) +{ + //printf("ncm_start_tx() - %d %d\n", ncm_interface.transferring, ncm_interface.datagram_count); + if (ncm_interface.transferring) { return; } @@ -188,49 +195,195 @@ static void ncm_start_tx(void) { ncm_prepare_for_tx(); } + + tu_static struct ecm_notify_struct ncm_notify_connected = { .header = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = CDC_NOTIF_NETWORK_CONNECTION, .wValue = 1 /* Connected */, .wLength = 0, }, }; tu_static struct ecm_notify_struct ncm_notify_speed_change = { .header = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = - CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wLength = 8, }, .downlink = 10000000, .uplink = 10000000, }; + CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wLength = 8, }, .downlink = 1000000, .uplink = 1000000, }; + + + +void tud_network_recv_renew(void) +/** + * context: lwIP & TinyUSB + */ +{ + printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); + if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { // && ncm_interface.rcv_datagram_size != 0) { + bool r; + + printf("--0\n"); +#if 0 + r = usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); + if ( !r) { + printf("--0.0\n"); + return; + } +#else + static uint8_t buffi[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; + + r = usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); + if ( !r) { + printf("--0.0\n"); + return; + } + memcpy(receive_ntb, buffi, sizeof(receive_ntb)); +#endif + + printf("--1\n"); -void tud_network_recv_renew(void) { - if (!ncm_interface.num_datagrams) { - usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); + const nth16_t *hdr = (const nth16_t*) receive_ntb; + TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE,); + //TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= ncm_interface.rcv_datagram_size,); + + const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); + TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1,); + //TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= ncm_interface.rcv_datagram_size,); + + printf("--2\n"); + + int max_rcv_datagrams = (ndp->wLength - 12) / 4; + ncm_interface.rcv_datagram_index = 0; + ncm_interface.rcv_datagram_num = 0; + ncm_interface.ndp = ndp; +#if 0 + for (int i = 0; i < max_rcv_datagrams && ndp->datagram[i].wDatagramIndex != 0 && ndp->datagram[i].wDatagramLength != 0; i++) + { + ncm_interface.rcv_datagram_num++; + } +#else + int i = 0; + while (i <= max_rcv_datagrams) + { + printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); + if (ndp->datagram[i].wDatagramIndex == 0 && ndp->datagram[i].wDatagramLength == 0) { + break; + } + ++i; + ncm_interface.rcv_datagram_num++; + } +#endif + +#if 1 + printf("tud_network_recv_renew: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, + ndp->wNextNdpIndex); +#endif + + } + + if (ncm_interface.rcv_datagram_num == 0) { return; } const ndp16_t *ndp = ncm_interface.ndp; - const int i = ncm_interface.current_datagram_index; - ncm_interface.current_datagram_index++; - ncm_interface.num_datagrams--; + const int i = ncm_interface.rcv_datagram_index; + ncm_interface.rcv_datagram_index++; - tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); + printf("tud_network_recv_renew->: %d %p %d %d\n", i, ndp, ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); + + if ( !tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength)) { + printf("!!!!!!!!!!!!!!!!!!!!\n"); + ncm_interface.rcv_datagram_index--; + } } + + +static void handle_incoming_datagram(uint32_t len) +{ + uint32_t size = len; + + printf("handle_incoming_datagram(%lu)\n", len); + + ncm_interface.rcv_datagram_size = len; + + if (len == 0) { + //return; + } + +#if 0 + TU_ASSERT(size >= sizeof(nth16_t),); + + const nth16_t *hdr = (const nth16_t*) receive_ntb; + TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE,); + TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len,); + + const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); + TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1,); + TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len,); + + int max_rcv_datagrams = (ndp->wLength - 12) / 4; + ncm_interface.rcv_datagram_index = 0; + ncm_interface.rcv_datagram_num = 0; + ncm_interface.ndp = ndp; + for (int i = 0; i < max_rcv_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) { + ncm_interface.rcv_datagram_num++; + } + +#if 1 + printf("handle_incoming_datagram: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, + ndp->wNextNdpIndex); +#endif +#endif + + tud_network_recv_renew(); +} + + + //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void netd_init(void) { +void netd_init(void) +/** + * called on start + * + * context: TinyUSB + */ +{ + printf("netd_init() [%p]\n", xTaskGetCurrentTaskHandle()); + tu_memclr(&ncm_interface, sizeof(ncm_interface)); ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; ncm_prepare_for_tx(); } -void netd_reset(uint8_t rhport) { + + +void netd_reset(uint8_t rhport) +/** + * called with rhport=0 + * + * context: TinyUSB + */ +{ (void) rhport; + printf("netd_reset(%d) [%p]\n", rhport, xTaskGetCurrentTaskHandle()); + netd_init(); } -uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + + +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +/** + * called with max_len=143 + * + * context: TinyUSB + */ +{ // confirm interface hasn't already been allocated TU_ASSERT(0 == ncm_interface.ep_notif, 0); + printf("netd_open(%d,%p,%d) [%p]\n", rhport, itf_desc, max_len, xTaskGetCurrentTaskHandle()); + //------------- Management Interface -------------// ncm_interface.itf_num = itf_desc->bInterfaceNumber; @@ -277,7 +430,14 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 return drv_len; } -static void ncm_report(void) { + + +static void ncm_report(void) +/** + * called on init + */ +{ + //printf("ncm_report - %d\n", ncm_interface.report_state); uint8_t const rhport = 0; if (ncm_interface.report_state == REPORT_SPEED) { ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; @@ -294,15 +454,34 @@ static void ncm_report(void) { } } -TU_ATTR_WEAK void tud_network_link_state_cb(bool state) { + + +TU_ATTR_WEAK void tud_network_link_state_cb(bool state) +/** + * called on init three times with 1/0/1 + * + * context: TinyUSB + */ +{ (void) state; + printf("tud_network_link_state_cb(%d) [%p]\n", state, xTaskGetCurrentTaskHandle()); } + + // Handle class control request // return false to stall control endpoint (e.g unsupported request) -bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +/** + * Called on init of connection + * + * context: TinyUSB + */ +{ + printf("netd_control_xfer_cb(%d, %d, %p) [%p]\n", rhport, stage, request, xTaskGetCurrentTaskHandle()); + if (stage != CONTROL_STAGE_SETUP) - return true; + return true ; switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: @@ -343,13 +522,15 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t // unsupported request default: - return false; + return false ; } break; case TUSB_REQ_TYPE_CLASS: TU_VERIFY(ncm_interface.itf_num == request->wIndex); + //printf("netd_control_xfer_cb/TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); + if (NCM_GET_NTB_PARAMETERS == request->bRequest) { tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); } @@ -358,53 +539,37 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t // unsupported request default: - return false; + return false ; } - return true; + return true ; } -static void handle_incoming_datagram(uint32_t len) { - uint32_t size = len; - if (len == 0) { - return; - } - - TU_ASSERT(size >= sizeof(nth16_t),); - const nth16_t *hdr = (const nth16_t*) receive_ntb; - TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE,); - TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len,); - - const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); - TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1,); - TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len,); - - int num_datagrams = (ndp->wLength - 12) / 4; - ncm_interface.current_datagram_index = 0; - ncm_interface.num_datagrams = 0; - ncm_interface.ndp = ndp; - for (int i = 0; i < num_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) { - ncm_interface.num_datagrams++; - } - - tud_network_recv_renew(); -} - -bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +/** + * context: TinyUSB + */ +{ (void) rhport; (void) result; + //printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); + /* new datagram receive_ntb */ if (ep_addr == ncm_interface.ep_out) { + //printf(" EP_OUT\n"); handle_incoming_datagram(xferred_bytes); } /* data transmission finished */ if (ep_addr == ncm_interface.ep_in) { + //printf(" EP_IN %d %d %d\n", ncm_interface.transferring, ncm_interface.datagram_count, + //ncm_interface.itf_data_alt); if (ncm_interface.transferring) { ncm_interface.transferring = false; + //tud_network_recv_renew(); } // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now @@ -414,35 +579,60 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } if (ep_addr == ncm_interface.ep_notif) { + //printf(" EP_NOTIF\n"); ncm_interface.report_pending = false; ncm_report(); } - return true; + return true ; } -// poll network driver for its ability to accept another packet to transmit -bool tud_network_can_xmit(uint16_t size) { + + +bool tud_network_can_xmit(uint16_t size) +/** + * poll network driver for its ability to accept another packet to transmit + * + * context: lwIP + * + */ +{ TU_VERIFY(ncm_interface.itf_data_alt == 1); + size_t next_datagram_offset = ncm_interface.next_datagram_offset; + +#if 0 + printf("tud_network_can_xmit(%d) %d %d - %d %d [%p]\n", size, ncm_interface.datagram_count, ncm_interface.max_datagrams_per_ntb, + next_datagram_offset, ncm_interface.ntb_in_size, xTaskGetCurrentTaskHandle()); +#endif + if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { - TU_LOG2("NTB full [by count]\r\n"); - return false; + // this happens if max... is set to 1 + printf("NTB full [by count]\r\n"); + return false ; } - size_t next_datagram_offset = ncm_interface.next_datagram_offset; if (next_datagram_offset + size > ncm_interface.ntb_in_size) { - TU_LOG2("ntb full [by size]\r\n"); - return false; + // this happens + printf("ntb full [by size]\r\n"); + return false ; } - return true; + return true ; } -void tud_network_xmit(void *ref, uint16_t arg) { + + +void tud_network_xmit(void *ref, uint16_t arg) +/** + * context: lwIP. + */ +{ transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; size_t next_datagram_offset = ncm_interface.next_datagram_offset; + //printf("tud_network_xmit(%p,%d) [%p]\n", ref, arg, xTaskGetCurrentTaskHandle()); + uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; From 5fe76f93c9e4f20306b431d1715a7a721862c5c8 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 10:56:01 +0200 Subject: [PATCH 09/64] .wNtbOutMaxDatagrams = 1 : works with iperf but not with Systemview --- src/net/tinyusb/ncm_device.c | 92 ++++++++++++++++++++++++++++++------ src/net/tinyusb/net_device.h | 1 + 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 0313722b0..7acd6d4a3 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -28,7 +28,11 @@ #include "tusb_option.h" -#if 1 // ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + +#if ECLIPSE_GUI + #define tu_static static +#endif #include "device/usbd.h" #include "device/usbd_pvt.h" @@ -126,14 +130,20 @@ typedef struct { // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { .wLength = - sizeof(ntb_parameters_t), +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { + .wLength = sizeof(ntb_parameters_t), .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported - .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE+400, .wNdbInDivisor = 4, .wNdbInPayloadRemainder = 0, - .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, .wReserved = 0, .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, - .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 16 // 0=no limit - }; + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE+400, + .wNdbInDivisor = 4, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 4, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 1 // 0=no limit +}; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; @@ -197,13 +207,32 @@ static void ncm_start_tx(void) -tu_static struct ecm_notify_struct ncm_notify_connected = { .header = { .bmRequestType_bit = { .recipient = - TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = - CDC_NOTIF_NETWORK_CONNECTION, .wValue = 1 /* Connected */, .wLength = 0, }, }; +tu_static struct ecm_notify_struct ncm_notify_connected = { + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_NETWORK_CONNECTION, + .wValue = 1 /* Connected */, + .wLength = 0, + }, +}; -tu_static struct ecm_notify_struct ncm_notify_speed_change = { .header = { .bmRequestType_bit = { .recipient = - TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = - CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wLength = 8, }, .downlink = 1000000, .uplink = 1000000, }; +tu_static struct ecm_notify_struct ncm_notify_speed_change = { + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, + .wLength = 8, + }, + .downlink = 1000000, + .uplink = 1000000, +}; @@ -218,6 +247,41 @@ void tud_network_recv_renew(void) printf("--0\n"); #if 0 + // funny effect with "iperf -c 192.168.14.1 -e -i 1 -l 22 -M 200" + // receive_ntb is overwritten! + // [10:37:42.330968 0.000287] 38.039 ( 0) - 0 90 54 + // [10:37:42.331361 0.000394] 38.039 ( 0) - 1 146 114 + // [10:37:42.331770 0.000409] 38.039 ( 0) - 2 262 254 + // [10:37:42.332156 0.000386] 38.039 ( 0) - 3 518 254 + // [10:37:42.332566 0.000410] 38.039 ( 0) - 4 774 254 + // [10:37:42.332979 0.000412] 38.039 ( 0) - 5 1030 254 + // [10:37:42.333436 0.000457] 38.040 ( 1) - 6 1286 254 + // [10:37:42.333871 0.000435] 38.040 ( 0) - 7 1542 254 + // [10:37:42.334303 0.000432] 38.040 ( 0) - 8 1798 254 + // [10:37:42.334732 0.000429] 38.040 ( 0) - 9 2054 254 + // [10:37:42.335162 0.000431] 38.040 ( 0) - 10 2310 254 + // [10:37:42.335614 0.000452] 38.040 ( 0) - 11 0 0 + // [10:37:42.335992 0.000378] 38.040 ( 0) - tud_network_recv_renew: 11 0x304d434e 56 0 + // [10:37:42.336912 0.000919] 38.040 ( 0) - tud_network_recv_renew->: 0 200103D8 90 54 OK + // [10:37:42.337755 0.000844] 38.041 ( 1) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.338528 0.000773] 38.041 ( 0) - tud_network_recv_renew->: 1 200103D8 146 114 OK + // [10:37:42.339365 0.000837] 38.041 ( 0) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.340137 0.000771] 38.041 ( 0) - tud_network_recv_renew->: 2 200103D8 262 254 OK + // [10:37:42.340965 0.000828] 38.042 ( 1) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.341748 0.000783] 38.042 ( 0) - tud_network_recv_renew->: 3 200103D8 518 254 OK + // [10:37:42.342572 0.000824] 38.042 ( 0) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.343345 0.000773] 38.042 ( 0) - tud_network_recv_renew->: 4 200103D8 774 254 OK + // [10:37:42.344172 0.000827] 38.043 ( 1) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.344932 0.000760] 38.043 ( 0) - tud_network_recv_renew->: 5 200103D8 1030 254 OK + // [10:37:42.345778 0.000847] 38.043 ( 0) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.346567 0.000788] 38.043 ( 0) - tud_network_recv_renew->: 6 200103D8 1626 254 FAIL + // [10:37:42.347423 0.000856] 38.044 ( 1) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.348195 0.000772] 38.044 ( 0) - tud_network_recv_renew->: 7 200103D8 1882 254 FAIL + // [10:37:42.349037 0.000842] 38.044 ( 0) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.349828 0.000792] 38.044 ( 0) - tud_network_recv_renew->: 8 200103D8 0 0 FAIL + // [10:37:42.350546 0.000717] 38.046 ( 2) - handle_incoming_datagram(2136) + // [10:37:42.351156 0.000611] 38.046 ( 0) - tud_network_recv_renew() - 11 [20020120] + // [10:37:42.351867 0.000711] 38.046 ( 0) - tud_network_recv_renew->: 9 200103D8 0 0 FAIL & DEAD r = usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); if ( !r) { printf("--0.0\n"); diff --git a/src/net/tinyusb/net_device.h b/src/net/tinyusb/net_device.h index 399916355..f6ab42b48 100755 --- a/src/net/tinyusb/net_device.h +++ b/src/net/tinyusb/net_device.h @@ -28,6 +28,7 @@ #ifndef _TUSB_NET_DEVICE_H_ #define _TUSB_NET_DEVICE_H_ +#include #include "class/cdc/cdc.h" #if CFG_TUD_ECM_RNDIS && CFG_TUD_NCM From 18256d6557f464092d276b66a1f97cb14d6976fc Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:05:01 +0200 Subject: [PATCH 10/64] config --- include/FreeRTOSConfig.h | 5 ++++- include/lwipopts.h | 12 ++++++++---- include/picoprobe_config.h | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/FreeRTOSConfig.h b/include/FreeRTOSConfig.h index fad0cf741..95809da63 100644 --- a/include/FreeRTOSConfig.h +++ b/include/FreeRTOSConfig.h @@ -97,6 +97,9 @@ #warning "configGENERATE_RUN_TIME_STATS is set" #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() do {} while( 0 ) #define portALT_GET_RUN_TIME_COUNTER_VALUE( dest ) ( dest = *((uint32_t *)(TF_TIMER_BASE + TF_TIMER_TIMERAWL_OFFSET)) ) + + #undef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 1 #endif /* Co-routine related definitions. */ @@ -117,7 +120,7 @@ */ /* SMP port only */ -#define configNUM_CORES 2 +#define configNUM_CORES 1 #define configTICK_CORE 1 #define configRUN_MULTIPLE_PRIORITIES 1 #if configNUM_CORES != 1 diff --git a/include/lwipopts.h b/include/lwipopts.h index f971b424b..315e3acef 100755 --- a/include/lwipopts.h +++ b/include/lwipopts.h @@ -69,8 +69,12 @@ #define TCP_MSS (1500 - 20 - 20) // MTU minus header sizes (best value til now) #define TCP_SND_BUF (4 * TCP_MSS) // good tuning -//#define TCP_WND TCP_SND_BUF -//#define TCP_OVERSIZE (TCP_MSS / 4) // til now no good value found +//#define TCP_WND (2 * TCP_MSS) +//#define TCP_OVERSIZE TCP_MSS // til now no good value found + +//#define TCP_TMR_INTERVAL 50 // TODO just a test (default: 250) +//#define TCP_FAST_INTERVAL 250 +//#define TCP_SLOW_INTERVAL 100 //-------------------------------------- // memory @@ -108,7 +112,7 @@ #define API_LIB_DEBUG LWIP_DBG_OFF #define API_MSG_DEBUG LWIP_DBG_OFF #define AUTOIP_DEBUG LWIP_DBG_OFF -#define DHCP_DEBUG LWIP_DBG_ON +#define DHCP_DEBUG LWIP_DBG_OFF #define DNS_DEBUG LWIP_DBG_OFF #define ETHARP_DEBUG LWIP_DBG_OFF #define ICMP_DEBUG LWIP_DBG_OFF @@ -125,7 +129,7 @@ #define TCP_INPUT_DEBUG LWIP_DBG_OFF #define TCP_FR_DEBUG LWIP_DBG_OFF #define TCP_RTO_DEBUG LWIP_DBG_OFF -#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_ON #define TCP_WND_DEBUG LWIP_DBG_OFF #define TCP_RST_DEBUG LWIP_DBG_OFF #define TCP_OUTPUT_DEBUG LWIP_DBG_OFF diff --git a/include/picoprobe_config.h b/include/picoprobe_config.h index abfee7402..14ca1b58c 100755 --- a/include/picoprobe_config.h +++ b/include/picoprobe_config.h @@ -66,7 +66,7 @@ #if 0 #define PROBE_CPU_CLOCK_KHZ ((120 + 2*24) * 1000) // overclocked, even 264MHz seems to be no problem #else -#define PROBE_CPU_CLOCK_KHZ ((120 + 0*24) * 1000) // overclocked, even 264MHz seems to be no problem +#define PROBE_CPU_CLOCK_KHZ ((120 + 5*24) * 1000) // overclocked, even 264MHz seems to be no problem #endif From 8851751f92d674b6fed39be24b1f4667d1aea001 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:05:20 +0200 Subject: [PATCH 11/64] minor other changes --- src/cdc/cdc_debug.c | 4 ++-- src/net/net_glue.c | 2 +- src/net/net_sysview.c | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cdc/cdc_debug.c b/src/cdc/cdc_debug.c index 981b8c59a..aed740bf5 100644 --- a/src/cdc/cdc_debug.c +++ b/src/cdc/cdc_debug.c @@ -43,7 +43,7 @@ #include "picoprobe_config.h" -#define STREAM_PRINTF_SIZE 4096 +#define STREAM_PRINTF_SIZE 32768 #define STREAM_PRINTF_TRIGGER 32 static TaskHandle_t task_printf = NULL; @@ -79,7 +79,7 @@ void cdc_debug_thread(void *ptr) if (xStreamBufferIsEmpty(stream_printf)) { // -> end of transmission: flush and sleep for a long time (or until new data is available) tud_cdc_n_write_flush(CDC_DEBUG_N); - xEventGroupWaitBits(events, EV_TX_COMPLETE | EV_STREAM, pdTRUE, pdFALSE, pdMS_TO_TICKS(10000)); + xEventGroupWaitBits(events, EV_TX_COMPLETE | EV_STREAM, pdTRUE, pdFALSE, pdMS_TO_TICKS(1000)); } else { size_t cnt; diff --git a/src/net/net_glue.c b/src/net/net_glue.c index d6a9458ca..f61c1acf9 100755 --- a/src/net/net_glue.c +++ b/src/net/net_glue.c @@ -152,7 +152,7 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) * \return false if the packet buffer was not accepted */ { - //printf("tud_network_recv_cb(%p,%u)\n", src, size); + printf("tud_network_recv_cb(%p,%u)\n", src, size); #if 0 /* this shouldn't happen, but if we get another packet before diff --git a/src/net/net_sysview.c b/src/net/net_sysview.c index 3e6bc7a6f..b369ca178 100755 --- a/src/net/net_sysview.c +++ b/src/net/net_sysview.c @@ -137,11 +137,15 @@ static void sysview_try_send(void *ctx) sysview_close(m_pcb_client); } +#if 1 if ( !block_call_to_tcp_output && tcp_sndbuf(m_pcb_client) < 3 * TCP_SND_BUF / 4) { printf("sysview_try_send: flush %d %d\n", tcp_sndbuf(m_pcb_client), 3 * TCP_SND_BUF / 4); block_call_to_tcp_output = true; tcp_output(m_pcb_client); } +#else + tcp_output(m_pcb_client); +#endif if ( !xStreamBufferIsEmpty(stream_sysview_to_host)) { tcpip_callback_with_block(sysview_try_send, NULL, 0); From bdb7e6338906bbb39be2f80fc2934b6e23541643 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:05:34 +0200 Subject: [PATCH 12/64] mini --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 74fb79911..cc3751708 100644 --- a/README.adoc +++ b/README.adoc @@ -99,7 +99,7 @@ containing the steps from installation until debugging in VSCode. |yes |`openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 25000" -c "program {firmware.elf} verify reset; shutdown;"` -|pyOCD 0.34.x +|pyOCD 0.34 & 0.35 |yes |yes |`pyocd flash -f 400000 -t nrf52840 firmware.elf` From 183681cb356b3d1a9edd93e2ecef70d96ec19b0f Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:05:56 +0200 Subject: [PATCH 13/64] trying to understand buffering --- src/net/tinyusb/ncm_device.c | 66 ++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 7acd6d4a3..5d88d699d 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -105,8 +105,9 @@ typedef struct { uint8_t ep_in; uint8_t ep_out; - const ndp16_t *ndp; - uint8_t rcv_datagram_num, rcv_datagram_index; + const ndp16_t *rcv_ndp; + uint8_t rcv_datagram_num; + uint8_t rcv_datagram_index; uint16_t rcv_datagram_size; enum { @@ -236,6 +237,8 @@ tu_static struct ecm_notify_struct ncm_notify_speed_change = { +static uint8_t buffi[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; + void tud_network_recv_renew(void) /** * context: lwIP & TinyUSB @@ -287,33 +290,65 @@ void tud_network_recv_renew(void) printf("--0.0\n"); return; } -#else - static uint8_t buffi[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; - +#elif 1 + //memset(buffi, 0, sizeof(buffi)); // this will not work! r = usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); if ( !r) { printf("--0.0\n"); return; } memcpy(receive_ntb, buffi, sizeof(receive_ntb)); +#else +#if 1 + { + static bool inited; + + if ( !inited) { + inited = true; + r = usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); + if ( !r) { + printf("--0.0\n"); + return; + } + } + } +#endif + if (ncm_interface.rcv_datagram_size == 0) { + printf("--0.0\n"); + return; + } + memcpy(receive_ntb, buffi, ncm_interface.rcv_datagram_size); + ncm_interface.rcv_datagram_size = 0; #endif printf("--1\n"); const nth16_t *hdr = (const nth16_t*) receive_ntb; + const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); + +#if 0 TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE,); //TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= ncm_interface.rcv_datagram_size,); - const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1,); //TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= ncm_interface.rcv_datagram_size,); +#else + if (hdr->dwSignature != NTH16_SIGNATURE) { + printf("--1.1 0x%x\n", hdr->dwSignature); + return; + } + if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { + printf("--1.2 0x%x\n", ndp->dwSignature); + return; + } +#endif printf("--2\n"); int max_rcv_datagrams = (ndp->wLength - 12) / 4; ncm_interface.rcv_datagram_index = 0; ncm_interface.rcv_datagram_num = 0; - ncm_interface.ndp = ndp; + ncm_interface.rcv_ndp = ndp; #if 0 for (int i = 0; i < max_rcv_datagrams && ndp->datagram[i].wDatagramIndex != 0 && ndp->datagram[i].wDatagramLength != 0; i++) { @@ -343,7 +378,7 @@ void tud_network_recv_renew(void) return; } - const ndp16_t *ndp = ncm_interface.ndp; + const ndp16_t *ndp = ncm_interface.rcv_ndp; const int i = ncm_interface.rcv_datagram_index; ncm_interface.rcv_datagram_index++; @@ -361,9 +396,16 @@ static void handle_incoming_datagram(uint32_t len) { uint32_t size = len; - printf("handle_incoming_datagram(%lu)\n", len); + printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_datagram_size); +#if 0 + if (len != 0) { + usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, len); + ncm_interface.rcv_datagram_size = len; + } +#else ncm_interface.rcv_datagram_size = len; +#endif if (len == 0) { //return; @@ -489,6 +531,8 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); + //usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); return drv_len; @@ -619,11 +663,11 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ (void) rhport; (void) result; - //printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); + printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); /* new datagram receive_ntb */ if (ep_addr == ncm_interface.ep_out) { - //printf(" EP_OUT\n"); + printf(" EP_OUT\n"); handle_incoming_datagram(xferred_bytes); } From cbd6e46d92193a7f1e8b939578cc1532e7d17427 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:13:13 +0200 Subject: [PATCH 14/64] remove old code --- src/net/tinyusb/ncm_device.c | 47 +++++++----------------------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 5d88d699d..01e041134 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -323,22 +323,24 @@ void tud_network_recv_renew(void) printf("--1\n"); - const nth16_t *hdr = (const nth16_t*) receive_ntb; - const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); - #if 0 + const nth16_t *hdr = (const nth16_t*) receive_ntb; TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE,); //TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= ncm_interface.rcv_datagram_size,); + const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1,); //TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= ncm_interface.rcv_datagram_size,); #else + const nth16_t *hdr = (const nth16_t*) receive_ntb; if (hdr->dwSignature != NTH16_SIGNATURE) { - printf("--1.1 0x%x\n", hdr->dwSignature); + printf("--1.1 0x%lx\n", hdr->dwSignature); return; } + + const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { - printf("--1.2 0x%x\n", ndp->dwSignature); + printf("--1.2 0x%lx\n", ndp->dwSignature); return; } #endif @@ -394,48 +396,17 @@ void tud_network_recv_renew(void) static void handle_incoming_datagram(uint32_t len) { - uint32_t size = len; - - printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_datagram_size); + //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_datagram_size); #if 0 if (len != 0) { - usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, len); + usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); ncm_interface.rcv_datagram_size = len; } #else ncm_interface.rcv_datagram_size = len; #endif - if (len == 0) { - //return; - } - -#if 0 - TU_ASSERT(size >= sizeof(nth16_t),); - - const nth16_t *hdr = (const nth16_t*) receive_ntb; - TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE,); - TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len,); - - const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); - TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1,); - TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len,); - - int max_rcv_datagrams = (ndp->wLength - 12) / 4; - ncm_interface.rcv_datagram_index = 0; - ncm_interface.rcv_datagram_num = 0; - ncm_interface.ndp = ndp; - for (int i = 0; i < max_rcv_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) { - ncm_interface.rcv_datagram_num++; - } - -#if 1 - printf("handle_incoming_datagram: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, - ndp->wNextNdpIndex); -#endif -#endif - tud_network_recv_renew(); } From 712cea1cc3cccab521ca0c70a8ed3e1e7ba9f584 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:22:29 +0200 Subject: [PATCH 15/64] renamed --- src/net/tinyusb/ncm_device.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 01e041134..9e283ab46 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -237,7 +237,7 @@ tu_static struct ecm_notify_struct ncm_notify_speed_change = { -static uint8_t buffi[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; +static uint8_t usb_buffi[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; void tud_network_recv_renew(void) /** @@ -291,13 +291,13 @@ void tud_network_recv_renew(void) return; } #elif 1 - //memset(buffi, 0, sizeof(buffi)); // this will not work! - r = usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); + //memset(usb_buffi, 0, sizeof(usb_buffi)); // this will not work! + r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); if ( !r) { printf("--0.0\n"); return; } - memcpy(receive_ntb, buffi, sizeof(receive_ntb)); + memcpy(receive_ntb, usb_buffi, sizeof(receive_ntb)); #else #if 1 { @@ -305,7 +305,7 @@ void tud_network_recv_renew(void) if ( !inited) { inited = true; - r = usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); + r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); if ( !r) { printf("--0.0\n"); return; @@ -317,7 +317,7 @@ void tud_network_recv_renew(void) printf("--0.0\n"); return; } - memcpy(receive_ntb, buffi, ncm_interface.rcv_datagram_size); + memcpy(receive_ntb, usb_buffi, ncm_interface.rcv_datagram_size); ncm_interface.rcv_datagram_size = 0; #endif @@ -400,7 +400,7 @@ static void handle_incoming_datagram(uint32_t len) #if 0 if (len != 0) { - usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); + usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); ncm_interface.rcv_datagram_size = len; } #else @@ -502,7 +502,7 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); - //usbd_edpt_xfer(0, ncm_interface.ep_out, buffi, sizeof(buffi)); + //usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); drv_len += 2 * sizeof(tusb_desc_endpoint_t); From fef0a1dcf8d4107ae785fe3a05aa963907b8c7b5 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:27:36 +0200 Subject: [PATCH 16/64] this works with "iperf -c 192.168.14.1 -e -i 1 -l 1400 -M 1400" --- src/net/tinyusb/ncm_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 9e283ab46..17e56a923 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -314,7 +314,7 @@ void tud_network_recv_renew(void) } #endif if (ncm_interface.rcv_datagram_size == 0) { - printf("--0.0\n"); + printf("--0.00\n"); return; } memcpy(receive_ntb, usb_buffi, ncm_interface.rcv_datagram_size); @@ -396,7 +396,7 @@ void tud_network_recv_renew(void) static void handle_incoming_datagram(uint32_t len) { - //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_datagram_size); + printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_datagram_size); #if 0 if (len != 0) { From 7bf8b16e256c21a1970eb34e286a22fac1924724 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:32:04 +0200 Subject: [PATCH 17/64] minor --- src/net/tinyusb/ncm_device.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 17e56a923..67c0ac2e1 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -323,15 +323,6 @@ void tud_network_recv_renew(void) printf("--1\n"); -#if 0 - const nth16_t *hdr = (const nth16_t*) receive_ntb; - TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE,); - //TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= ncm_interface.rcv_datagram_size,); - - const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); - TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1,); - //TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= ncm_interface.rcv_datagram_size,); -#else const nth16_t *hdr = (const nth16_t*) receive_ntb; if (hdr->dwSignature != NTH16_SIGNATURE) { printf("--1.1 0x%lx\n", hdr->dwSignature); @@ -343,7 +334,6 @@ void tud_network_recv_renew(void) printf("--1.2 0x%lx\n", ndp->dwSignature); return; } -#endif printf("--2\n"); From 22f4717478d4d7854667f0286c3ca0c47c037990 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:49:50 +0200 Subject: [PATCH 18/64] still works --- src/net/tinyusb/ncm_device.c | 51 ++++++++---------------------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 67c0ac2e1..c3182333b 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -290,35 +290,14 @@ void tud_network_recv_renew(void) printf("--0.0\n"); return; } -#elif 1 - //memset(usb_buffi, 0, sizeof(usb_buffi)); // this will not work! +#else + memcpy(receive_ntb, usb_buffi, ncm_interface.rcv_datagram_size); + ncm_interface.rcv_datagram_size = 0; r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); if ( !r) { printf("--0.0\n"); return; } - memcpy(receive_ntb, usb_buffi, sizeof(receive_ntb)); -#else -#if 1 - { - static bool inited; - - if ( !inited) { - inited = true; - r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); - if ( !r) { - printf("--0.0\n"); - return; - } - } - } -#endif - if (ncm_interface.rcv_datagram_size == 0) { - printf("--0.00\n"); - return; - } - memcpy(receive_ntb, usb_buffi, ncm_interface.rcv_datagram_size); - ncm_interface.rcv_datagram_size = 0; #endif printf("--1\n"); @@ -337,27 +316,21 @@ void tud_network_recv_renew(void) printf("--2\n"); - int max_rcv_datagrams = (ndp->wLength - 12) / 4; + int max_rcv_datagrams = (ndp->wLength - 8) / 4; ncm_interface.rcv_datagram_index = 0; ncm_interface.rcv_datagram_num = 0; ncm_interface.rcv_ndp = ndp; -#if 0 - for (int i = 0; i < max_rcv_datagrams && ndp->datagram[i].wDatagramIndex != 0 && ndp->datagram[i].wDatagramLength != 0; i++) + while (ncm_interface.rcv_datagram_num < max_rcv_datagrams) { - ncm_interface.rcv_datagram_num++; - } -#else - int i = 0; - while (i <= max_rcv_datagrams) - { - printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); - if (ndp->datagram[i].wDatagramIndex == 0 && ndp->datagram[i].wDatagramLength == 0) { + printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, + ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex, + ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength); + if ( ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex == 0 + && ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength == 0) { break; } - ++i; - ncm_interface.rcv_datagram_num++; + ++ncm_interface.rcv_datagram_num; } -#endif #if 1 printf("tud_network_recv_renew: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, @@ -492,8 +465,6 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); - //usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); - drv_len += 2 * sizeof(tusb_desc_endpoint_t); return drv_len; From b90c2492d39ac4ff7814f6f3c7cfa4b07f4255b7 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 13:59:15 +0200 Subject: [PATCH 19/64] more checking --- src/net/tinyusb/ncm_device.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index c3182333b..8fc622dba 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -292,7 +292,6 @@ void tud_network_recv_renew(void) } #else memcpy(receive_ntb, usb_buffi, ncm_interface.rcv_datagram_size); - ncm_interface.rcv_datagram_size = 0; r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); if ( !r) { printf("--0.0\n"); @@ -303,14 +302,26 @@ void tud_network_recv_renew(void) printf("--1\n"); const nth16_t *hdr = (const nth16_t*) receive_ntb; + if (hdr->wNdpIndex < sizeof(nth16_t)) { + printf("--1.1.1 %d\n", hdr->wNdpIndex); + return; + } + if (hdr->wNdpIndex + sizeof(ndp16_t) > ncm_interface.rcv_datagram_size) { + printf("--1.1.2 %d %d\n", hdr->wNdpIndex + sizeof(ndp16_t), ncm_interface.rcv_datagram_size); + return; + } if (hdr->dwSignature != NTH16_SIGNATURE) { - printf("--1.1 0x%lx\n", hdr->dwSignature); + printf("--1.1.3 0x%lx\n", hdr->dwSignature); return; } const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); + if (hdr->wNdpIndex + ndp->wLength > ncm_interface.rcv_datagram_size) { + printf("--1.2.1 %d %d\n", hdr->wNdpIndex + ndp->wLength, ncm_interface.rcv_datagram_size); + return; + } if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { - printf("--1.2 0x%lx\n", ndp->dwSignature); + printf("--1.2.2 0x%lx\n", ndp->dwSignature); return; } @@ -337,6 +348,7 @@ void tud_network_recv_renew(void) ndp->wNextNdpIndex); #endif + ncm_interface.rcv_datagram_size = 0; } if (ncm_interface.rcv_datagram_num == 0) { From e838a00fbae5f2e9fb5b893bec2ee4cbaab215b9 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 14:38:02 +0200 Subject: [PATCH 20/64] rename --- src/net/tinyusb/ncm_device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 8fc622dba..a43eceabd 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -237,7 +237,7 @@ tu_static struct ecm_notify_struct ncm_notify_speed_change = { -static uint8_t usb_buffi[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; +static uint8_t usb_rcv_buff[CFG_TUD_NCM_OUT_NTB_MAX_SIZE + 400]; void tud_network_recv_renew(void) /** @@ -291,8 +291,8 @@ void tud_network_recv_renew(void) return; } #else - memcpy(receive_ntb, usb_buffi, ncm_interface.rcv_datagram_size); - r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); + memcpy(receive_ntb, usb_rcv_buff, ncm_interface.rcv_datagram_size); + r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_rcv_buff, sizeof(usb_rcv_buff)); if ( !r) { printf("--0.0\n"); return; @@ -375,7 +375,7 @@ static void handle_incoming_datagram(uint32_t len) #if 0 if (len != 0) { - usbd_edpt_xfer(0, ncm_interface.ep_out, usb_buffi, sizeof(usb_buffi)); + usbd_edpt_xfer(0, ncm_interface.ep_out, usb_rcv_buff, sizeof(usb_rcv_buff)); ncm_interface.rcv_datagram_size = len; } #else From a5dbb737ef2e46f8572dbe21e3601108e89fbc68 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 15:46:43 +0200 Subject: [PATCH 21/64] best version til now, BUT CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB=1 !!! --- src/net/tinyusb/ncm_device.c | 55 +++++++++++++++++++++++------------- src/net/tinyusb/net_device.h | 2 +- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index a43eceabd..d0a5f81ed 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -245,8 +245,7 @@ void tud_network_recv_renew(void) */ { printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); - if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { // && ncm_interface.rcv_datagram_size != 0) { - bool r; + if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { printf("--0\n"); #if 0 @@ -285,33 +284,48 @@ void tud_network_recv_renew(void) // [10:37:42.350546 0.000717] 38.046 ( 2) - handle_incoming_datagram(2136) // [10:37:42.351156 0.000611] 38.046 ( 0) - tud_network_recv_renew() - 11 [20020120] // [10:37:42.351867 0.000711] 38.046 ( 0) - tud_network_recv_renew->: 9 200103D8 0 0 FAIL & DEAD + bool r; r = usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); if ( !r) { printf("--0.0\n"); return; } #else - memcpy(receive_ntb, usb_rcv_buff, ncm_interface.rcv_datagram_size); - r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_rcv_buff, sizeof(usb_rcv_buff)); - if ( !r) { - printf("--0.0\n"); - return; + if (ncm_interface.rcv_datagram_size != 0) { + memcpy(receive_ntb, usb_rcv_buff, ncm_interface.rcv_datagram_size); + } + else { + if (usbd_edpt_busy(0, ncm_interface.ep_out)) { + printf("--0.0\n"); + return; + } + else { + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_rcv_buff, sizeof(usb_rcv_buff)); + if ( !r) { + printf("--0.1\n"); + return; + } + } } #endif printf("--1\n"); - const nth16_t *hdr = (const nth16_t*) receive_ntb; - if (hdr->wNdpIndex < sizeof(nth16_t)) { - printf("--1.1.1 %d\n", hdr->wNdpIndex); + const nth16_t *hdr = (const nth16_t*)receive_ntb; + if (ncm_interface.rcv_datagram_size <= sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + printf("--1.1.1 %d\n", ncm_interface.rcv_datagram_size); return; } - if (hdr->wNdpIndex + sizeof(ndp16_t) > ncm_interface.rcv_datagram_size) { - printf("--1.1.2 %d %d\n", hdr->wNdpIndex + sizeof(ndp16_t), ncm_interface.rcv_datagram_size); + if (hdr->dwSignature != NTH16_SIGNATURE) { + printf("--1.1.2 0x%lx\n", hdr->dwSignature); return; } - if (hdr->dwSignature != NTH16_SIGNATURE) { - printf("--1.1.3 0x%lx\n", hdr->dwSignature); + if (hdr->wNdpIndex < sizeof(nth16_t)) { + printf("--1.1.3 %d\n", hdr->wNdpIndex); + return; + } + if (hdr->wNdpIndex + sizeof(ndp16_t) > ncm_interface.rcv_datagram_size) { + printf("--1.1.4 %d %d\n", hdr->wNdpIndex + sizeof(ndp16_t), ncm_interface.rcv_datagram_size); return; } @@ -333,9 +347,11 @@ void tud_network_recv_renew(void) ncm_interface.rcv_ndp = ndp; while (ncm_interface.rcv_datagram_num < max_rcv_datagrams) { +#if 1 printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength); +#endif if ( ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex == 0 && ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength == 0) { break; @@ -356,14 +372,15 @@ void tud_network_recv_renew(void) } const ndp16_t *ndp = ncm_interface.rcv_ndp; - const int i = ncm_interface.rcv_datagram_index; - ncm_interface.rcv_datagram_index++; - printf("tud_network_recv_renew->: %d %p %d %d\n", i, ndp, ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); + printf("tud_network_recv_renew->: %d %p %d %d\n", ncm_interface.rcv_datagram_index, + ndp, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength); - if ( !tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength)) { + if (tud_network_recv_cb(receive_ntb + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength)) { printf("!!!!!!!!!!!!!!!!!!!!\n"); - ncm_interface.rcv_datagram_index--; + ++ncm_interface.rcv_datagram_index; } } diff --git a/src/net/tinyusb/net_device.h b/src/net/tinyusb/net_device.h index f6ab42b48..88840abb5 100755 --- a/src/net/tinyusb/net_device.h +++ b/src/net/tinyusb/net_device.h @@ -54,7 +54,7 @@ #endif #ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB -#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 +#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 1 #endif #ifndef CFG_TUD_NCM_ALIGNMENT From 51cc65aa17928a65d02d5fa819ccf0b1889670e3 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 16:32:35 +0200 Subject: [PATCH 22/64] works better without debugoutput, but still not as perfect as ECM --- doc/lwIP-notes.adoc | 2 ++ src/net/tinyusb/ncm_device.c | 32 +++++++++++++++++--------------- src/net/tinyusb/net_device.h | 2 +- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/doc/lwIP-notes.adoc b/doc/lwIP-notes.adoc index 5918a7e38..6f378c416 100755 --- a/doc/lwIP-notes.adoc +++ b/doc/lwIP-notes.adoc @@ -117,6 +117,8 @@ Monitor performance/errors with Wireshark. * is there multicore a problem!? I have seen retries with multicore even with `wNtbOutMaxDatagrams = 1` * I think it is assumed, that TinyUSB and lwIP are running in the same task (but in my scenario they don't) +* if removing debug messages, then the receive path seems to work better, which + indicates a race condition somewhere ### Remarks about Functionality diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index d0a5f81ed..2eb967a49 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -143,7 +143,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 1 // 0=no limit + .wNtbOutMaxDatagrams = 1 // 0=no limit TODO set to 0 }; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; @@ -244,10 +244,10 @@ void tud_network_recv_renew(void) * context: lwIP & TinyUSB */ { - printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); + //printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { - printf("--0\n"); + //printf("--0\n"); #if 0 // funny effect with "iperf -c 192.168.14.1 -e -i 1 -l 22 -M 200" // receive_ntb is overwritten! @@ -309,15 +309,15 @@ void tud_network_recv_renew(void) } #endif - printf("--1\n"); + //printf("--1\n"); const nth16_t *hdr = (const nth16_t*)receive_ntb; - if (ncm_interface.rcv_datagram_size <= sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - printf("--1.1.1 %d\n", ncm_interface.rcv_datagram_size); + if (ncm_interface.rcv_datagram_size < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + //printf("--1.1.1 %d\n", ncm_interface.rcv_datagram_size); return; } if (hdr->dwSignature != NTH16_SIGNATURE) { - printf("--1.1.2 0x%lx\n", hdr->dwSignature); + printf("--1.1.2 0x%lx %d\n", hdr->dwSignature, ncm_interface.rcv_datagram_size); return; } if (hdr->wNdpIndex < sizeof(nth16_t)) { @@ -335,11 +335,11 @@ void tud_network_recv_renew(void) return; } if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { - printf("--1.2.2 0x%lx\n", ndp->dwSignature); + printf("--1.2.2 0x%lx %d\n", ndp->dwSignature, ncm_interface.rcv_datagram_size); return; } - printf("--2\n"); + //printf("--2\n"); int max_rcv_datagrams = (ndp->wLength - 8) / 4; ncm_interface.rcv_datagram_index = 0; @@ -347,7 +347,7 @@ void tud_network_recv_renew(void) ncm_interface.rcv_ndp = ndp; while (ncm_interface.rcv_datagram_num < max_rcv_datagrams) { -#if 1 +#if 0 printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength); @@ -359,7 +359,7 @@ void tud_network_recv_renew(void) ++ncm_interface.rcv_datagram_num; } -#if 1 +#if 0 printf("tud_network_recv_renew: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, ndp->wNextNdpIndex); #endif @@ -373,13 +373,15 @@ void tud_network_recv_renew(void) const ndp16_t *ndp = ncm_interface.rcv_ndp; +#if 0 printf("tud_network_recv_renew->: %d %p %d %d\n", ncm_interface.rcv_datagram_index, ndp, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength); +#endif if (tud_network_recv_cb(receive_ntb + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength)) { - printf("!!!!!!!!!!!!!!!!!!!!\n"); + //printf("!!!!!!!!!!!!!!!!!!!!\n"); ++ncm_interface.rcv_datagram_index; } } @@ -388,7 +390,7 @@ void tud_network_recv_renew(void) static void handle_incoming_datagram(uint32_t len) { - printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_datagram_size); + //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_datagram_size); #if 0 if (len != 0) { @@ -624,11 +626,11 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ (void) rhport; (void) result; - printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); + //printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); /* new datagram receive_ntb */ if (ep_addr == ncm_interface.ep_out) { - printf(" EP_OUT\n"); + //printf(" EP_OUT\n"); handle_incoming_datagram(xferred_bytes); } diff --git a/src/net/tinyusb/net_device.h b/src/net/tinyusb/net_device.h index 88840abb5..935161904 100755 --- a/src/net/tinyusb/net_device.h +++ b/src/net/tinyusb/net_device.h @@ -54,7 +54,7 @@ #endif #ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB -#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 1 +#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 1 // TODO should be 8 or so #endif #ifndef CFG_TUD_NCM_ALIGNMENT From 91507afa17bac74a61153b0087542c9037b0f81d Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 16:52:17 +0200 Subject: [PATCH 23/64] removed some temp variables --- src/net/tinyusb/ncm_device.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 2eb967a49..6261910a8 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -670,8 +670,6 @@ bool tud_network_can_xmit(uint16_t size) { TU_VERIFY(ncm_interface.itf_data_alt == 1); - size_t next_datagram_offset = ncm_interface.next_datagram_offset; - #if 0 printf("tud_network_can_xmit(%d) %d %d - %d %d [%p]\n", size, ncm_interface.datagram_count, ncm_interface.max_datagrams_per_ntb, next_datagram_offset, ncm_interface.ntb_in_size, xTaskGetCurrentTaskHandle()); @@ -683,7 +681,7 @@ bool tud_network_can_xmit(uint16_t size) return false ; } - if (next_datagram_offset + size > ncm_interface.ntb_in_size) { + if (ncm_interface.next_datagram_offset + size > ncm_interface.ntb_in_size) { // this happens printf("ntb full [by size]\r\n"); return false ; @@ -700,23 +698,20 @@ void tud_network_xmit(void *ref, uint16_t arg) */ { transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t next_datagram_offset = ncm_interface.next_datagram_offset; //printf("tud_network_xmit(%p,%d) [%p]\n", ref, arg, xTaskGetCurrentTaskHandle()); - uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); + uint16_t size = tud_network_xmit_cb(ntb->data + ncm_interface.next_datagram_offset, ref, arg); ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; ncm_interface.datagram_count++; - next_datagram_offset += size; + ncm_interface.next_datagram_offset += size; // round up so the next datagram is aligned correctly - next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); - next_datagram_offset -= (next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); - - ncm_interface.next_datagram_offset = next_datagram_offset; + ncm_interface.next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); + ncm_interface.next_datagram_offset -= (ncm_interface.next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); ncm_start_tx(); } From 6e02af68de277f96c8b053e49598fa2474b5e887 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 17:17:54 +0200 Subject: [PATCH 24/64] minor renaming etc --- src/net/tinyusb/ncm_device.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 6261910a8..119a9aa80 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -123,7 +123,7 @@ typedef struct { uint16_t nth_sequence; // Sequence number counter for transmitted NTBs - bool transferring; + bool xmt_running; } ncm_interface_t; @@ -168,15 +168,17 @@ static void ncm_prepare_for_tx(void) memset(transmit_ntb + ncm_interface.current_ntb, 0, sizeof(transmit_ntb_t)); } + + /* * If not already transmitting, start sending the current NTB to the host and swap buffers * to start filling the other one with datagrams. */ static void ncm_start_tx(void) { - //printf("ncm_start_tx() - %d %d\n", ncm_interface.transferring, ncm_interface.datagram_count); + //printf("ncm_start_tx() - %d %d\n", ncm_interface.xmt_running, ncm_interface.datagram_count); - if (ncm_interface.transferring) { + if (ncm_interface.xmt_running) { return; } @@ -199,7 +201,7 @@ static void ncm_start_tx(void) // Kick off an endpoint transfer usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); - ncm_interface.transferring = true; + ncm_interface.xmt_running = true; // Swap to the other NTB and clear it out ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; @@ -237,6 +239,7 @@ tu_static struct ecm_notify_struct ncm_notify_speed_change = { +/** this buffer receives the data from USB */ static uint8_t usb_rcv_buff[CFG_TUD_NCM_OUT_NTB_MAX_SIZE + 400]; void tud_network_recv_renew(void) @@ -293,16 +296,18 @@ void tud_network_recv_renew(void) #else if (ncm_interface.rcv_datagram_size != 0) { memcpy(receive_ntb, usb_rcv_buff, ncm_interface.rcv_datagram_size); + // now usb_rcv_buff can actually be reused, but this does not work. We have to wait } - else { + else + { if (usbd_edpt_busy(0, ncm_interface.ep_out)) { - printf("--0.0\n"); + printf("--0.1\n"); return; } else { bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_rcv_buff, sizeof(usb_rcv_buff)); if ( !r) { - printf("--0.1\n"); + printf("--0.2\n"); return; } } @@ -636,12 +641,9 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ /* data transmission finished */ if (ep_addr == ncm_interface.ep_in) { - //printf(" EP_IN %d %d %d\n", ncm_interface.transferring, ncm_interface.datagram_count, + //printf(" EP_IN %d %d %d\n", ncm_interface.xmt_running, ncm_interface.datagram_count, //ncm_interface.itf_data_alt); - if (ncm_interface.transferring) { - ncm_interface.transferring = false; - //tud_network_recv_renew(); - } + ncm_interface.xmt_running = false; // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { From 8fc70315aa80ed6ea8a04f7909ad50917d585c6c Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 17:28:10 +0200 Subject: [PATCH 25/64] renaming rcv buffers --- src/net/tinyusb/ncm_device.c | 56 +++++++++++++++++------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 119a9aa80..1c8b5878c 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -108,7 +108,10 @@ typedef struct { const ndp16_t *rcv_ndp; uint8_t rcv_datagram_num; uint8_t rcv_datagram_index; - uint16_t rcv_datagram_size; + CFG_TUSB_MEM_ALIGN uint8_t rcv_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; + + uint16_t rcv_usb_datagram_size; + CFG_TUSB_MEM_ALIGN uint8_t rcv_usb_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE + 400]; // this buffer receives the data from USB enum { REPORT_SPEED, REPORT_CONNECTED, REPORT_DONE @@ -148,8 +151,6 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; - tu_static ncm_interface_t ncm_interface; static void ncm_prepare_for_tx(void) @@ -239,9 +240,6 @@ tu_static struct ecm_notify_struct ncm_notify_speed_change = { -/** this buffer receives the data from USB */ -static uint8_t usb_rcv_buff[CFG_TUD_NCM_OUT_NTB_MAX_SIZE + 400]; - void tud_network_recv_renew(void) /** * context: lwIP & TinyUSB @@ -253,7 +251,7 @@ void tud_network_recv_renew(void) //printf("--0\n"); #if 0 // funny effect with "iperf -c 192.168.14.1 -e -i 1 -l 22 -M 200" - // receive_ntb is overwritten! + // rcv_datagram is overwritten! // [10:37:42.330968 0.000287] 38.039 ( 0) - 0 90 54 // [10:37:42.331361 0.000394] 38.039 ( 0) - 1 146 114 // [10:37:42.331770 0.000409] 38.039 ( 0) - 2 262 254 @@ -288,15 +286,15 @@ void tud_network_recv_renew(void) // [10:37:42.351156 0.000611] 38.046 ( 0) - tud_network_recv_renew() - 11 [20020120] // [10:37:42.351867 0.000711] 38.046 ( 0) - tud_network_recv_renew->: 9 200103D8 0 0 FAIL & DEAD bool r; - r = usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); + r = usbd_edpt_xfer(0, ncm_interface.ep_out, rcv_datagram, sizeof(rcv_datagram)); if ( !r) { printf("--0.0\n"); return; } #else - if (ncm_interface.rcv_datagram_size != 0) { - memcpy(receive_ntb, usb_rcv_buff, ncm_interface.rcv_datagram_size); - // now usb_rcv_buff can actually be reused, but this does not work. We have to wait + if (ncm_interface.rcv_usb_datagram_size != 0) { + memcpy(ncm_interface.rcv_datagram, ncm_interface.rcv_usb_datagram, ncm_interface.rcv_usb_datagram_size); + // now ncm_interface.rcv_usb_datagram can actually be reused, but this does not work. We have to wait } else { @@ -305,7 +303,7 @@ void tud_network_recv_renew(void) return; } else { - bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, usb_rcv_buff, sizeof(usb_rcv_buff)); + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_usb_datagram, sizeof(ncm_interface.rcv_usb_datagram)); if ( !r) { printf("--0.2\n"); return; @@ -316,31 +314,31 @@ void tud_network_recv_renew(void) //printf("--1\n"); - const nth16_t *hdr = (const nth16_t*)receive_ntb; - if (ncm_interface.rcv_datagram_size < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - //printf("--1.1.1 %d\n", ncm_interface.rcv_datagram_size); + const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_datagram; + if (ncm_interface.rcv_usb_datagram_size < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + //printf("--1.1.1 %d\n", ncm_interface.rcv_usb_datagram_size); return; } if (hdr->dwSignature != NTH16_SIGNATURE) { - printf("--1.1.2 0x%lx %d\n", hdr->dwSignature, ncm_interface.rcv_datagram_size); + printf("--1.1.2 0x%lx %d\n", hdr->dwSignature, ncm_interface.rcv_usb_datagram_size); return; } if (hdr->wNdpIndex < sizeof(nth16_t)) { printf("--1.1.3 %d\n", hdr->wNdpIndex); return; } - if (hdr->wNdpIndex + sizeof(ndp16_t) > ncm_interface.rcv_datagram_size) { - printf("--1.1.4 %d %d\n", hdr->wNdpIndex + sizeof(ndp16_t), ncm_interface.rcv_datagram_size); + if (hdr->wNdpIndex + sizeof(ndp16_t) > ncm_interface.rcv_usb_datagram_size) { + printf("--1.1.4 %d %d\n", hdr->wNdpIndex + sizeof(ndp16_t), ncm_interface.rcv_usb_datagram_size); return; } - const ndp16_t *ndp = (const ndp16_t*) (receive_ntb + hdr->wNdpIndex); - if (hdr->wNdpIndex + ndp->wLength > ncm_interface.rcv_datagram_size) { - printf("--1.2.1 %d %d\n", hdr->wNdpIndex + ndp->wLength, ncm_interface.rcv_datagram_size); + const ndp16_t *ndp = (const ndp16_t*) (ncm_interface.rcv_datagram + hdr->wNdpIndex); + if (hdr->wNdpIndex + ndp->wLength > ncm_interface.rcv_usb_datagram_size) { + printf("--1.2.1 %d %d\n", hdr->wNdpIndex + ndp->wLength, ncm_interface.rcv_usb_datagram_size); return; } if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { - printf("--1.2.2 0x%lx %d\n", ndp->dwSignature, ncm_interface.rcv_datagram_size); + printf("--1.2.2 0x%lx %d\n", ndp->dwSignature, ncm_interface.rcv_usb_datagram_size); return; } @@ -369,7 +367,7 @@ void tud_network_recv_renew(void) ndp->wNextNdpIndex); #endif - ncm_interface.rcv_datagram_size = 0; + ncm_interface.rcv_usb_datagram_size = 0; } if (ncm_interface.rcv_datagram_num == 0) { @@ -384,7 +382,7 @@ void tud_network_recv_renew(void) ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength); #endif - if (tud_network_recv_cb(receive_ntb + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, + if (tud_network_recv_cb(ncm_interface.rcv_datagram + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength)) { //printf("!!!!!!!!!!!!!!!!!!!!\n"); ++ncm_interface.rcv_datagram_index; @@ -395,15 +393,15 @@ void tud_network_recv_renew(void) static void handle_incoming_datagram(uint32_t len) { - //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_datagram_size); + //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_usb_datagram_size); #if 0 if (len != 0) { - usbd_edpt_xfer(0, ncm_interface.ep_out, usb_rcv_buff, sizeof(usb_rcv_buff)); - ncm_interface.rcv_datagram_size = len; + usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_usb_datagram, sizeof(ncm_interface.rcv_usb_datagram)); + ncm_interface.rcv_usb_datagram_size = len; } #else - ncm_interface.rcv_datagram_size = len; + ncm_interface.rcv_usb_datagram_size = len; #endif tud_network_recv_renew(); @@ -633,7 +631,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ //printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); - /* new datagram receive_ntb */ + /* new datagram rcv_datagram */ if (ep_addr == ncm_interface.ep_out) { //printf(" EP_OUT\n"); handle_incoming_datagram(xferred_bytes); From 76c4f2055ada348921ce8bde04bef5e1a5b430a8 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 17:40:10 +0200 Subject: [PATCH 26/64] removed rcv_usb_datagram --- src/net/tinyusb/ncm_device.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 1c8b5878c..4f11da615 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -109,9 +109,7 @@ typedef struct { uint8_t rcv_datagram_num; uint8_t rcv_datagram_index; CFG_TUSB_MEM_ALIGN uint8_t rcv_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; - uint16_t rcv_usb_datagram_size; - CFG_TUSB_MEM_ALIGN uint8_t rcv_usb_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE + 400]; // this buffer receives the data from USB enum { REPORT_SPEED, REPORT_CONNECTED, REPORT_DONE @@ -292,18 +290,13 @@ void tud_network_recv_renew(void) return; } #else - if (ncm_interface.rcv_usb_datagram_size != 0) { - memcpy(ncm_interface.rcv_datagram, ncm_interface.rcv_usb_datagram, ncm_interface.rcv_usb_datagram_size); - // now ncm_interface.rcv_usb_datagram can actually be reused, but this does not work. We have to wait - } - else - { + if (ncm_interface.rcv_usb_datagram_size == 0) { if (usbd_edpt_busy(0, ncm_interface.ep_out)) { printf("--0.1\n"); return; } else { - bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_usb_datagram, sizeof(ncm_interface.rcv_usb_datagram)); + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_datagram, sizeof(ncm_interface.rcv_datagram)); if ( !r) { printf("--0.2\n"); return; @@ -395,14 +388,7 @@ static void handle_incoming_datagram(uint32_t len) { //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_usb_datagram_size); -#if 0 - if (len != 0) { - usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_usb_datagram, sizeof(ncm_interface.rcv_usb_datagram)); - ncm_interface.rcv_usb_datagram_size = len; - } -#else ncm_interface.rcv_usb_datagram_size = len; -#endif tud_network_recv_renew(); } From a67de1f82f6c0037289c17b548cbdd285737a477 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 17:53:41 +0200 Subject: [PATCH 27/64] - moved some common things into ncm.h - removed some old code --- src/net/tinyusb/ncm.h | 74 +++++++++++++++++++++++-- src/net/tinyusb/ncm_device.c | 102 ++--------------------------------- src/net/tinyusb/net_device.h | 17 ------ 3 files changed, 73 insertions(+), 120 deletions(-) diff --git a/src/net/tinyusb/ncm.h b/src/net/tinyusb/ncm.h index 96ba11fbc..672b4f48b 100755 --- a/src/net/tinyusb/ncm.h +++ b/src/net/tinyusb/ncm.h @@ -30,10 +30,24 @@ #include "common/tusb_common.h" -#ifdef __cplusplus - extern "C" { + +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE + #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 1 // TODO should be 8 or so #endif +#ifndef CFG_TUD_NCM_ALIGNMENT + #define CFG_TUD_NCM_ALIGNMENT 4 +#endif + + // Table 4.3 Data Class Interface Protocol Codes typedef enum { @@ -62,8 +76,58 @@ typedef enum NCM_SET_CRC_MODE = 0x8A, } ncm_request_code_t; -#ifdef __cplusplus - } -#endif + +#define NTH16_SIGNATURE 0x484D434E +#define NDP16_SIGNATURE_NCM0 0x304D434E +#define NDP16_SIGNATURE_NCM1 0x314D434E + +typedef struct TU_ATTR_PACKED { + uint16_t wLength; + uint16_t bmNtbFormatsSupported; + uint32_t dwNtbInMaxSize; + uint16_t wNdbInDivisor; + uint16_t wNdbInPayloadRemainder; + uint16_t wNdbInAlignment; + uint16_t wReserved; + uint32_t dwNtbOutMaxSize; + uint16_t wNdbOutDivisor; + uint16_t wNdbOutPayloadRemainder; + uint16_t wNdbOutAlignment; + uint16_t wNtbOutMaxDatagrams; +} ntb_parameters_t; + +typedef struct TU_ATTR_PACKED { + uint32_t dwSignature; + uint16_t wHeaderLength; + uint16_t wSequence; + uint16_t wBlockLength; + uint16_t wNdpIndex; +} nth16_t; + +typedef struct TU_ATTR_PACKED { + uint16_t wDatagramIndex; + uint16_t wDatagramLength; +} ndp16_datagram_t; + +typedef struct TU_ATTR_PACKED { + uint32_t dwSignature; + uint16_t wLength; + uint16_t wNextNdpIndex; + ndp16_datagram_t datagram[]; +} ndp16_t; + +typedef union TU_ATTR_PACKED { + struct { + nth16_t nth; + ndp16_t ndp; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; +} transmit_ntb_t; + +struct ncm_notify_struct { + tusb_control_request_t header; + uint32_t downlink, uplink; +}; + #endif diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 4f11da615..c35bc584b 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -37,6 +37,7 @@ #include "device/usbd.h" #include "device/usbd_pvt.h" #include "net_device.h" +#include "ncm.h" #include #include "task.h" @@ -45,58 +46,6 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#define NTH16_SIGNATURE 0x484D434E -#define NDP16_SIGNATURE_NCM0 0x304D434E -#define NDP16_SIGNATURE_NCM1 0x314D434E - -typedef struct TU_ATTR_PACKED { - uint16_t wLength; - uint16_t bmNtbFormatsSupported; - uint32_t dwNtbInMaxSize; - uint16_t wNdbInDivisor; - uint16_t wNdbInPayloadRemainder; - uint16_t wNdbInAlignment; - uint16_t wReserved; - uint32_t dwNtbOutMaxSize; - uint16_t wNdbOutDivisor; - uint16_t wNdbOutPayloadRemainder; - uint16_t wNdbOutAlignment; - uint16_t wNtbOutMaxDatagrams; -} ntb_parameters_t; - -typedef struct TU_ATTR_PACKED { - uint32_t dwSignature; - uint16_t wHeaderLength; - uint16_t wSequence; - uint16_t wBlockLength; - uint16_t wNdpIndex; -} nth16_t; - -typedef struct TU_ATTR_PACKED { - uint16_t wDatagramIndex; - uint16_t wDatagramLength; -} ndp16_datagram_t; - -typedef struct TU_ATTR_PACKED { - uint32_t dwSignature; - uint16_t wLength; - uint16_t wNextNdpIndex; - ndp16_datagram_t datagram[]; -} ndp16_t; - -typedef union TU_ATTR_PACKED { - struct { - nth16_t nth; - ndp16_t ndp; - }; - uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; -} transmit_ntb_t; - -struct ecm_notify_struct { - tusb_control_request_t header; - uint32_t downlink, uplink; -}; - typedef struct { uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active @@ -209,7 +158,7 @@ static void ncm_start_tx(void) -tu_static struct ecm_notify_struct ncm_notify_connected = { +tu_static struct ncm_notify_struct ncm_notify_connected = { .header = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, @@ -222,7 +171,7 @@ tu_static struct ecm_notify_struct ncm_notify_connected = { }, }; -tu_static struct ecm_notify_struct ncm_notify_speed_change = { +tu_static struct ncm_notify_struct ncm_notify_speed_change = { .header = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, @@ -247,49 +196,7 @@ void tud_network_recv_renew(void) if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { //printf("--0\n"); -#if 0 - // funny effect with "iperf -c 192.168.14.1 -e -i 1 -l 22 -M 200" - // rcv_datagram is overwritten! - // [10:37:42.330968 0.000287] 38.039 ( 0) - 0 90 54 - // [10:37:42.331361 0.000394] 38.039 ( 0) - 1 146 114 - // [10:37:42.331770 0.000409] 38.039 ( 0) - 2 262 254 - // [10:37:42.332156 0.000386] 38.039 ( 0) - 3 518 254 - // [10:37:42.332566 0.000410] 38.039 ( 0) - 4 774 254 - // [10:37:42.332979 0.000412] 38.039 ( 0) - 5 1030 254 - // [10:37:42.333436 0.000457] 38.040 ( 1) - 6 1286 254 - // [10:37:42.333871 0.000435] 38.040 ( 0) - 7 1542 254 - // [10:37:42.334303 0.000432] 38.040 ( 0) - 8 1798 254 - // [10:37:42.334732 0.000429] 38.040 ( 0) - 9 2054 254 - // [10:37:42.335162 0.000431] 38.040 ( 0) - 10 2310 254 - // [10:37:42.335614 0.000452] 38.040 ( 0) - 11 0 0 - // [10:37:42.335992 0.000378] 38.040 ( 0) - tud_network_recv_renew: 11 0x304d434e 56 0 - // [10:37:42.336912 0.000919] 38.040 ( 0) - tud_network_recv_renew->: 0 200103D8 90 54 OK - // [10:37:42.337755 0.000844] 38.041 ( 1) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.338528 0.000773] 38.041 ( 0) - tud_network_recv_renew->: 1 200103D8 146 114 OK - // [10:37:42.339365 0.000837] 38.041 ( 0) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.340137 0.000771] 38.041 ( 0) - tud_network_recv_renew->: 2 200103D8 262 254 OK - // [10:37:42.340965 0.000828] 38.042 ( 1) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.341748 0.000783] 38.042 ( 0) - tud_network_recv_renew->: 3 200103D8 518 254 OK - // [10:37:42.342572 0.000824] 38.042 ( 0) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.343345 0.000773] 38.042 ( 0) - tud_network_recv_renew->: 4 200103D8 774 254 OK - // [10:37:42.344172 0.000827] 38.043 ( 1) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.344932 0.000760] 38.043 ( 0) - tud_network_recv_renew->: 5 200103D8 1030 254 OK - // [10:37:42.345778 0.000847] 38.043 ( 0) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.346567 0.000788] 38.043 ( 0) - tud_network_recv_renew->: 6 200103D8 1626 254 FAIL - // [10:37:42.347423 0.000856] 38.044 ( 1) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.348195 0.000772] 38.044 ( 0) - tud_network_recv_renew->: 7 200103D8 1882 254 FAIL - // [10:37:42.349037 0.000842] 38.044 ( 0) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.349828 0.000792] 38.044 ( 0) - tud_network_recv_renew->: 8 200103D8 0 0 FAIL - // [10:37:42.350546 0.000717] 38.046 ( 2) - handle_incoming_datagram(2136) - // [10:37:42.351156 0.000611] 38.046 ( 0) - tud_network_recv_renew() - 11 [20020120] - // [10:37:42.351867 0.000711] 38.046 ( 0) - tud_network_recv_renew->: 9 200103D8 0 0 FAIL & DEAD - bool r; - r = usbd_edpt_xfer(0, ncm_interface.ep_out, rcv_datagram, sizeof(rcv_datagram)); - if ( !r) { - printf("--0.0\n"); - return; - } -#else + if (ncm_interface.rcv_usb_datagram_size == 0) { if (usbd_edpt_busy(0, ncm_interface.ep_out)) { printf("--0.1\n"); @@ -303,7 +210,6 @@ void tud_network_recv_renew(void) } } } -#endif //printf("--1\n"); diff --git a/src/net/tinyusb/net_device.h b/src/net/tinyusb/net_device.h index 935161904..cf40651b4 100755 --- a/src/net/tinyusb/net_device.h +++ b/src/net/tinyusb/net_device.h @@ -35,8 +35,6 @@ #error "Cannot enable both ECM_RNDIS and NCM network drivers" #endif -#include "ncm.h" - /* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ #define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) @@ -45,21 +43,6 @@ #define CFG_TUD_NET_MTU 1514 #endif -#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE -#define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 -#endif - -#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE -#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 -#endif - -#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB -#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 1 // TODO should be 8 or so -#endif - -#ifndef CFG_TUD_NCM_ALIGNMENT -#define CFG_TUD_NCM_ALIGNMENT 4 -#endif #ifdef __cplusplus extern "C" { From 4e5e8c1991d485f543dec0301e7ba9a98cc06c53 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 18:17:38 +0200 Subject: [PATCH 28/64] ncm_device_simple uses ncm_device as base --- src/net/tinyusb/ncm_device.c | 4 +- src/net/tinyusb/ncm_device_simple.c | 609 ++++++++++++++++++++++++++++ 2 files changed, 610 insertions(+), 3 deletions(-) create mode 100755 src/net/tinyusb/ncm_device_simple.c diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index c35bc584b..dd2883d03 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -34,13 +34,11 @@ #define tu_static static #endif +#include #include "device/usbd.h" #include "device/usbd_pvt.h" #include "net_device.h" #include "ncm.h" -#include - -#include "task.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c new file mode 100755 index 000000000..dd2883d03 --- /dev/null +++ b/src/net/tinyusb/ncm_device_simple.c @@ -0,0 +1,609 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + +#if ECLIPSE_GUI + #define tu_static static +#endif + +#include +#include "device/usbd.h" +#include "device/usbd_pvt.h" +#include "net_device.h" +#include "ncm.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +typedef struct { + uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface + uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active + + uint8_t ep_notif; + uint8_t ep_in; + uint8_t ep_out; + + const ndp16_t *rcv_ndp; + uint8_t rcv_datagram_num; + uint8_t rcv_datagram_index; + CFG_TUSB_MEM_ALIGN uint8_t rcv_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; + uint16_t rcv_usb_datagram_size; + + enum { + REPORT_SPEED, REPORT_CONNECTED, REPORT_DONE + } report_state; + bool report_pending; + + uint8_t current_ntb; // Index in transmit_ntb[] that is currently being filled with datagrams + uint8_t datagram_count; // Number of datagrams in transmit_ntb[current_ntb] + uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram + uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE + uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + + uint16_t nth_sequence; // Sequence number counter for transmitted NTBs + + bool xmt_running; + +} ncm_interface_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE+400, + .wNdbInDivisor = 4, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 4, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 1 // 0=no limit TODO set to 0 +}; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; + +tu_static ncm_interface_t ncm_interface; + +static void ncm_prepare_for_tx(void) +/** + * Set up the NTB state in ncm_interface to be ready to add datagrams. + * + * \pre + * \a ncm_interface.current_ntb must be set correctly + */ +{ + //printf("ncm_prepare_for_tx()\n"); + ncm_interface.datagram_count = 0; + // datagrams start after all the headers + ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) + + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); + memset(transmit_ntb + ncm_interface.current_ntb, 0, sizeof(transmit_ntb_t)); +} + + + +/* + * If not already transmitting, start sending the current NTB to the host and swap buffers + * to start filling the other one with datagrams. + */ +static void ncm_start_tx(void) +{ + //printf("ncm_start_tx() - %d %d\n", ncm_interface.xmt_running, ncm_interface.datagram_count); + + if (ncm_interface.xmt_running) { + return; + } + + transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + size_t ntb_length = ncm_interface.next_datagram_offset; + + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(nth16_t); + ntb->nth.wSequence = ncm_interface.nth_sequence++; + ntb->nth.wBlockLength = ntb_length; + ntb->nth.wNdpIndex = sizeof(nth16_t); + + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ndp16_t) + (ncm_interface.datagram_count + 1) * sizeof(ndp16_datagram_t); + ntb->ndp.wNextNdpIndex = 0; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = 0; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; + + // Kick off an endpoint transfer + usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); + ncm_interface.xmt_running = true; + + // Swap to the other NTB and clear it out + ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; + ncm_prepare_for_tx(); +} + + + +tu_static struct ncm_notify_struct ncm_notify_connected = { + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_NETWORK_CONNECTION, + .wValue = 1 /* Connected */, + .wLength = 0, + }, +}; + +tu_static struct ncm_notify_struct ncm_notify_speed_change = { + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, + .wLength = 8, + }, + .downlink = 1000000, + .uplink = 1000000, +}; + + + +void tud_network_recv_renew(void) +/** + * context: lwIP & TinyUSB + */ +{ + //printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); + if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { + + //printf("--0\n"); + + if (ncm_interface.rcv_usb_datagram_size == 0) { + if (usbd_edpt_busy(0, ncm_interface.ep_out)) { + printf("--0.1\n"); + return; + } + else { + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_datagram, sizeof(ncm_interface.rcv_datagram)); + if ( !r) { + printf("--0.2\n"); + return; + } + } + } + + //printf("--1\n"); + + const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_datagram; + if (ncm_interface.rcv_usb_datagram_size < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + //printf("--1.1.1 %d\n", ncm_interface.rcv_usb_datagram_size); + return; + } + if (hdr->dwSignature != NTH16_SIGNATURE) { + printf("--1.1.2 0x%lx %d\n", hdr->dwSignature, ncm_interface.rcv_usb_datagram_size); + return; + } + if (hdr->wNdpIndex < sizeof(nth16_t)) { + printf("--1.1.3 %d\n", hdr->wNdpIndex); + return; + } + if (hdr->wNdpIndex + sizeof(ndp16_t) > ncm_interface.rcv_usb_datagram_size) { + printf("--1.1.4 %d %d\n", hdr->wNdpIndex + sizeof(ndp16_t), ncm_interface.rcv_usb_datagram_size); + return; + } + + const ndp16_t *ndp = (const ndp16_t*) (ncm_interface.rcv_datagram + hdr->wNdpIndex); + if (hdr->wNdpIndex + ndp->wLength > ncm_interface.rcv_usb_datagram_size) { + printf("--1.2.1 %d %d\n", hdr->wNdpIndex + ndp->wLength, ncm_interface.rcv_usb_datagram_size); + return; + } + if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { + printf("--1.2.2 0x%lx %d\n", ndp->dwSignature, ncm_interface.rcv_usb_datagram_size); + return; + } + + //printf("--2\n"); + + int max_rcv_datagrams = (ndp->wLength - 8) / 4; + ncm_interface.rcv_datagram_index = 0; + ncm_interface.rcv_datagram_num = 0; + ncm_interface.rcv_ndp = ndp; + while (ncm_interface.rcv_datagram_num < max_rcv_datagrams) + { +#if 0 + printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, + ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex, + ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength); +#endif + if ( ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex == 0 + && ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength == 0) { + break; + } + ++ncm_interface.rcv_datagram_num; + } + +#if 0 + printf("tud_network_recv_renew: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, + ndp->wNextNdpIndex); +#endif + + ncm_interface.rcv_usb_datagram_size = 0; + } + + if (ncm_interface.rcv_datagram_num == 0) { + return; + } + + const ndp16_t *ndp = ncm_interface.rcv_ndp; + +#if 0 + printf("tud_network_recv_renew->: %d %p %d %d\n", ncm_interface.rcv_datagram_index, + ndp, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength); +#endif + + if (tud_network_recv_cb(ncm_interface.rcv_datagram + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength)) { + //printf("!!!!!!!!!!!!!!!!!!!!\n"); + ++ncm_interface.rcv_datagram_index; + } +} + + + +static void handle_incoming_datagram(uint32_t len) +{ + //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_usb_datagram_size); + + ncm_interface.rcv_usb_datagram_size = len; + + tud_network_recv_renew(); +} + + + +//--------------------------------------------------------------------+ +// USBD Driver API +//--------------------------------------------------------------------+ + +void netd_init(void) +/** + * called on start + * + * context: TinyUSB + */ +{ + printf("netd_init() [%p]\n", xTaskGetCurrentTaskHandle()); + + tu_memclr(&ncm_interface, sizeof(ncm_interface)); + ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; + ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; + ncm_prepare_for_tx(); +} + + + +void netd_reset(uint8_t rhport) +/** + * called with rhport=0 + * + * context: TinyUSB + */ +{ + (void) rhport; + + printf("netd_reset(%d) [%p]\n", rhport, xTaskGetCurrentTaskHandle()); + + netd_init(); +} + + + +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +/** + * called with max_len=143 + * + * context: TinyUSB + */ +{ + // confirm interface hasn't already been allocated + TU_ASSERT(0 == ncm_interface.ep_notif, 0); + + printf("netd_open(%d,%p,%d) [%p]\n", rhport, itf_desc, max_len, xTaskGetCurrentTaskHandle()); + + //------------- Management Interface -------------// + ncm_interface.itf_num = itf_desc->bInterfaceNumber; + + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const *p_desc = tu_desc_next(itf_desc); + + // Communication Functional Descriptors + while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // notification endpoint (if any) + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { + TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const* ) p_desc), 0); + + ncm_interface.ep_notif = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + //------------- Data Interface -------------// + // - CDC-NCM data interface has 2 alternate settings + // - 0 : zero endpoints for inactive (default) + // - 1 : IN & OUT endpoints for transfer of NTBs + TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); + + do { + tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const*) p_desc; + TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } while ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len)); + + // Pair of endpoints + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); + + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); + + drv_len += 2 * sizeof(tusb_desc_endpoint_t); + + return drv_len; +} + + + +static void ncm_report(void) +/** + * called on init + */ +{ + //printf("ncm_report - %d\n", ncm_interface.report_state); + uint8_t const rhport = 0; + if (ncm_interface.report_state == REPORT_SPEED) { + ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_speed_change, + sizeof(ncm_notify_speed_change)); + ncm_interface.report_state = REPORT_CONNECTED; + ncm_interface.report_pending = true; + } + else if (ncm_interface.report_state == REPORT_CONNECTED) { + ncm_notify_connected.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_connected, sizeof(ncm_notify_connected)); + ncm_interface.report_state = REPORT_DONE; + ncm_interface.report_pending = true; + } +} + + + +TU_ATTR_WEAK void tud_network_link_state_cb(bool state) +/** + * called on init three times with 1/0/1 + * + * context: TinyUSB + */ +{ + (void) state; + printf("tud_network_link_state_cb(%d) [%p]\n", state, xTaskGetCurrentTaskHandle()); +} + + + +// Handle class control request +// return false to stall control endpoint (e.g unsupported request) +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +/** + * Called on init of connection + * + * context: TinyUSB + */ +{ + printf("netd_control_xfer_cb(%d, %d, %p) [%p]\n", rhport, stage, request, xTaskGetCurrentTaskHandle()); + + if (stage != CONTROL_STAGE_SETUP) + return true ; + + switch (request->bmRequestType_bit.type) { + case TUSB_REQ_TYPE_STANDARD: + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); + + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + } + break; + + case TUSB_REQ_SET_INTERFACE: { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + uint8_t const req_alt = (uint8_t) request->wValue; + + // Only valid for Data Interface with Alternate is either 0 or 1 + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); + + if (req_alt != ncm_interface.itf_data_alt) { + ncm_interface.itf_data_alt = req_alt; + + if (ncm_interface.itf_data_alt) { + if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { + tud_network_recv_renew(); // prepare for incoming datagrams + } + if (!ncm_interface.report_pending) { + ncm_report(); + } + } + + tud_network_link_state_cb(ncm_interface.itf_data_alt); + } + + tud_control_status(rhport, request); + } + break; + + // unsupported request + default: + return false ; + } + break; + + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY(ncm_interface.itf_num == request->wIndex); + + //printf("netd_control_xfer_cb/TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); + + if (NCM_GET_NTB_PARAMETERS == request->bRequest) { + tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } + + break; + + // unsupported request + default: + return false ; + } + + return true ; +} + + + +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +/** + * context: TinyUSB + */ +{ + (void) rhport; + (void) result; + + //printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); + + /* new datagram rcv_datagram */ + if (ep_addr == ncm_interface.ep_out) { + //printf(" EP_OUT\n"); + handle_incoming_datagram(xferred_bytes); + } + + /* data transmission finished */ + if (ep_addr == ncm_interface.ep_in) { + //printf(" EP_IN %d %d %d\n", ncm_interface.xmt_running, ncm_interface.datagram_count, + //ncm_interface.itf_data_alt); + ncm_interface.xmt_running = false; + + // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now + if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { + ncm_start_tx(); + } + } + + if (ep_addr == ncm_interface.ep_notif) { + //printf(" EP_NOTIF\n"); + ncm_interface.report_pending = false; + ncm_report(); + } + + return true ; +} + + + +bool tud_network_can_xmit(uint16_t size) +/** + * poll network driver for its ability to accept another packet to transmit + * + * context: lwIP + * + */ +{ + TU_VERIFY(ncm_interface.itf_data_alt == 1); + +#if 0 + printf("tud_network_can_xmit(%d) %d %d - %d %d [%p]\n", size, ncm_interface.datagram_count, ncm_interface.max_datagrams_per_ntb, + next_datagram_offset, ncm_interface.ntb_in_size, xTaskGetCurrentTaskHandle()); +#endif + + if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { + // this happens if max... is set to 1 + printf("NTB full [by count]\r\n"); + return false ; + } + + if (ncm_interface.next_datagram_offset + size > ncm_interface.ntb_in_size) { + // this happens + printf("ntb full [by size]\r\n"); + return false ; + } + + return true ; +} + + + +void tud_network_xmit(void *ref, uint16_t arg) +/** + * context: lwIP. + */ +{ + transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + + //printf("tud_network_xmit(%p,%d) [%p]\n", ref, arg, xTaskGetCurrentTaskHandle()); + + uint16_t size = tud_network_xmit_cb(ntb->data + ncm_interface.next_datagram_offset, ref, arg); + + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; + ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; + + ncm_interface.datagram_count++; + ncm_interface.next_datagram_offset += size; + + // round up so the next datagram is aligned correctly + ncm_interface.next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); + ncm_interface.next_datagram_offset -= (ncm_interface.next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); + + ncm_start_tx(); +} + +#endif From 3b05f0f625255ad6c2946a93f11be19e4719861b Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 20:12:24 +0200 Subject: [PATCH 29/64] this simple version can already communicate --- src/net/tinyusb/ncm_device_simple.c | 247 ++++++++++++---------------- 1 file changed, 104 insertions(+), 143 deletions(-) diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index dd2883d03..65f4fb50c 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -40,6 +40,10 @@ #include "net_device.h" #include "ncm.h" +#undef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB +#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 1 + + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -63,16 +67,13 @@ typedef struct { } report_state; bool report_pending; - uint8_t current_ntb; // Index in transmit_ntb[] that is currently being filled with datagrams - uint8_t datagram_count; // Number of datagrams in transmit_ntb[current_ntb] uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB uint16_t nth_sequence; // Sequence number counter for transmitted NTBs - bool xmt_running; - + bool can_xmit; } ncm_interface_t; //--------------------------------------------------------------------+ @@ -94,64 +95,23 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNtbOutMaxDatagrams = 1 // 0=no limit TODO set to 0 }; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb; tu_static ncm_interface_t ncm_interface; + + static void ncm_prepare_for_tx(void) /** * Set up the NTB state in ncm_interface to be ready to add datagrams. - * - * \pre - * \a ncm_interface.current_ntb must be set correctly */ { //printf("ncm_prepare_for_tx()\n"); - ncm_interface.datagram_count = 0; // datagrams start after all the headers ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); - memset(transmit_ntb + ncm_interface.current_ntb, 0, sizeof(transmit_ntb_t)); -} - - - -/* - * If not already transmitting, start sending the current NTB to the host and swap buffers - * to start filling the other one with datagrams. - */ -static void ncm_start_tx(void) -{ - //printf("ncm_start_tx() - %d %d\n", ncm_interface.xmt_running, ncm_interface.datagram_count); - - if (ncm_interface.xmt_running) { - return; - } - - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t ntb_length = ncm_interface.next_datagram_offset; - - // Fill in NTB header - ntb->nth.dwSignature = NTH16_SIGNATURE; - ntb->nth.wHeaderLength = sizeof(nth16_t); - ntb->nth.wSequence = ncm_interface.nth_sequence++; - ntb->nth.wBlockLength = ntb_length; - ntb->nth.wNdpIndex = sizeof(nth16_t); - - // Fill in NDP16 header and terminator - ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; - ntb->ndp.wLength = sizeof(ndp16_t) + (ncm_interface.datagram_count + 1) * sizeof(ndp16_datagram_t); - ntb->ndp.wNextNdpIndex = 0; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = 0; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; - - // Kick off an endpoint transfer - usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); - ncm_interface.xmt_running = true; - - // Swap to the other NTB and clear it out - ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; - ncm_prepare_for_tx(); + memset(&transmit_ntb, 0, sizeof(transmit_ntb_t)); + ncm_interface.can_xmit = true; } @@ -190,10 +150,10 @@ void tud_network_recv_renew(void) * context: lwIP & TinyUSB */ { - //printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); + printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { - //printf("--0\n"); + printf("--0\n"); if (ncm_interface.rcv_usb_datagram_size == 0) { if (usbd_edpt_busy(0, ncm_interface.ep_out)) { @@ -209,11 +169,11 @@ void tud_network_recv_renew(void) } } - //printf("--1\n"); + printf("--1\n"); const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_datagram; if (ncm_interface.rcv_usb_datagram_size < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - //printf("--1.1.1 %d\n", ncm_interface.rcv_usb_datagram_size); + printf("--1.1.1 %d\n", ncm_interface.rcv_usb_datagram_size); return; } if (hdr->dwSignature != NTH16_SIGNATURE) { @@ -239,7 +199,7 @@ void tud_network_recv_renew(void) return; } - //printf("--2\n"); + printf("--2\n"); int max_rcv_datagrams = (ndp->wLength - 8) / 4; ncm_interface.rcv_datagram_index = 0; @@ -247,7 +207,7 @@ void tud_network_recv_renew(void) ncm_interface.rcv_ndp = ndp; while (ncm_interface.rcv_datagram_num < max_rcv_datagrams) { -#if 0 +#if 1 printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength); @@ -259,7 +219,7 @@ void tud_network_recv_renew(void) ++ncm_interface.rcv_datagram_num; } -#if 0 +#if 1 printf("tud_network_recv_renew: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, ndp->wNextNdpIndex); #endif @@ -273,7 +233,7 @@ void tud_network_recv_renew(void) const ndp16_t *ndp = ncm_interface.rcv_ndp; -#if 0 +#if 1 printf("tud_network_recv_renew->: %d %p %d %d\n", ncm_interface.rcv_datagram_index, ndp, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength); @@ -288,9 +248,17 @@ void tud_network_recv_renew(void) +static void do_in_xfer(uint8_t *buf, uint16_t len) +{ + ncm_interface.can_xmit = false; + usbd_edpt_xfer(0, ncm_interface.ep_in, buf, len); +} // do_in_xfer + + + static void handle_incoming_datagram(uint32_t len) { - //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_usb_datagram_size); + printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_usb_datagram_size); ncm_interface.rcv_usb_datagram_size = len; @@ -401,12 +369,11 @@ static void ncm_report(void) * called on init */ { - //printf("ncm_report - %d\n", ncm_interface.report_state); + printf("ncm_report - %d\n", ncm_interface.report_state); uint8_t const rhport = 0; if (ncm_interface.report_state == REPORT_SPEED) { ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_speed_change, - sizeof(ncm_notify_speed_change)); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); ncm_interface.report_state = REPORT_CONNECTED; ncm_interface.report_pending = true; } @@ -448,62 +415,62 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t return true ; switch (request->bmRequestType_bit.type) { - case TUSB_REQ_TYPE_STANDARD: - switch (request->bRequest) { - case TUSB_REQ_GET_INTERFACE: { - uint8_t const req_itfnum = (uint8_t) request->wIndex; - TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); + case TUSB_REQ_TYPE_STANDARD: + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); - tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); - } - break; + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + } + break; - case TUSB_REQ_SET_INTERFACE: { - uint8_t const req_itfnum = (uint8_t) request->wIndex; - uint8_t const req_alt = (uint8_t) request->wValue; + case TUSB_REQ_SET_INTERFACE: { + uint8_t const req_itfnum = (uint8_t) request->wIndex; + uint8_t const req_alt = (uint8_t) request->wValue; - // Only valid for Data Interface with Alternate is either 0 or 1 - TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); + // Only valid for Data Interface with Alternate is either 0 or 1 + TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); - if (req_alt != ncm_interface.itf_data_alt) { - ncm_interface.itf_data_alt = req_alt; + if (req_alt != ncm_interface.itf_data_alt) { + ncm_interface.itf_data_alt = req_alt; - if (ncm_interface.itf_data_alt) { - if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { - tud_network_recv_renew(); // prepare for incoming datagrams - } - if (!ncm_interface.report_pending) { - ncm_report(); + if (ncm_interface.itf_data_alt) { + if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { + tud_network_recv_renew(); // prepare for incoming datagrams + } + if ( !ncm_interface.report_pending) { + ncm_report(); + } + } + + tud_network_link_state_cb(ncm_interface.itf_data_alt); } + + tud_control_status(rhport, request); } + break; - tud_network_link_state_cb(ncm_interface.itf_data_alt); + // unsupported request + default: + return false ; } - - tud_control_status(rhport, request); - } break; - // unsupported request - default: - return false ; - } - break; - - case TUSB_REQ_TYPE_CLASS: - TU_VERIFY(ncm_interface.itf_num == request->wIndex); + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY(ncm_interface.itf_num == request->wIndex); - //printf("netd_control_xfer_cb/TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); + //printf("netd_control_xfer_cb/TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - if (NCM_GET_NTB_PARAMETERS == request->bRequest) { - tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); - } + if (NCM_GET_NTB_PARAMETERS == request->bRequest) { + tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } - break; + break; - // unsupported request - default: - return false ; + // unsupported request + default: + return false ; } return true ; @@ -519,34 +486,28 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ (void) rhport; (void) result; - //printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); + printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); /* new datagram rcv_datagram */ if (ep_addr == ncm_interface.ep_out) { - //printf(" EP_OUT\n"); + printf(" EP_OUT\n"); handle_incoming_datagram(xferred_bytes); } /* data transmission finished */ if (ep_addr == ncm_interface.ep_in) { - //printf(" EP_IN %d %d %d\n", ncm_interface.xmt_running, ncm_interface.datagram_count, - //ncm_interface.itf_data_alt); - ncm_interface.xmt_running = false; - - // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now - if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { - ncm_start_tx(); - } + printf(" EP_IN %d %d\n", ncm_interface.can_xmit, ncm_interface.itf_data_alt); + ncm_prepare_for_tx(); } if (ep_addr == ncm_interface.ep_notif) { - //printf(" EP_NOTIF\n"); + printf(" EP_NOTIF\n"); ncm_interface.report_pending = false; ncm_report(); } return true ; -} +} // netd_xfer_cb @@ -558,27 +519,9 @@ bool tud_network_can_xmit(uint16_t size) * */ { - TU_VERIFY(ncm_interface.itf_data_alt == 1); - -#if 0 - printf("tud_network_can_xmit(%d) %d %d - %d %d [%p]\n", size, ncm_interface.datagram_count, ncm_interface.max_datagrams_per_ntb, - next_datagram_offset, ncm_interface.ntb_in_size, xTaskGetCurrentTaskHandle()); -#endif - - if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { - // this happens if max... is set to 1 - printf("NTB full [by count]\r\n"); - return false ; - } - - if (ncm_interface.next_datagram_offset + size > ncm_interface.ntb_in_size) { - // this happens - printf("ntb full [by size]\r\n"); - return false ; - } - - return true ; -} + printf("tud_network_can_xmit() %d [%p]\n", ncm_interface.can_xmit, xTaskGetCurrentTaskHandle()); + return ncm_interface.can_xmit; +} // tud_network_can_xmit @@ -587,23 +530,41 @@ void tud_network_xmit(void *ref, uint16_t arg) * context: lwIP. */ { - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; + transmit_ntb_t *ntb = &transmit_ntb; - //printf("tud_network_xmit(%p,%d) [%p]\n", ref, arg, xTaskGetCurrentTaskHandle()); + printf("tud_network_xmit(%p,%d) %d [%p]\n", ref, arg, ncm_interface.can_xmit, xTaskGetCurrentTaskHandle()); + + if ( !ncm_interface.can_xmit) { + return; + } uint16_t size = tud_network_xmit_cb(ntb->data + ncm_interface.next_datagram_offset, ref, arg); - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; + ntb->ndp.datagram[0].wDatagramIndex = ncm_interface.next_datagram_offset; + ntb->ndp.datagram[0].wDatagramLength = size; - ncm_interface.datagram_count++; ncm_interface.next_datagram_offset += size; // round up so the next datagram is aligned correctly ncm_interface.next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); ncm_interface.next_datagram_offset -= (ncm_interface.next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); - ncm_start_tx(); -} + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(nth16_t); + ntb->nth.wSequence = ncm_interface.nth_sequence++; + ntb->nth.wBlockLength = ncm_interface.next_datagram_offset; + ntb->nth.wNdpIndex = sizeof(nth16_t); + + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ndp16_t) + (2) * sizeof(ndp16_datagram_t); + ntb->ndp.wNextNdpIndex = 0; + ntb->ndp.datagram[1].wDatagramIndex = 0; + ntb->ndp.datagram[1].wDatagramLength = 0; + + // Kick off an endpoint transfer + do_in_xfer(ntb->data, ncm_interface.next_datagram_offset); +} // tud_network_xmit #endif From ab5047971e2a98e3352f34a0cb013440da522fa4 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 20:29:18 +0200 Subject: [PATCH 30/64] the ZLP is important! --- src/net/tinyusb/ncm_device_simple.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 65f4fb50c..9de0a32cc 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -497,7 +497,15 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ /* data transmission finished */ if (ep_addr == ncm_interface.ep_in) { printf(" EP_IN %d %d\n", ncm_interface.can_xmit, ncm_interface.itf_data_alt); - ncm_prepare_for_tx(); + if (xferred_bytes != 0 && xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE == 0) + { + do_in_xfer(NULL, 0); /* a ZLP is needed */ + } + else + { + /* we're finally finished */ + ncm_prepare_for_tx(); + } } if (ep_addr == ncm_interface.ep_notif) { From f0a30519c632fdc8abc26caf9db129b4a10ff2bd Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 21:55:46 +0200 Subject: [PATCH 31/64] switch off debugging messages: now works even better --- src/net/tinyusb/ncm_device_simple.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 9de0a32cc..e74fca96d 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -150,10 +150,10 @@ void tud_network_recv_renew(void) * context: lwIP & TinyUSB */ { - printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); + //printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { - printf("--0\n"); + //printf("--0\n"); if (ncm_interface.rcv_usb_datagram_size == 0) { if (usbd_edpt_busy(0, ncm_interface.ep_out)) { @@ -169,11 +169,11 @@ void tud_network_recv_renew(void) } } - printf("--1\n"); + //printf("--1\n"); const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_datagram; if (ncm_interface.rcv_usb_datagram_size < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - printf("--1.1.1 %d\n", ncm_interface.rcv_usb_datagram_size); + //printf("--1.1.1 %d\n", ncm_interface.rcv_usb_datagram_size); return; } if (hdr->dwSignature != NTH16_SIGNATURE) { @@ -199,7 +199,7 @@ void tud_network_recv_renew(void) return; } - printf("--2\n"); + //printf("--2\n"); int max_rcv_datagrams = (ndp->wLength - 8) / 4; ncm_interface.rcv_datagram_index = 0; @@ -207,7 +207,7 @@ void tud_network_recv_renew(void) ncm_interface.rcv_ndp = ndp; while (ncm_interface.rcv_datagram_num < max_rcv_datagrams) { -#if 1 +#if 0 printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength); @@ -219,7 +219,7 @@ void tud_network_recv_renew(void) ++ncm_interface.rcv_datagram_num; } -#if 1 +#if 0 printf("tud_network_recv_renew: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, ndp->wNextNdpIndex); #endif @@ -233,7 +233,7 @@ void tud_network_recv_renew(void) const ndp16_t *ndp = ncm_interface.rcv_ndp; -#if 1 +#if 0 printf("tud_network_recv_renew->: %d %p %d %d\n", ncm_interface.rcv_datagram_index, ndp, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength); @@ -258,7 +258,7 @@ static void do_in_xfer(uint8_t *buf, uint16_t len) static void handle_incoming_datagram(uint32_t len) { - printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_usb_datagram_size); + //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_usb_datagram_size); ncm_interface.rcv_usb_datagram_size = len; @@ -486,17 +486,17 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ (void) rhport; (void) result; - printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); + //printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); /* new datagram rcv_datagram */ if (ep_addr == ncm_interface.ep_out) { - printf(" EP_OUT\n"); + //printf(" EP_OUT\n"); handle_incoming_datagram(xferred_bytes); } /* data transmission finished */ if (ep_addr == ncm_interface.ep_in) { - printf(" EP_IN %d %d\n", ncm_interface.can_xmit, ncm_interface.itf_data_alt); + //printf(" EP_IN %d %d\n", ncm_interface.can_xmit, ncm_interface.itf_data_alt); if (xferred_bytes != 0 && xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE == 0) { do_in_xfer(NULL, 0); /* a ZLP is needed */ @@ -527,7 +527,7 @@ bool tud_network_can_xmit(uint16_t size) * */ { - printf("tud_network_can_xmit() %d [%p]\n", ncm_interface.can_xmit, xTaskGetCurrentTaskHandle()); + //printf("tud_network_can_xmit() %d [%p]\n", ncm_interface.can_xmit, xTaskGetCurrentTaskHandle()); return ncm_interface.can_xmit; } // tud_network_can_xmit @@ -540,7 +540,7 @@ void tud_network_xmit(void *ref, uint16_t arg) { transmit_ntb_t *ntb = &transmit_ntb; - printf("tud_network_xmit(%p,%d) %d [%p]\n", ref, arg, ncm_interface.can_xmit, xTaskGetCurrentTaskHandle()); + //printf("tud_network_xmit(%p,%d) %d [%p]\n", ref, arg, ncm_interface.can_xmit, xTaskGetCurrentTaskHandle()); if ( !ncm_interface.can_xmit) { return; From eec2a9a6ab78592736acc2bc7f2e0aab52fc7c5d Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 22:29:20 +0200 Subject: [PATCH 32/64] handle_incoming_datagram() simplyfied --- src/net/tinyusb/ncm_device_simple.c | 152 +++++++++------------------- 1 file changed, 46 insertions(+), 106 deletions(-) diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index e74fca96d..55d4598ec 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -40,10 +40,6 @@ #include "net_device.h" #include "ncm.h" -#undef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB -#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 1 - - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -56,11 +52,7 @@ typedef struct { uint8_t ep_in; uint8_t ep_out; - const ndp16_t *rcv_ndp; - uint8_t rcv_datagram_num; - uint8_t rcv_datagram_index; CFG_TUSB_MEM_ALIGN uint8_t rcv_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; - uint16_t rcv_usb_datagram_size; enum { REPORT_SPEED, REPORT_CONNECTED, REPORT_DONE @@ -68,8 +60,6 @@ typedef struct { bool report_pending; uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram - uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE - uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB uint16_t nth_sequence; // Sequence number counter for transmitted NTBs @@ -109,7 +99,7 @@ static void ncm_prepare_for_tx(void) //printf("ncm_prepare_for_tx()\n"); // datagrams start after all the headers ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) - + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); + + ((1 + 1) * sizeof(ndp16_datagram_t)); memset(&transmit_ntb, 0, sizeof(transmit_ntb_t)); ncm_interface.can_xmit = true; } @@ -150,99 +140,18 @@ void tud_network_recv_renew(void) * context: lwIP & TinyUSB */ { - //printf("tud_network_recv_renew() - %d [%p]\n", ncm_interface.rcv_datagram_num, xTaskGetCurrentTaskHandle()); - if (ncm_interface.rcv_datagram_index >= ncm_interface.rcv_datagram_num) { - - //printf("--0\n"); - - if (ncm_interface.rcv_usb_datagram_size == 0) { - if (usbd_edpt_busy(0, ncm_interface.ep_out)) { - printf("--0.1\n"); - return; - } - else { - bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_datagram, sizeof(ncm_interface.rcv_datagram)); - if ( !r) { - printf("--0.2\n"); - return; - } - } - } + // printf("tud_network_recv_renew() - [%p]\n", xTaskGetCurrentTaskHandle()); - //printf("--1\n"); - - const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_datagram; - if (ncm_interface.rcv_usb_datagram_size < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - //printf("--1.1.1 %d\n", ncm_interface.rcv_usb_datagram_size); - return; - } - if (hdr->dwSignature != NTH16_SIGNATURE) { - printf("--1.1.2 0x%lx %d\n", hdr->dwSignature, ncm_interface.rcv_usb_datagram_size); - return; - } - if (hdr->wNdpIndex < sizeof(nth16_t)) { - printf("--1.1.3 %d\n", hdr->wNdpIndex); - return; - } - if (hdr->wNdpIndex + sizeof(ndp16_t) > ncm_interface.rcv_usb_datagram_size) { - printf("--1.1.4 %d %d\n", hdr->wNdpIndex + sizeof(ndp16_t), ncm_interface.rcv_usb_datagram_size); - return; - } - - const ndp16_t *ndp = (const ndp16_t*) (ncm_interface.rcv_datagram + hdr->wNdpIndex); - if (hdr->wNdpIndex + ndp->wLength > ncm_interface.rcv_usb_datagram_size) { - printf("--1.2.1 %d %d\n", hdr->wNdpIndex + ndp->wLength, ncm_interface.rcv_usb_datagram_size); - return; - } - if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { - printf("--1.2.2 0x%lx %d\n", ndp->dwSignature, ncm_interface.rcv_usb_datagram_size); - return; - } - - //printf("--2\n"); - - int max_rcv_datagrams = (ndp->wLength - 8) / 4; - ncm_interface.rcv_datagram_index = 0; - ncm_interface.rcv_datagram_num = 0; - ncm_interface.rcv_ndp = ndp; - while (ncm_interface.rcv_datagram_num < max_rcv_datagrams) - { -#if 0 - printf(" %d %d %d\n", ncm_interface.rcv_datagram_num, - ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex, - ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength); -#endif - if ( ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramIndex == 0 - && ndp->datagram[ncm_interface.rcv_datagram_num].wDatagramLength == 0) { - break; - } - ++ncm_interface.rcv_datagram_num; - } - -#if 0 - printf("tud_network_recv_renew: %d 0x%08lx %d %d\n", ncm_interface.rcv_datagram_num, ndp->dwSignature, ndp->wLength, - ndp->wNextNdpIndex); -#endif - - ncm_interface.rcv_usb_datagram_size = 0; - } - - if (ncm_interface.rcv_datagram_num == 0) { + if (usbd_edpt_busy(0, ncm_interface.ep_out)) { + printf("--0.1\n"); return; } - - const ndp16_t *ndp = ncm_interface.rcv_ndp; - -#if 0 - printf("tud_network_recv_renew->: %d %p %d %d\n", ncm_interface.rcv_datagram_index, - ndp, ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, - ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength); -#endif - - if (tud_network_recv_cb(ncm_interface.rcv_datagram + ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramIndex, - ndp->datagram[ncm_interface.rcv_datagram_index].wDatagramLength)) { - //printf("!!!!!!!!!!!!!!!!!!!!\n"); - ++ncm_interface.rcv_datagram_index; + else { + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_datagram, sizeof(ncm_interface.rcv_datagram)); + if ( !r) { + printf("--0.2\n"); + return; + } } } @@ -258,11 +167,44 @@ static void do_in_xfer(uint8_t *buf, uint16_t len) static void handle_incoming_datagram(uint32_t len) { - //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu) %d\n", len, ncm_interface.rcv_usb_datagram_size); + //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu)\n", len); + + const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_datagram; + if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + printf("--1.1.1 %ld\n", len); + tud_network_recv_renew(); + return; + } + if (hdr->dwSignature != NTH16_SIGNATURE) { + printf("--1.1.2 0x%lx %ld\n", hdr->dwSignature, len); + return; + } + if (hdr->wNdpIndex < sizeof(nth16_t)) { + printf("--1.1.3 %d\n", hdr->wNdpIndex); + return; + } + if (hdr->wNdpIndex + sizeof(ndp16_t) > len) { + printf("--1.1.4 %d %ld\n", hdr->wNdpIndex + sizeof(ndp16_t), len); + return; + } - ncm_interface.rcv_usb_datagram_size = len; + const ndp16_t *ndp = (const ndp16_t*) (ncm_interface.rcv_datagram + hdr->wNdpIndex); + if (hdr->wNdpIndex + ndp->wLength > len) { + printf("--1.2.1 %d %ld\n", hdr->wNdpIndex + ndp->wLength, len); + return; + } + if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { + printf("--1.2.2 0x%lx %ld\n", ndp->dwSignature, len); + return; + } - tud_network_recv_renew(); + //printf("--2\n"); + + if ( !tud_network_recv_cb(ncm_interface.rcv_datagram + ndp->datagram[0].wDatagramIndex, + ndp->datagram[0].wDatagramLength)) { + //printf("!!!!!!!!!!!!!!!!!!!!\n"); + tud_network_recv_renew(); + } } @@ -281,8 +223,6 @@ void netd_init(void) printf("netd_init() [%p]\n", xTaskGetCurrentTaskHandle()); tu_memclr(&ncm_interface, sizeof(ncm_interface)); - ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; - ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; ncm_prepare_for_tx(); } From 9130590a81d61d3c6f680bf90eea24846eb72218 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 22:52:21 +0200 Subject: [PATCH 33/64] it works with multicore as well (wasn't sure before) --- include/FreeRTOSConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/FreeRTOSConfig.h b/include/FreeRTOSConfig.h index 95809da63..53ca2c208 100644 --- a/include/FreeRTOSConfig.h +++ b/include/FreeRTOSConfig.h @@ -120,7 +120,7 @@ */ /* SMP port only */ -#define configNUM_CORES 1 +#define configNUM_CORES 2 #define configTICK_CORE 1 #define configRUN_MULTIPLE_PRIORITIES 1 #if configNUM_CORES != 1 From 9f065e542941e5f27f3bb8ec5a26f1616182e71e Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 29 Jun 2023 22:59:16 +0200 Subject: [PATCH 34/64] latest working versions --- CMakeLists.txt | 8 ++++---- src/net/net_glue.c | 6 +++--- src/net/net_sysview.c | 12 ++++-------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b2f71894..cab451ac9 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ else() endif() option(OPT_CMSIS_DAPV1 "Enable CMSIS-DAPv1" 0) -option(OPT_CMSIS_DAPV2 "Enable CMSIS-DAPv2" 0) +option(OPT_CMSIS_DAPV2 "Enable CMSIS-DAPv2" 1) option(OPT_TARGET_UART "Enable CDC for target UART I/O" 1) option(OPT_PROBE_DEBUG_OUT "Enable CDC for probe debug output" ${DEFAULT_OPT_PROBE_DEBUG_OUT}) option(OPT_SIGROK "Enable sigrok" 0) @@ -265,7 +265,7 @@ if(NOT OPT_NET STREQUAL "") else() # NCM: use own copy of ncm_device, original one must be outcommented target_sources(${PROJECT} PRIVATE - src/net/tinyusb/ncm_device.c + src/net/tinyusb/ncm_device_simple.c ) endif() @@ -332,8 +332,8 @@ pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/src/probe.pio) target_include_directories(${PROJECT} PRIVATE src) target_compile_definitions (${PROJECT} PRIVATE - PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 - PICO_RP2040_USB_DEVICE_UFRAME_FIX=1 + #PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 + #PICO_RP2040_USB_DEVICE_UFRAME_FIX=1 ) target_link_libraries(${PROJECT} PRIVATE diff --git a/src/net/net_glue.c b/src/net/net_glue.c index f61c1acf9..06986d4b1 100755 --- a/src/net/net_glue.c +++ b/src/net/net_glue.c @@ -152,7 +152,7 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) * \return false if the packet buffer was not accepted */ { - printf("tud_network_recv_cb(%p,%u)\n", src, size); + //printf("tud_network_recv_cb(%p,%u)\n", src, size); #if 0 /* this shouldn't happen, but if we get another packet before @@ -237,8 +237,8 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) static void context_tinyusb_linkoutput(void *param) { if ( !tud_network_can_xmit(xmt_buff_len)) { - printf("context_tinyusb_linkoutput: sleep\n"); - vTaskDelay(pdMS_TO_TICKS(10)); + //printf("context_tinyusb_linkoutput: sleep\n"); + vTaskDelay(pdMS_TO_TICKS(5)); usbd_defer_func(context_tinyusb_linkoutput, NULL, false); } else { diff --git a/src/net/net_sysview.c b/src/net/net_sysview.c index b369ca178..c30865ed8 100755 --- a/src/net/net_sysview.c +++ b/src/net/net_sysview.c @@ -137,15 +137,11 @@ static void sysview_try_send(void *ctx) sysview_close(m_pcb_client); } -#if 1 if ( !block_call_to_tcp_output && tcp_sndbuf(m_pcb_client) < 3 * TCP_SND_BUF / 4) { - printf("sysview_try_send: flush %d %d\n", tcp_sndbuf(m_pcb_client), 3 * TCP_SND_BUF / 4); + //printf("sysview_try_send: flush %d %d\n", tcp_sndbuf(m_pcb_client), 3 * TCP_SND_BUF / 4); block_call_to_tcp_output = true; tcp_output(m_pcb_client); } -#else - tcp_output(m_pcb_client); -#endif if ( !xStreamBufferIsEmpty(stream_sysview_to_host)) { tcpip_callback_with_block(sysview_try_send, NULL, 0); @@ -153,7 +149,7 @@ static void sysview_try_send(void *ctx) } } else { - printf("sysview_try_send: no tcp_sndbuf!!!!\n"); + //printf("sysview_try_send: no tcp_sndbuf!!!!\n"); if ( !block_call_to_tcp_output) { printf("sysview_try_send: flush\n"); block_call_to_tcp_output = true; @@ -167,7 +163,7 @@ static void sysview_try_send(void *ctx) static err_t sysview_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len) { - printf("sysview_sent(%p,%p,%d) %d\n", arg, tpcb, len, m_state); + //printf("sysview_sent(%p,%p,%d) %d\n", arg, tpcb, len, m_state); block_call_to_tcp_output = false; @@ -262,7 +258,7 @@ static err_t sysview_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err_t sysview_poll(void *arg, struct tcp_pcb *tpcb) { - printf("sysview_poll(%p,%p) %d\n", arg, tpcb, m_state); + //printf("sysview_poll(%p,%p) %d\n", arg, tpcb, m_state); //sysview_try_send(NULL); tcpip_callback_with_block(sysview_try_send, NULL, 0); From 4e8deed5a93211aaaf7dc82ba0a178c365d536a1 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 30 Jun 2023 07:31:14 +0200 Subject: [PATCH 35/64] more frame checking --- doc/lwIP-notes.adoc | 6 +++ src/net/tinyusb/ncm_device_simple.c | 71 +++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/doc/lwIP-notes.adoc b/doc/lwIP-notes.adoc index 6f378c416..6210316e2 100755 --- a/doc/lwIP-notes.adoc +++ b/doc/lwIP-notes.adoc @@ -130,6 +130,12 @@ Monitor performance/errors with Wireshark. ## Log +### 2023-06-30 + +* for debugging purposes reimplemented `ncm_device_simple.c` which can hold only + one ethernet frame per NTB (NCM Transfer Block). This unfortunately requires + that the original `ncm_device.c` must be outcommented via `#if` on top. + ### 2023-06-26 * after some changes to `rtt_console.c`, `net_sysview.c` and `net_glue.c` diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 55d4598ec..e846c3fc8 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -166,46 +166,77 @@ static void do_in_xfer(uint8_t *buf, uint16_t len) static void handle_incoming_datagram(uint32_t len) +/** + * Handle an incoming NTP. + * Most is checking validity of the frame. If the frame is not valid, it is rejected. + * Input NTP is in \a ncm_interface.rcv_datagram. + */ { + bool ok = true; + //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu)\n", len); const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_datagram; + const ndp16_t *ndp = NULL; + if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { printf("--1.1.1 %ld\n", len); - tud_network_recv_renew(); - return; + ok = false; } - if (hdr->dwSignature != NTH16_SIGNATURE) { + else if (hdr->dwSignature != NTH16_SIGNATURE) { printf("--1.1.2 0x%lx %ld\n", hdr->dwSignature, len); - return; + ok = false; } - if (hdr->wNdpIndex < sizeof(nth16_t)) { + else if (hdr->wNdpIndex < sizeof(nth16_t)) { printf("--1.1.3 %d\n", hdr->wNdpIndex); - return; + ok = false; } - if (hdr->wNdpIndex + sizeof(ndp16_t) > len) { + else if (hdr->wNdpIndex + sizeof(ndp16_t) > len) { printf("--1.1.4 %d %ld\n", hdr->wNdpIndex + sizeof(ndp16_t), len); - return; + ok = false; } - const ndp16_t *ndp = (const ndp16_t*) (ncm_interface.rcv_datagram + hdr->wNdpIndex); - if (hdr->wNdpIndex + ndp->wLength > len) { - printf("--1.2.1 %d %ld\n", hdr->wNdpIndex + ndp->wLength, len); - return; + if (ok) { + ndp = (const ndp16_t*) (ncm_interface.rcv_datagram + hdr->wNdpIndex); + + if (hdr->wNdpIndex + ndp->wLength > len) { + printf("--1.2.1 %d %ld\n", hdr->wNdpIndex + ndp->wLength, len); + ok = false; + } + else if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { + printf("--1.2.2 0x%lx %ld\n", ndp->dwSignature, len); + ok = false; + } } - if (ndp->dwSignature != NDP16_SIGNATURE_NCM0 && ndp->dwSignature != NDP16_SIGNATURE_NCM1) { - printf("--1.2.2 0x%lx %ld\n", ndp->dwSignature, len); - return; + + if (ok) { + if (ndp->datagram[1].wDatagramIndex != 0 || ndp->datagram[1].wDatagramLength != 0) { + printf("--1.3.1 %d %d\n", ndp->datagram[1].wDatagramIndex, ndp->datagram[1].wDatagramLength); + ok = false; + } + else if (ndp->wNextNdpIndex != 0) { + printf("--1.3.2 %d\n", ndp->wNextNdpIndex); + ok = false; + } + else if (ndp->datagram[0].wDatagramIndex + ndp->datagram[0].wDatagramLength > len) { + printf("--1.3.3 %d %d %ld\n", ndp->datagram[0].wDatagramIndex, ndp->datagram[0].wDatagramLength, len); + ok = false; + } } - //printf("--2\n"); + if (ok) { + if ( !tud_network_recv_cb(ncm_interface.rcv_datagram + ndp->datagram[0].wDatagramIndex, + ndp->datagram[0].wDatagramLength)) { + ok = false; + } + } - if ( !tud_network_recv_cb(ncm_interface.rcv_datagram + ndp->datagram[0].wDatagramIndex, - ndp->datagram[0].wDatagramLength)) { - //printf("!!!!!!!!!!!!!!!!!!!!\n"); + if ( !ok) { + // receiver must be reenabled to get a chance to recover + printf("!!!!!!!!!!!!!!!!!!!!\n"); tud_network_recv_renew(); } -} +} // handle_incoming_datagram From 08755c93b26b2cb97c378bf392c13127b4bcbbbc Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 30 Jun 2023 07:56:34 +0200 Subject: [PATCH 36/64] minor simplifications --- src/net/tinyusb/ncm_device_simple.c | 57 ++++++++++++++--------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index e846c3fc8..08eba78e2 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -1,6 +1,7 @@ /* * The MIT License (MIT) * + * Copyright (c) 2023 Hardy Griech * Copyright (c) 2020 Jacob Berg Potter * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -37,6 +38,8 @@ #include #include "device/usbd.h" #include "device/usbd_pvt.h" + +// TODO CFG_TUD_NCM_OUT_NTB_MAX_SIZE set correctly (it is too big currently) #include "net_device.h" #include "ncm.h" @@ -52,15 +55,15 @@ typedef struct { uint8_t ep_in; uint8_t ep_out; - CFG_TUSB_MEM_ALIGN uint8_t rcv_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; + CFG_TUSB_MEM_ALIGN uint8_t rcv_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; enum { - REPORT_SPEED, REPORT_CONNECTED, REPORT_DONE + REPORT_SPEED, + REPORT_CONNECTED, + REPORT_DONE } report_state; bool report_pending; - uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram - uint16_t nth_sequence; // Sequence number counter for transmitted NTBs bool can_xmit; @@ -97,12 +100,9 @@ static void ncm_prepare_for_tx(void) */ { //printf("ncm_prepare_for_tx()\n"); - // datagrams start after all the headers - ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) - + ((1 + 1) * sizeof(ndp16_datagram_t)); memset(&transmit_ntb, 0, sizeof(transmit_ntb_t)); ncm_interface.can_xmit = true; -} +} // ncm_prepare_for_tx @@ -147,7 +147,7 @@ void tud_network_recv_renew(void) return; } else { - bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_datagram, sizeof(ncm_interface.rcv_datagram)); + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_ntb, sizeof(ncm_interface.rcv_ntb)); if ( !r) { printf("--0.2\n"); return; @@ -169,14 +169,14 @@ static void handle_incoming_datagram(uint32_t len) /** * Handle an incoming NTP. * Most is checking validity of the frame. If the frame is not valid, it is rejected. - * Input NTP is in \a ncm_interface.rcv_datagram. + * Input NTP is in \a ncm_interface.rcv_ntb. */ { bool ok = true; //printf("!!!!!!!!!!!!!handle_incoming_datagram(%lu)\n", len); - const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_datagram; + const nth16_t *hdr = (const nth16_t*)ncm_interface.rcv_ntb; const ndp16_t *ndp = NULL; if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { @@ -197,7 +197,7 @@ static void handle_incoming_datagram(uint32_t len) } if (ok) { - ndp = (const ndp16_t*) (ncm_interface.rcv_datagram + hdr->wNdpIndex); + ndp = (const ndp16_t*) (ncm_interface.rcv_ntb + hdr->wNdpIndex); if (hdr->wNdpIndex + ndp->wLength > len) { printf("--1.2.1 %d %ld\n", hdr->wNdpIndex + ndp->wLength, len); @@ -225,7 +225,7 @@ static void handle_incoming_datagram(uint32_t len) } if (ok) { - if ( !tud_network_recv_cb(ncm_interface.rcv_datagram + ndp->datagram[0].wDatagramIndex, + if ( !tud_network_recv_cb(ncm_interface.rcv_ntb + ndp->datagram[0].wDatagramIndex, ndp->datagram[0].wDatagramLength)) { ok = false; } @@ -459,7 +459,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ //printf("netd_xfer_cb(%d,%d,%d,%lu) [%p]\n", rhport, ep_addr, result, xferred_bytes, xTaskGetCurrentTaskHandle()); - /* new datagram rcv_datagram */ + /* new datagram rcv_ntb */ if (ep_addr == ncm_interface.ep_out) { //printf(" EP_OUT\n"); handle_incoming_datagram(xferred_bytes); @@ -470,6 +470,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ //printf(" EP_IN %d %d\n", ncm_interface.can_xmit, ncm_interface.itf_data_alt); if (xferred_bytes != 0 && xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE == 0) { + // TODO check when ZLP is really needed do_in_xfer(NULL, 0); /* a ZLP is needed */ } else @@ -510,6 +511,8 @@ void tud_network_xmit(void *ref, uint16_t arg) */ { transmit_ntb_t *ntb = &transmit_ntb; + uint16_t next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) + + ((1 + 1) * sizeof(ndp16_datagram_t)); //printf("tud_network_xmit(%p,%d) %d [%p]\n", ref, arg, ncm_interface.can_xmit, xTaskGetCurrentTaskHandle()); @@ -517,33 +520,29 @@ void tud_network_xmit(void *ref, uint16_t arg) return; } - uint16_t size = tud_network_xmit_cb(ntb->data + ncm_interface.next_datagram_offset, ref, arg); + uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); - ntb->ndp.datagram[0].wDatagramIndex = ncm_interface.next_datagram_offset; + ntb->ndp.datagram[0].wDatagramIndex = next_datagram_offset; ntb->ndp.datagram[0].wDatagramLength = size; - ncm_interface.next_datagram_offset += size; - - // round up so the next datagram is aligned correctly - ncm_interface.next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); - ncm_interface.next_datagram_offset -= (ncm_interface.next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); + next_datagram_offset += size; // Fill in NTB header - ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.dwSignature = NTH16_SIGNATURE; ntb->nth.wHeaderLength = sizeof(nth16_t); - ntb->nth.wSequence = ncm_interface.nth_sequence++; - ntb->nth.wBlockLength = ncm_interface.next_datagram_offset; - ntb->nth.wNdpIndex = sizeof(nth16_t); + ntb->nth.wSequence = ncm_interface.nth_sequence++; + ntb->nth.wBlockLength = next_datagram_offset; + ntb->nth.wNdpIndex = sizeof(nth16_t); // Fill in NDP16 header and terminator - ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; - ntb->ndp.wLength = sizeof(ndp16_t) + (2) * sizeof(ndp16_datagram_t); + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ndp16_t) + (2) * sizeof(ndp16_datagram_t); ntb->ndp.wNextNdpIndex = 0; - ntb->ndp.datagram[1].wDatagramIndex = 0; + ntb->ndp.datagram[1].wDatagramIndex = 0; ntb->ndp.datagram[1].wDatagramLength = 0; // Kick off an endpoint transfer - do_in_xfer(ntb->data, ncm_interface.next_datagram_offset); + do_in_xfer(ntb->data, next_datagram_offset); } // tud_network_xmit #endif From b6661f81bb97067827e3843f04503e3a66139c30 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sat, 1 Jul 2023 10:06:28 +0200 Subject: [PATCH 37/64] ncm_device plus ZLP works better but reception is limited to one datagram per NTB --- CMakeLists.txt | 4 +++- doc/lwIP-notes.adoc | 4 +++- src/net/tinyusb/ncm.h | 2 +- src/net/tinyusb/ncm_device.c | 23 +++++++++++++++-------- src/net/tinyusb/ncm_device_simple.c | 2 +- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cab451ac9..66c1ba969 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,8 @@ pico_sdk_init() # message("--------- " ${PICO_LWIP_PATH}) # message("--------- " ${PICO_LWIP_CONTRIB_PATH}) # message("--------- " ${PICO_TINYUSB_PATH}) +message("---------" ${tinyusb_device_base}) + # # set some things inherited from Makefile / command line @@ -265,7 +267,7 @@ if(NOT OPT_NET STREQUAL "") else() # NCM: use own copy of ncm_device, original one must be outcommented target_sources(${PROJECT} PRIVATE - src/net/tinyusb/ncm_device_simple.c + src/net/tinyusb/ncm_device.c ) endif() diff --git a/doc/lwIP-notes.adoc b/doc/lwIP-notes.adoc index 6210316e2..e2b49ba34 100755 --- a/doc/lwIP-notes.adoc +++ b/doc/lwIP-notes.adoc @@ -95,9 +95,11 @@ must be set on built). Good command line for measurement: ## Testing -Good test case is the following script: +Good test cases are the following command lines: for MSS in 90 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1459 1460 1500; do iperf -c 192.168.14.1 -e -i 1 -l 1024 -M $MSS; sleep 10; done + + for LEN in 40000 16000 1400 1024 800 200 80 22 8 2 1; do for MSS in 90 93 100 150 200 255 256 300 400 500 511 512 600 700 800 900 1000 1100 1200 1300 1400 1450 1459 1460 1500; do iperf -c 192.168.14.1 -e -i 1 -l $LEN -M $MSS; sleep 2; done; done Monitor performance/errors with Wireshark. diff --git a/src/net/tinyusb/ncm.h b/src/net/tinyusb/ncm.h index 672b4f48b..fc0efcade 100755 --- a/src/net/tinyusb/ncm.h +++ b/src/net/tinyusb/ncm.h @@ -40,7 +40,7 @@ #endif #ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB - #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 1 // TODO should be 8 or so + #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 // TODO should be 8 or so #endif #ifndef CFG_TUD_NCM_ALIGNMENT diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index dd2883d03..29a50dda6 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -401,7 +401,7 @@ static void ncm_report(void) * called on init */ { - //printf("ncm_report - %d\n", ncm_interface.report_state); + printf("ncm_report - %d\n", ncm_interface.report_state); uint8_t const rhport = 0; if (ncm_interface.report_state == REPORT_SPEED) { ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; @@ -529,18 +529,25 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ /* data transmission finished */ if (ep_addr == ncm_interface.ep_in) { - //printf(" EP_IN %d %d %d\n", ncm_interface.xmt_running, ncm_interface.datagram_count, - //ncm_interface.itf_data_alt); + //printf(" EP_IN %d %d %d\n", ncm_interface.xmt_running, ncm_interface.datagram_count, ncm_interface.itf_data_alt); ncm_interface.xmt_running = false; - // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now - if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { - ncm_start_tx(); + if (xferred_bytes != 0 && xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE == 0) + { + // TODO check when ZLP is really needed + ncm_interface.xmt_running = true; + usbd_edpt_xfer(0, ncm_interface.ep_in, NULL, 0); + } + else { + // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now + if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { + ncm_start_tx(); + } } } if (ep_addr == ncm_interface.ep_notif) { - //printf(" EP_NOTIF\n"); + printf(" EP_NOTIF\n"); ncm_interface.report_pending = false; ncm_report(); } @@ -562,7 +569,7 @@ bool tud_network_can_xmit(uint16_t size) #if 0 printf("tud_network_can_xmit(%d) %d %d - %d %d [%p]\n", size, ncm_interface.datagram_count, ncm_interface.max_datagrams_per_ntb, - next_datagram_offset, ncm_interface.ntb_in_size, xTaskGetCurrentTaskHandle()); + ncm_interface.next_datagram_offset, ncm_interface.ntb_in_size, xTaskGetCurrentTaskHandle()); #endif if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 08eba78e2..7c2adba80 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -468,7 +468,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ /* data transmission finished */ if (ep_addr == ncm_interface.ep_in) { //printf(" EP_IN %d %d\n", ncm_interface.can_xmit, ncm_interface.itf_data_alt); - if (xferred_bytes != 0 && xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE == 0) + if (xferred_bytes != 0 && xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE == 0) { // TODO check when ZLP is really needed do_in_xfer(NULL, 0); /* a ZLP is needed */ From b6cbfda76cc819f775874ea401e3c84e37360ad2 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sat, 1 Jul 2023 10:54:33 +0200 Subject: [PATCH 38/64] remove original ncm_device.c from build list --- CMakeLists.txt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66c1ba969..4a0e6b169 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,8 +61,6 @@ pico_sdk_init() # message("--------- " ${PICO_LWIP_PATH}) # message("--------- " ${PICO_LWIP_CONTRIB_PATH}) # message("--------- " ${PICO_TINYUSB_PATH}) -message("---------" ${tinyusb_device_base}) - # # set some things inherited from Makefile / command line @@ -259,15 +257,20 @@ if(NOT OPT_NET STREQUAL "") ${PICO_TINYUSB_PATH}/lib/networking/dhserver.c ) - if(NOT OPT_NET STREQUAL "NCM") - # !NCM + if(OPT_NET STREQUAL "NCM") + # NCM: use own copy of ncm_device, original one is removed from target_sources() with a trick + message("--------- " ${PICO_TINYUSB_PATH}) target_sources(${PROJECT} PRIVATE - ${PICO_TINYUSB_PATH}/lib/networking/rndis_reports.c + src/net/tinyusb/ncm_device.c + ) + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/class/net/ncm_device.c + PROPERTIES HEADER_FILE_ONLY ON ) else() - # NCM: use own copy of ncm_device, original one must be outcommented + # !NCM target_sources(${PROJECT} PRIVATE - src/net/tinyusb/ncm_device.c + ${PICO_TINYUSB_PATH}/lib/networking/rndis_reports.c ) endif() From fe1a9b3b6a128355f8e9232414be0c45c122f016 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sat, 1 Jul 2023 21:37:25 +0200 Subject: [PATCH 39/64] input/output buffer --- src/net/tinyusb/ncm_device.c | 10 +++++----- src/net/tinyusb/ncm_device_simple.c | 18 +++++++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index 29a50dda6..bb540c2ed 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -55,7 +55,7 @@ typedef struct { const ndp16_t *rcv_ndp; uint8_t rcv_datagram_num; uint8_t rcv_datagram_index; - CFG_TUSB_MEM_ALIGN uint8_t rcv_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; + CFG_TUSB_MEM_ALIGN uint8_t rcv_datagram[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; uint16_t rcv_usb_datagram_size; enum { @@ -82,7 +82,7 @@ typedef struct { CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { .wLength = sizeof(ntb_parameters_t), .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported - .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE+400, + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, .wNdbInDivisor = 4, .wNdbInPayloadRemainder = 0, .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, @@ -91,7 +91,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 1 // 0=no limit TODO set to 0 + .wNtbOutMaxDatagrams = 0 // 0=no limit TODO set to 0 }; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; @@ -201,7 +201,7 @@ void tud_network_recv_renew(void) return; } else { - bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_datagram, sizeof(ncm_interface.rcv_datagram)); + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_datagram, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); if ( !r) { printf("--0.2\n"); return; @@ -523,7 +523,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ /* new datagram rcv_datagram */ if (ep_addr == ncm_interface.ep_out) { - //printf(" EP_OUT\n"); + printf(" EP_OUT %d %d %d %lu\n", rhport, ep_addr, result, xferred_bytes); handle_incoming_datagram(xferred_bytes); } diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 7c2adba80..0e2a993ef 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -39,8 +39,16 @@ #include "device/usbd.h" #include "device/usbd_pvt.h" -// TODO CFG_TUD_NCM_OUT_NTB_MAX_SIZE set correctly (it is too big currently) #include "net_device.h" + +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE (CFG_TUD_NET_MTU) +#endif + +#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE + #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (CFG_TUD_NET_MTU+200) +#endif + #include "ncm.h" //--------------------------------------------------------------------+ @@ -55,7 +63,7 @@ typedef struct { uint8_t ep_in; uint8_t ep_out; - CFG_TUSB_MEM_ALIGN uint8_t rcv_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE+400]; + CFG_TUSB_MEM_ALIGN uint8_t rcv_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; enum { REPORT_SPEED, @@ -76,7 +84,7 @@ typedef struct { CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { .wLength = sizeof(ntb_parameters_t), .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported - .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE+400, + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, .wNdbInDivisor = 4, .wNdbInPayloadRemainder = 0, .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, @@ -147,7 +155,7 @@ void tud_network_recv_renew(void) return; } else { - bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_ntb, sizeof(ncm_interface.rcv_ntb)); + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.rcv_ntb, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); if ( !r) { printf("--0.2\n"); return; @@ -461,7 +469,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ /* new datagram rcv_ntb */ if (ep_addr == ncm_interface.ep_out) { - //printf(" EP_OUT\n"); + //printf(" EP_OUT %d %d %d %lu\n", rhport, ep_addr, result, xferred_bytes); handle_incoming_datagram(xferred_bytes); } From 230eebb3236d20d02bbfee27e3feb3652a3ca815 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sat, 1 Jul 2023 21:51:25 +0200 Subject: [PATCH 40/64] now better --- src/net/tinyusb/ncm_device_simple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 0e2a993ef..d638b8edf 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -42,7 +42,7 @@ #include "net_device.h" #ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE - #define CFG_TUD_NCM_IN_NTB_MAX_SIZE (CFG_TUD_NET_MTU) + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE (CFG_TUD_NET_MTU+200) #endif #ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE @@ -93,7 +93,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 1 // 0=no limit TODO set to 0 + .wNtbOutMaxDatagrams = 1 // 0=no limit TODO set to 0 }; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb; From 28f3256b9f32e590a9fb04d9468765d76601a195 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sat, 1 Jul 2023 22:08:41 +0200 Subject: [PATCH 41/64] good version --- CMakeLists.txt | 6 +++--- src/net/net_sysview.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a0e6b169..9e09d15c8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -261,7 +261,7 @@ if(NOT OPT_NET STREQUAL "") # NCM: use own copy of ncm_device, original one is removed from target_sources() with a trick message("--------- " ${PICO_TINYUSB_PATH}) target_sources(${PROJECT} PRIVATE - src/net/tinyusb/ncm_device.c + src/net/tinyusb/ncm_device_simple.c ) set_source_files_properties( ${PICO_TINYUSB_PATH}/src/class/net/ncm_device.c @@ -337,8 +337,8 @@ pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/src/probe.pio) target_include_directories(${PROJECT} PRIVATE src) target_compile_definitions (${PROJECT} PRIVATE - #PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 - #PICO_RP2040_USB_DEVICE_UFRAME_FIX=1 + PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 + PICO_RP2040_USB_DEVICE_UFRAME_FIX=1 ) target_link_libraries(${PROJECT} PRIVATE diff --git a/src/net/net_sysview.c b/src/net/net_sysview.c index c30865ed8..a65ce00b3 100755 --- a/src/net/net_sysview.c +++ b/src/net/net_sysview.c @@ -137,7 +137,7 @@ static void sysview_try_send(void *ctx) sysview_close(m_pcb_client); } - if ( !block_call_to_tcp_output && tcp_sndbuf(m_pcb_client) < 3 * TCP_SND_BUF / 4) { + if ( !block_call_to_tcp_output && tcp_sndbuf(m_pcb_client) < 2 * TCP_SND_BUF / 4) { //printf("sysview_try_send: flush %d %d\n", tcp_sndbuf(m_pcb_client), 3 * TCP_SND_BUF / 4); block_call_to_tcp_output = true; tcp_output(m_pcb_client); @@ -149,7 +149,7 @@ static void sysview_try_send(void *ctx) } } else { - //printf("sysview_try_send: no tcp_sndbuf!!!!\n"); + printf("sysview_try_send: no tcp_sndbuf!!!!\n"); if ( !block_call_to_tcp_output) { printf("sysview_try_send: flush\n"); block_call_to_tcp_output = true; From 6f3fdaa93d307392720e7d42bca8eb74cc021253 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 6 Jul 2023 21:05:49 +0200 Subject: [PATCH 42/64] mini build fix --- src/get_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/get_config.h b/src/get_config.h index 6a7d94b22..866cfc71c 100644 --- a/src/get_config.h +++ b/src/get_config.h @@ -80,6 +80,7 @@ #endif #else #define __OPT_NET + #define __OPT_NET_CONF "" #endif #if OPT_NET_SYSVIEW_SERVER #define __OPT_NET_SYSVIEW_SERVER " [Net: SysView]" From a18f9cb1bf4d264a1dd2b9d01181059c1ccdd1ae Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 11:31:26 +0200 Subject: [PATCH 43/64] minor --- src/get_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/get_config.h b/src/get_config.h index 866cfc71c..7a6c06701 100644 --- a/src/get_config.h +++ b/src/get_config.h @@ -102,7 +102,7 @@ /** * CONFIG_FEATURES */ -#define CONFIG_FEATURES() __OPT_CMSIS_DAPV1 __OPT_CMSIS_DAPV2 __OPT_MSC __OPT_TARGET_UART __OPT_TARGET_UART \ +#define CONFIG_FEATURES() __OPT_CMSIS_DAPV1 __OPT_CMSIS_DAPV2 __OPT_MSC __OPT_TARGET_UART __OPT_SIGROK \ __OPT_PROBE_DEBUG_OUT __OPT_CDC_SYSVIEW \ __OPT_NET_CONF __OPT_NET_SYSVIEW_SERVER __OPT_NET_ECHO_SERVER __OPT_NET_IPERF_SERVER From cf0f5892b7cccd69e3b69e24373b9c7c6ddaec06 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 14:17:02 +0200 Subject: [PATCH 44/64] Issue #57 is now understood --- CMakeLists.txt | 6 +++--- src/main.c | 21 +++++++++++---------- src/rtt_console.c | 39 ++++++++++++++++++++++++--------------- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e09d15c8..8ef58af3b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,14 +24,14 @@ else() set(DEFAULT_OPT_PROBE_DEBUG_OUT 1) endif() -option(OPT_CMSIS_DAPV1 "Enable CMSIS-DAPv1" 0) +option(OPT_CMSIS_DAPV1 "Enable CMSIS-DAPv1" 1) option(OPT_CMSIS_DAPV2 "Enable CMSIS-DAPv2" 1) option(OPT_TARGET_UART "Enable CDC for target UART I/O" 1) option(OPT_PROBE_DEBUG_OUT "Enable CDC for probe debug output" ${DEFAULT_OPT_PROBE_DEBUG_OUT}) option(OPT_SIGROK "Enable sigrok" 0) -option(OPT_MSC "Enable Mass Storage Device" 0) +option(OPT_MSC "Enable Mass Storage Device" 1) option(OPT_MSC_RAM_UF2 "Enable file 'RAM.UF2' on Mass Storage" 1) -set(OPT_NET "NCM" CACHE STRING "Enable lwIP on the Pico via ECM/NCM/RNDIS") +set(OPT_NET "NCM" CACHE STRING "Enable lwIP on the Pico via ECM/NCM/RNDIS, disable NET with empty string") set(OPT_NET_192_168 14 CACHE STRING "Set the subnet of 192.168.x") option(OPT_NET_ECHO_SERVER "Enable echo server for testing" 1) option(OPT_NET_IPERF_SERVER "Enable iperf server for tuning" 1) diff --git a/src/main.c b/src/main.c index 4575e6802..1fd76a10a 100644 --- a/src/main.c +++ b/src/main.c @@ -118,19 +118,20 @@ static uint8_t RxDataBuffer[_DAP_PACKET_COUNT_OPENOCD * CFG_TUD_VENDOR_RX_BUFSIZ // prios are critical and determine throughput // there is one more task prio in lwipopts.h +#define PRINT_STATUS_TASK_PRIO (tskIDLE_PRIORITY + 30) // high prio to get status output in (almost) any case #define TUD_TASK_PRIO (tskIDLE_PRIORITY + 20) // uses one core continuously (no longer valid with FreeRTOS usage) #define LED_TASK_PRIO (tskIDLE_PRIORITY + 12) // simple task which may interrupt everything else for periodic blinking #define SIGROK_TASK_PRIO (tskIDLE_PRIORITY + 9) // Sigrok digital/analog signals (does nothing at the moment) #define MSC_WRITER_THREAD_PRIO (tskIDLE_PRIORITY + 8) // this is only running on writing UF2 files #define SYSVIEW_TASK_PRIO (tskIDLE_PRIORITY + 6) // target -> host via SysView #define UART_TASK_PRIO (tskIDLE_PRIORITY + 5) // target -> host via UART -#define RTT_CONSOLE_TASK_PRIO (tskIDLE_PRIORITY + 4) // target -> host via RTT #define CDC_DEBUG_TASK_PRIO (tskIDLE_PRIORITY + 4) // probe debugging output -#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 2) // DAP execution, during connection this takes the other core +#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 3) // DAP execution, during connection this takes the other core +#define RTT_CONSOLE_TASK_PRIO (tskIDLE_PRIORITY + 1) // target -> host via RTT, ATTENTION: this task can fully load the CPU static TaskHandle_t tud_taskhandle; static TaskHandle_t dap_taskhandle; -static EventGroupHandle_t events; +static EventGroupHandle_t dap_events; @@ -224,7 +225,7 @@ void tud_cdc_tx_complete_cb(uint8_t itf) void tud_vendor_rx_cb(uint8_t itf) { if (itf == 0) { - xEventGroupSetBits(events, 0x01); + xEventGroupSetBits(dap_events, 0x01); } } // tud_vendor_rx_cb #endif @@ -272,7 +273,7 @@ void dap_task(void *ptr) tool = DAP_FingerprintTool(NULL, 0); } - xEventGroupWaitBits(events, 0x01, pdTRUE, pdFALSE, pdMS_TO_TICKS(100)); // TODO "pyocd reset -f 500000" does otherwise not disconnect + xEventGroupWaitBits(dap_events, 0x01, pdTRUE, pdFALSE, pdMS_TO_TICKS(100)); // TODO "pyocd reset -f 500000" does otherwise not disconnect if (tud_vendor_available()) { @@ -306,7 +307,7 @@ void dap_task(void *ptr) // // initiate SWD connect / disconnect // - if ( !swd_connected && RxDataBuffer[0] == ID_DAP_Connect) { + if ( !swd_connected && RxDataBuffer[0] != ID_DAP_Info) { if (sw_lock("DAPv2", true)) { swd_connected = true; picoprobe_info("=================================== DAPv2 connect target, host %s\n", @@ -539,13 +540,13 @@ void usb_thread(void *ptr) #endif #if OPT_CMSIS_DAPV2 - xTaskCreate(dap_task, "CMSIS-DAP", configMINIMAL_STACK_SIZE, NULL, DAP_TASK_PRIO, &dap_taskhandle); + xTaskCreate(dap_task, "CMSIS-DAPv2", configMINIMAL_STACK_SIZE, NULL, DAP_TASK_PRIO, &dap_taskhandle); #endif #if configGENERATE_RUN_TIME_STATS { TaskHandle_t task_stat_handle; - xTaskCreate(print_task_stat, "Print Task Stat", configMINIMAL_STACK_SIZE, NULL, 30, &task_stat_handle); + xTaskCreate(print_task_stat, "Print Task Stat", configMINIMAL_STACK_SIZE, NULL, PRINT_STATUS_TASK_PRIO, &task_stat_handle); } #endif @@ -623,7 +624,7 @@ int main(void) picoprobe_info(" %s\n", CONFIG_BOARD()); picoprobe_info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); - events = xEventGroupCreate(); + dap_events = xEventGroupCreate(); // it seems that TinyUSB does not like affinity setting in its thread, so the affinity of the USB thread is corrected in the task itself xTaskCreate(usb_thread, "TinyUSB Main", 4096, NULL, TUD_TASK_PRIO, &tud_taskhandle); @@ -690,7 +691,7 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep // // initiate SWD connect / disconnect // - if ( !hid_swd_connected && RxDataBuffer[0] == ID_DAP_Connect) { + if ( !hid_swd_connected && RxDataBuffer[0] != ID_DAP_Info) { if (sw_lock("DAPv1", true)) { hid_swd_connected = true; picoprobe_info("=================================== DAPv1 connect target\n"); diff --git a/src/rtt_console.c b/src/rtt_console.c index 0e6dc3eb7..b783c14c0 100755 --- a/src/rtt_console.c +++ b/src/rtt_console.c @@ -241,7 +241,12 @@ static void rtt_from_target_thread(void *) */ { for (;;) { - xEventGroupWaitBits(events, EV_RTT_FROM_TARGET_STRT, pdTRUE, pdFALSE, portMAX_DELAY); + EventBits_t ev; + + ev = xEventGroupWaitBits(events, EV_RTT_FROM_TARGET_STRT, pdTRUE, pdFALSE, portMAX_DELAY); + if (ev == 0) { + continue; + } ft_ok = swd_read_word(ft_rtt_cb + offsetof(SEGGER_RTT_CB, aUp[ft_channel].WrOff), (uint32_t *)&(ft_aUp->WrOff)); @@ -281,6 +286,7 @@ static bool rtt_from_target(uint32_t rtt_cb, uint16_t channel, SEGGER_RTT_BUFFER ft_cnt = data_to_host(NULL, 0); if (ft_cnt < sizeof(ft_buf) / 4) { //printf("no space in stream %d: %d\n", channel, ft_cnt); + *worked = true; } else { ft_aUp = aUp; @@ -291,7 +297,7 @@ static bool rtt_from_target(uint32_t rtt_cb, uint16_t channel, SEGGER_RTT_BUFFER xEventGroupWaitBits(events, EV_RTT_FROM_TARGET_END, pdTRUE, pdFALSE, portMAX_DELAY); if (ft_cnt != 0) { - // direct received data to host + // redirect received data to host data_to_host(ft_buf, ft_cnt); led_state(LS_RTT_RX_DATA); @@ -312,9 +318,9 @@ static bool rtt_from_target(uint32_t rtt_cb, uint16_t channel, SEGGER_RTT_BUFFER //*worked = true; } else { - ft_aUp = aUp; - ft_channel = channel; - ft_rtt_cb = rtt_cb; +// ft_aUp = aUp; +// ft_channel = channel; +// ft_rtt_cb = rtt_cb; xEventGroupSetBits(events, EV_RTT_FROM_TARGET_STRT); xEventGroupWaitBits(events, EV_RTT_FROM_TARGET_END, pdTRUE, pdFALSE, portMAX_DELAY); @@ -444,24 +450,24 @@ static void do_rtt_io(uint32_t rtt_cb) #if OPT_TARGET_UART { - static bool worked_uart = false; + static bool working_uart = false; static TickType_t lastTimeWorked; - if ( !worked_uart && xTaskGetTickCount() - lastTimeWorked < pdMS_TO_TICKS(RTT_CONSOLE_POLL_INT_MS)) { + if ( !working_uart && xTaskGetTickCount() - lastTimeWorked < pdMS_TO_TICKS(RTT_CONSOLE_POLL_INT_MS)) { // // pause console IO for a longer time to let SysView the interface // } else { - worked_uart = false; + working_uart = false; if (ok_console_from_target) - ok = ok && rtt_from_target(rtt_cb, RTT_CHANNEL_CONSOLE, &aUpConsole, cdc_uart_write, &worked_uart); + ok = ok && rtt_from_target(rtt_cb, RTT_CHANNEL_CONSOLE, &aUpConsole, cdc_uart_write, &working_uart); if (ok_console_to_target) - ok = ok && rtt_to_target(rtt_cb, stream_rtt_console_to_target, RTT_CHANNEL_CONSOLE, &aDownConsole, &worked_uart); + ok = ok && rtt_to_target(rtt_cb, stream_rtt_console_to_target, RTT_CHANNEL_CONSOLE, &aDownConsole, &working_uart); - probe_rtt_cb = probe_rtt_cb && !worked_uart; + probe_rtt_cb = probe_rtt_cb && !working_uart; lastTimeWorked = xTaskGetTickCount(); } @@ -470,18 +476,19 @@ static void do_rtt_io(uint32_t rtt_cb) #if INCLUDE_SYSVIEW { - bool worked_sysview = false; + bool working_sysview = false; if (ok_sysview_from_target) - ok = ok && rtt_from_target(rtt_cb, RTT_CHANNEL_SYSVIEW, &aUpSysView, net_sysview_send, &worked_sysview); + ok = ok && rtt_from_target(rtt_cb, RTT_CHANNEL_SYSVIEW, &aUpSysView, net_sysview_send, &working_sysview); if (ok_sysview_to_target) - ok = ok && rtt_to_target(rtt_cb, stream_rtt_sysview_to_target, RTT_CHANNEL_SYSVIEW, &aDownSysView, &worked_sysview); + ok = ok && rtt_to_target(rtt_cb, stream_rtt_sysview_to_target, RTT_CHANNEL_SYSVIEW, &aDownSysView, &working_sysview); - probe_rtt_cb = probe_rtt_cb && !worked_sysview; + probe_rtt_cb = probe_rtt_cb && !working_sysview; } #endif + //printf("%d %d\n", ok, probe_rtt_cb); if (ok && probe_rtt_cb) { // did nothing -> check if RTT channels appeared #if OPT_TARGET_UART @@ -667,9 +674,11 @@ void rtt_console_init(uint32_t task_prio) picoprobe_error("rtt_console_init: cannot create task_rtt_console\n"); } +#ifdef USE_EXTRA_THREAD_FOR_FROM_TARGET xTaskCreate(rtt_from_target_thread, "RTT_FROM", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_rtt_from_target_thread); if (task_rtt_from_target_thread == NULL) { picoprobe_error("rtt_console_init: cannot create task_rtt_from_target_thread\n"); } +#endif } // rtt_console_init From 698a0a1b7feb4b50ffb35a9b96e2234db930e089 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 17:58:06 +0200 Subject: [PATCH 45/64] removed old code --- src/rtt_console.c | 68 +++++------------------------------------------ 1 file changed, 6 insertions(+), 62 deletions(-) diff --git a/src/rtt_console.c b/src/rtt_console.c index b783c14c0..60af9450b 100755 --- a/src/rtt_console.c +++ b/src/rtt_console.c @@ -222,10 +222,6 @@ static unsigned rtt_get_write_space(SEGGER_RTT_BUFFER_DOWN *pRing) -#define USE_EXTRA_THREAD_FOR_FROM_TARGET - -#ifdef USE_EXTRA_THREAD_FOR_FROM_TARGET - static SEGGER_RTT_BUFFER_UP *ft_aUp; static uint16_t ft_channel; static uint32_t ft_rtt_cb; @@ -235,6 +231,7 @@ static bool ft_ok; static void rtt_from_target_thread(void *) /** + * Fetch RTT data from target. * Data transfer is CPU intensive, because SWD access is blocking the CPU. * So the idea is to put this task in an extra thread with affinity to the second core. * Core affinity is set in \a main.c @@ -275,14 +272,11 @@ static void rtt_from_target_thread(void *) } } // rtt_from_target_thread -#endif - static bool rtt_from_target(uint32_t rtt_cb, uint16_t channel, SEGGER_RTT_BUFFER_UP *aUp, rtt_data_to_host data_to_host, bool *worked) { -#ifdef USE_EXTRA_THREAD_FOR_FROM_TARGET ft_cnt = data_to_host(NULL, 0); if (ft_cnt < sizeof(ft_buf) / 4) { //printf("no space in stream %d: %d\n", channel, ft_cnt); @@ -305,54 +299,6 @@ static bool rtt_from_target(uint32_t rtt_cb, uint16_t channel, SEGGER_RTT_BUFFER } } return ft_ok; -#else - bool ok = true; - uint8_t buf[256]; - uint32_t cnt; - - assert(data_to_host != NULL); - - cnt = data_to_host(NULL, 0); - if (cnt < sizeof(buf) / 4) { - //printf("no space in stream %d: %d\n", channel, cnt); - //*worked = true; - } - else { -// ft_aUp = aUp; -// ft_channel = channel; -// ft_rtt_cb = rtt_cb; - - xEventGroupSetBits(events, EV_RTT_FROM_TARGET_STRT); - xEventGroupWaitBits(events, EV_RTT_FROM_TARGET_END, pdTRUE, pdFALSE, portMAX_DELAY); - - ok = ok && swd_read_word(rtt_cb + offsetof(SEGGER_RTT_CB, aUp[channel].WrOff), (uint32_t *)&(aUp->WrOff)); - - if (ok && aUp->WrOff != aUp->RdOff) { - // - // fetch data from target - // - if (aUp->WrOff > aUp->RdOff) { - cnt = MIN(cnt, aUp->WrOff - aUp->RdOff); - } - else { - cnt = MIN(cnt, aUp->SizeOfBuffer - aUp->RdOff); - } - cnt = MIN(cnt, sizeof(buf)); - - memset(buf, 0, sizeof(buf)); - ok = ok && swd_read_memory((uint32_t)aUp->pBuffer + aUp->RdOff, buf, cnt); - aUp->RdOff = (aUp->RdOff + cnt) % aUp->SizeOfBuffer; - ok = ok && swd_write_word(rtt_cb + offsetof(SEGGER_RTT_CB, aUp[channel].RdOff), aUp->RdOff); - - // direct received data to host - data_to_host(buf, cnt); - - led_state(LS_RTT_RX_DATA); - *worked = true; - } - } - return ok; -#endif } // rtt_from_target @@ -475,7 +421,7 @@ static void do_rtt_io(uint32_t rtt_cb) #endif #if INCLUDE_SYSVIEW - { + if (net_sysview_is_connected()) { bool working_sysview = false; if (ok_sysview_from_target) @@ -545,7 +491,7 @@ void rtt_io_thread(void *ptr) bool target_online = false; for (;;) { - sw_lock("RTT", false); + sw_lock("RTT-IO", false); // post: we have the interface if ( !target_online) { @@ -592,7 +538,7 @@ void rtt_io_thread(void *ptr) target_disconnect(); vTaskDelay(pdMS_TO_TICKS(200)); // some guard time after disconnect } - sw_unlock("RTT"); + sw_unlock("RTT-IO"); vTaskDelay(pdMS_TO_TICKS(300)); // give the other task the opportunity to catch sw_lock(); } } // rtt_io_thread @@ -668,17 +614,15 @@ void rtt_console_init(uint32_t task_prio) } #endif - xTaskCreate(rtt_io_thread, "RTT", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_rtt_console); + xTaskCreate(rtt_io_thread, "RTT-IO", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_rtt_console); if (task_rtt_console == NULL) { picoprobe_error("rtt_console_init: cannot create task_rtt_console\n"); } -#ifdef USE_EXTRA_THREAD_FOR_FROM_TARGET - xTaskCreate(rtt_from_target_thread, "RTT_FROM", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_rtt_from_target_thread); + xTaskCreate(rtt_from_target_thread, "RTT-From", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_rtt_from_target_thread); if (task_rtt_from_target_thread == NULL) { picoprobe_error("rtt_console_init: cannot create task_rtt_from_target_thread\n"); } -#endif } // rtt_console_init From 588b8db66bc065f6e49e1d6aa93d0f5f1428d8e8 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 17:58:40 +0200 Subject: [PATCH 46/64] updated udev rules for sysview --- README.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/README.adoc b/README.adoc index cc3751708..65e37496b 100644 --- a/README.adoc +++ b/README.adoc @@ -371,6 +371,7 @@ SUBSYSTEM=="usb", ATTR{idVendor}=="2e8a", ATTR{idProduct}=="000c", MODE:="0666" ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="ttyACM[0-9]*", ATTRS{interface}=="YAPicoprobe CDC-UART", MODE:="0666", SYMLINK+="ttyPicoTarget" ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="ttyACM[0-9]*", ATTRS{interface}=="YAPicoprobe CDC-DEBUG", MODE:="0666", SYMLINK+="ttyPicoProbe" ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="ttyACM[0-9]*", ATTRS{interface}=="YAPicoprobe CDC-SIGROK", MODE:="0666", SYMLINK+="ttyPicoSigRok +ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="ttyACM[0-9]*", ATTRS{interface}=="YAPicoprobe CDC-SysView", MODE:="0666", SYMLINK+="ttyPicoSysView" # mount Picoprobe to /media/picoprobe ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", RUN+="/usr/bin/logger --tag picoprobe-mount Mounting what seems to be a Raspberry Pi Picoprobe", RUN+="/usr/bin/systemd-mount --no-block --collect --fsck=0 -o uid=hardy,gid=hardy,flush $devnode /media/picoprobe" From 52182d983dd2a9dad4368c4d90c0ae3d9b39c658 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 18:00:14 +0200 Subject: [PATCH 47/64] lot of minor fine-tuning (now again compilable) --- src/cdc/cdc_debug.c | 2 +- src/cdc/cdc_sysview.c | 13 ++++++++--- src/cdc/cdc_sysview.h | 14 ++++++------ src/cdc/cdc_uart.c | 2 +- src/main.c | 34 ++++++++++++++--------------- src/net/net_sysview.c | 11 ++++++++-- src/net/net_sysview.h | 2 +- src/net/tinyusb/ncm_device.c | 4 ++-- src/net/tinyusb/ncm_device_simple.c | 4 ++-- 9 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/cdc/cdc_debug.c b/src/cdc/cdc_debug.c index aed740bf5..d8225b113 100644 --- a/src/cdc/cdc_debug.c +++ b/src/cdc/cdc_debug.c @@ -255,7 +255,7 @@ void cdc_debug_init(uint32_t task_prio) panic("cdc_debug_init: cannot create sema_printf\n"); } - xTaskCreate(cdc_debug_thread, "CDC_DEBUG", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_printf); + xTaskCreate(cdc_debug_thread, "CDC-ProbeUart", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_printf); cdc_debug_line_state_cb(false, false); stdio_set_driver_enabled(&stdio_cdc, true); diff --git a/src/cdc/cdc_sysview.c b/src/cdc/cdc_sysview.c index 1ba7049e1..661ee9156 100755 --- a/src/cdc/cdc_sysview.c +++ b/src/cdc/cdc_sysview.c @@ -144,7 +144,7 @@ void cdc_sysview_line_state_cb(bool dtr, bool rts) * This seems to be necessary to survive e.g. a restart of the host (Linux) */ { - printf("cdc_sysview_line_state_cb(%d,%d)\n", dtr, rts); + //printf("cdc_sysview_line_state_cb(%d,%d)\n", dtr, rts); tud_cdc_n_write_clear(CDC_SYSVIEW_N); tud_cdc_n_read_flush(CDC_SYSVIEW_N); @@ -171,6 +171,13 @@ void cdc_sysview_rx_cb() +bool net_sysview_is_connected(void) +{ + return m_connected; +} // net_sysview_is_connected + + + uint32_t net_sysview_send(const uint8_t *buf, uint32_t cnt) /** * Send characters from SysView RTT channel into stream. @@ -188,7 +195,7 @@ uint32_t net_sysview_send(const uint8_t *buf, uint32_t cnt) r = xStreamBufferSpacesAvailable(stream_sysview); } else { - if ( !m_connected) { + if ( !net_sysview_is_connected()) { xStreamBufferReset(stream_sysview); } else { @@ -212,6 +219,6 @@ void cdc_sysview_init(uint32_t task_prio) picoprobe_error("cdc_sysview_init: cannot create stream_sysview\n"); } - xTaskCreate(cdc_thread, "CDC_SysView", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_sysview); + xTaskCreate(cdc_thread, "CDC-SysViewUart", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_sysview); cdc_sysview_line_state_cb(false, false); } // cdc_sysview_init diff --git a/src/cdc/cdc_sysview.h b/src/cdc/cdc_sysview.h index eee62eed4..eb1c6525e 100755 --- a/src/cdc/cdc_sysview.h +++ b/src/cdc/cdc_sysview.h @@ -30,13 +30,13 @@ #include #include "tusb.h" -#if OPT_CDC_SYSVIEW - uint32_t net_sysview_send(const uint8_t *buf, uint32_t cnt); - void cdc_sysview_init(uint32_t task_prio); +void cdc_sysview_init(uint32_t task_prio); - void cdc_sysview_line_state_cb(bool dtr, bool rts); - void cdc_sysview_tx_complete_cb(void); - void cdc_sysview_rx_cb(void); -#endif +uint32_t net_sysview_send(const uint8_t *buf, uint32_t cnt); +bool net_sysview_is_connected(void); + +void cdc_sysview_line_state_cb(bool dtr, bool rts); +void cdc_sysview_tx_complete_cb(void); +void cdc_sysview_rx_cb(void); #endif diff --git a/src/cdc/cdc_uart.c b/src/cdc/cdc_uart.c index ad6b35a9a..447b562c8 100644 --- a/src/cdc/cdc_uart.c +++ b/src/cdc/cdc_uart.c @@ -332,6 +332,6 @@ void cdc_uart_init(uint32_t task_prio) uart_set_irq_enables(PICOPROBE_UART_INTERFACE, true, false); /* UART needs to preempt USB as if we don't, characters get lost */ - xTaskCreate(cdc_thread, "CDC_UART", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_uart); + xTaskCreate(cdc_thread, "CDC-TargetUart", configMINIMAL_STACK_SIZE, NULL, task_prio, &task_uart); cdc_uart_line_state_cb(false, false); } // cdc_uart_init diff --git a/src/main.c b/src/main.c index 1fd76a10a..1f1c7b528 100644 --- a/src/main.c +++ b/src/main.c @@ -387,7 +387,7 @@ void print_task_stat(void *ptr) TaskStatus_t task_status[TASK_MAX_CNT]; uint32_t total_run_time; - vTaskDelay(pdMS_TO_TICKS(100)); + vTaskDelay(pdMS_TO_TICKS(5000)); timer_task_stat = xTimerCreate("task stat", pdMS_TO_TICKS(10000), pdTRUE, NULL, trigger_task_stat); // just for fun: exact period of 10s events_task_stat = xEventGroupCreate(); @@ -414,8 +414,8 @@ void print_task_stat(void *ptr) static uint32_t total_sum_tick_ms; uint32_t cnt; uint32_t all_delta_tick_sum_us; - uint32_t percent_sum; - uint32_t percent_total_sum; + uint32_t permille_sum; + uint32_t permille_total_sum; cnt = uxTaskGetSystemState(task_status, TASK_MAX_CNT, &total_run_time); all_delta_tick_sum_us = 0; @@ -436,11 +436,11 @@ void print_task_stat(void *ptr) all_delta_tick_sum_us /= configNUM_CORES; total_sum_tick_ms += (all_delta_tick_sum_us + 500) / 1000; - percent_sum = 0; - percent_total_sum = 0; + permille_sum = 0; + permille_total_sum = 0; for (uint32_t n = 0; n < cnt; ++n) { - uint32_t percent; - uint32_t percent_total; + uint32_t permille; + uint32_t permille_total; uint32_t curr_tick; uint32_t delta_tick; uint32_t task_ndx = task_status[n].xTaskNumber; @@ -448,17 +448,17 @@ void print_task_stat(void *ptr) curr_tick = task_status[n].ulRunTimeCounter; delta_tick = curr_tick - prev_tick_us[task_ndx]; - percent = (delta_tick + all_delta_tick_sum_us / 2000) / (all_delta_tick_sum_us / 1000); - percent_total = (1000 * sum_tick_ms[task_ndx] + total_sum_tick_ms / 2) / total_sum_tick_ms; - percent_sum += percent; - percent_total_sum += percent_total; + permille = (delta_tick + all_delta_tick_sum_us / 2000) / (all_delta_tick_sum_us / 1000); + permille_total = (sum_tick_ms[task_ndx] + total_sum_tick_ms / 2000) / (total_sum_tick_ms / 1000); + permille_sum += permille; + permille_total_sum += permille_total; #if defined(configUSE_CORE_AFFINITY) && configUSE_CORE_AFFINITY != 0 printf("%3lu %2lu %c/%2d %4lu %4lu %5lu %s\n", task_status[n].xTaskNumber, task_status[n].uxCurrentPriority, task_state(task_status[n].eCurrentState), (int)task_status[n].uxCoreAffinityMask, - percent, percent_total, + permille, permille_total, task_status[n].usStackHighWaterMark, task_status[n].pcTaskName); #else @@ -466,7 +466,7 @@ void print_task_stat(void *ptr) task_status[n].xTaskNumber, task_status[n].uxCurrentPriority, task_state(task_status[n].eCurrentState), 1, - percent, percent_total, + permille, permille_total, task_status[n].usStackHighWaterMark, task_status[n].pcTaskName); #endif @@ -474,7 +474,7 @@ void print_task_stat(void *ptr) prev_tick_us[task_ndx] = curr_tick; } printf("---------------------------------------\n"); - printf(" %4lu %4lu\n", percent_sum, percent_total_sum); + printf(" %4lu %4lu\n", permille_sum, permille_total_sum); } printf("---------------------------------------\n"); @@ -554,7 +554,7 @@ void usb_thread(void *ptr) // // This is the only place to set task affinity. // TODO ATTENTION core affinity - // Currently only RTT_FROM is running on an extra core (and RTT_FROM is a real hack). This is because + // Currently only "RTT-From" is running on an extra core (and "RTT-From" is a real hack). This is because // if RTT is running on a different thread than tinyusb/lwip (not sure), the probe is crashing very // fast on SystemView events in net_sysview_send() // @@ -570,8 +570,8 @@ void usb_thread(void *ptr) for (uint32_t n = 0; n < cnt; ++n) { if ( strcmp(task_status[n].pcTaskName, "IDLE1") == 0 - || strcmp(task_status[n].pcTaskName, "RTT_FROM") == 0 - || strcmp(task_status[n].pcTaskName, "RTTxxx") == 0 + || strcmp(task_status[n].pcTaskName, "RTT-From") == 0 + || strcmp(task_status[n].pcTaskName, "RTT-IO-Dont-Do-That") == 0 ) { // set it to core 1 vTaskCoreAffinitySet(task_status[n].xHandle, 1 << 1); diff --git a/src/net/net_sysview.c b/src/net/net_sysview.c index a65ce00b3..ce6217ed7 100755 --- a/src/net/net_sysview.c +++ b/src/net/net_sysview.c @@ -149,7 +149,7 @@ static void sysview_try_send(void *ctx) } } else { - printf("sysview_try_send: no tcp_sndbuf!!!!\n"); +// printf("sysview_try_send: no tcp_sndbuf!!!!\n"); if ( !block_call_to_tcp_output) { printf("sysview_try_send: flush\n"); block_call_to_tcp_output = true; @@ -286,6 +286,13 @@ static err_t sysview_accept(void *arg, struct tcp_pcb *newpcb, err_t err) +bool net_sysview_is_connected(void) +{ + return m_state == SVS_READY; +} // net_sysview_is_connected + + + uint32_t net_sysview_send(const uint8_t *buf, uint32_t cnt) /** * Send characters from SysView RTT channel into stream. @@ -306,7 +313,7 @@ uint32_t net_sysview_send(const uint8_t *buf, uint32_t cnt) r = xStreamBufferSpacesAvailable(stream_sysview_to_host); } else { - if (m_state != SVS_READY) + if ( !net_sysview_is_connected()) { xStreamBufferReset(stream_sysview_to_host); } diff --git a/src/net/net_sysview.h b/src/net/net_sysview.h index 1e53b4cd5..9b797bd00 100755 --- a/src/net/net_sysview.h +++ b/src/net/net_sysview.h @@ -34,7 +34,7 @@ void net_sysview_init(void); uint32_t net_sysview_send(const uint8_t *buf, uint32_t cnt); - +bool net_sysview_is_connected(void); #ifdef __cplusplus } diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index bb540c2ed..d729ce23c 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -91,7 +91,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 0 // 0=no limit TODO set to 0 + .wNtbOutMaxDatagrams = 0 // 0=no limit TODO set to 0 }; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; @@ -523,7 +523,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ /* new datagram rcv_datagram */ if (ep_addr == ncm_interface.ep_out) { - printf(" EP_OUT %d %d %d %lu\n", rhport, ep_addr, result, xferred_bytes); + //printf(" EP_OUT %d %d %d %lu\n", rhport, ep_addr, result, xferred_bytes); handle_incoming_datagram(xferred_bytes); } diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index d638b8edf..85786639b 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -137,8 +137,8 @@ tu_static struct ncm_notify_struct ncm_notify_speed_change = { .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wLength = 8, }, - .downlink = 1000000, - .uplink = 1000000, + .downlink = 10000000, + .uplink = 10000000, }; From 68b7fd8be5602eefad5b3f8ebf37fbdaf79370de Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 19:38:35 +0200 Subject: [PATCH 48/64] removed some debug output --- src/net/tinyusb/ncm_device_simple.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 85786639b..0e4598a8e 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -348,7 +348,7 @@ static void ncm_report(void) * called on init */ { - printf("ncm_report - %d\n", ncm_interface.report_state); +// printf("ncm_report - %d\n", ncm_interface.report_state); uint8_t const rhport = 0; if (ncm_interface.report_state == REPORT_SPEED) { ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; @@ -373,8 +373,7 @@ TU_ATTR_WEAK void tud_network_link_state_cb(bool state) * context: TinyUSB */ { - (void) state; - printf("tud_network_link_state_cb(%d) [%p]\n", state, xTaskGetCurrentTaskHandle()); +// printf("tud_network_link_state_cb(%d) [%p]\n", state, xTaskGetCurrentTaskHandle()); } @@ -388,7 +387,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t * context: TinyUSB */ { - printf("netd_control_xfer_cb(%d, %d, %p) [%p]\n", rhport, stage, request, xTaskGetCurrentTaskHandle()); +// printf("netd_control_xfer_cb(%d, %d, %p) [%p]\n", rhport, stage, request, xTaskGetCurrentTaskHandle()); if (stage != CONTROL_STAGE_SETUP) return true ; @@ -489,7 +488,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } if (ep_addr == ncm_interface.ep_notif) { - printf(" EP_NOTIF\n"); +// printf(" EP_NOTIF\n"); ncm_interface.report_pending = false; ncm_report(); } From ed13af06e550f4e79cf659d9171ccd8103383448 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 19:39:00 +0200 Subject: [PATCH 49/64] also show uptime --- src/main.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main.c b/src/main.c index 1f1c7b528..b52532378 100644 --- a/src/main.c +++ b/src/main.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "hardware/vreg.h" #include "bsp/board.h" @@ -118,16 +119,16 @@ static uint8_t RxDataBuffer[_DAP_PACKET_COUNT_OPENOCD * CFG_TUD_VENDOR_RX_BUFSIZ // prios are critical and determine throughput // there is one more task prio in lwipopts.h -#define PRINT_STATUS_TASK_PRIO (tskIDLE_PRIORITY + 30) // high prio to get status output in (almost) any case -#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 20) // uses one core continuously (no longer valid with FreeRTOS usage) +#define PRINT_STATUS_TASK_PRIO (tskIDLE_PRIORITY + 30) // high prio to get status output transferred in (almost) any case +#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 20) // high prio for TinyUSB #define LED_TASK_PRIO (tskIDLE_PRIORITY + 12) // simple task which may interrupt everything else for periodic blinking #define SIGROK_TASK_PRIO (tskIDLE_PRIORITY + 9) // Sigrok digital/analog signals (does nothing at the moment) #define MSC_WRITER_THREAD_PRIO (tskIDLE_PRIORITY + 8) // this is only running on writing UF2 files -#define SYSVIEW_TASK_PRIO (tskIDLE_PRIORITY + 6) // target -> host via SysView -#define UART_TASK_PRIO (tskIDLE_PRIORITY + 5) // target -> host via UART -#define CDC_DEBUG_TASK_PRIO (tskIDLE_PRIORITY + 4) // probe debugging output -#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 3) // DAP execution, during connection this takes the other core -#define RTT_CONSOLE_TASK_PRIO (tskIDLE_PRIORITY + 1) // target -> host via RTT, ATTENTION: this task can fully load the CPU +#define SYSVIEW_TASK_PRIO (tskIDLE_PRIORITY + 6) // target -> host via SysView (CDC) +#define UART_TASK_PRIO (tskIDLE_PRIORITY + 5) // target -> host via UART (CDC) +#define CDC_DEBUG_TASK_PRIO (tskIDLE_PRIORITY + 4) // probe debugging output (CDC) +#define DAPV2_TASK_PRIO (tskIDLE_PRIORITY + 3) // DAPv2 execution +#define RTT_CONSOLE_TASK_PRIO (tskIDLE_PRIORITY + 1) // target -> host via RTT, ATTENTION: this task can fully load the CPU depending on target RTT output static TaskHandle_t tud_taskhandle; static TaskHandle_t dap_taskhandle; @@ -428,6 +429,7 @@ void print_task_stat(void *ptr) all_delta_tick_sum_us += ticks_us; sum_tick_ms[task_ndx] += (ticks_us + 500) / 1000; } + printf("uptime [s] : %lu\n", clock() / CLOCKS_PER_SEC); printf("delta tick sum : %lu\n", all_delta_tick_sum_us); printf("NUM PRI S/AM CPU TOT STACK NAME\n"); @@ -540,7 +542,7 @@ void usb_thread(void *ptr) #endif #if OPT_CMSIS_DAPV2 - xTaskCreate(dap_task, "CMSIS-DAPv2", configMINIMAL_STACK_SIZE, NULL, DAP_TASK_PRIO, &dap_taskhandle); + xTaskCreate(dap_task, "CMSIS-DAPv2", configMINIMAL_STACK_SIZE, NULL, DAPV2_TASK_PRIO, &dap_taskhandle); #endif #if configGENERATE_RUN_TIME_STATS From 60a97e98f6a4a060e7d58693b381435786fe5c88 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 19:39:30 +0200 Subject: [PATCH 50/64] rtt_from_target_reset() on SysView connect --- src/rtt_console.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/rtt_console.c b/src/rtt_console.c index 60af9450b..e3887d939 100755 --- a/src/rtt_console.c +++ b/src/rtt_console.c @@ -87,8 +87,6 @@ static EventGroupHandle_t events; #define RTT_CHANNEL_SYSVIEW 1 #define RTT_POLL_INT_MS 1 // faster polling static StreamBufferHandle_t stream_rtt_sysview_to_target; // small stream for host->probe->target sysview communication - static bool ok_sysview_from_target = false; - static bool ok_sysview_to_target = false; #else #define RTT_POLL_INT_MS RTT_CONSOLE_POLL_INT_MS #endif @@ -274,6 +272,20 @@ static void rtt_from_target_thread(void *) +static void rtt_from_target_reset(uint32_t rtt_cb, uint16_t channel, SEGGER_RTT_BUFFER_UP *aUp) +/** + * Reset an upstream buffer. + */ +{ +// printf("rtt_from_target_reset(%lx,%d,%p)\n", rtt_cb, channel, aUp); + + swd_read_word(rtt_cb + offsetof(SEGGER_RTT_CB, aUp[channel].WrOff), (uint32_t *)&(aUp->WrOff)); + aUp->RdOff = aUp->WrOff; + swd_write_word(rtt_cb + offsetof(SEGGER_RTT_CB, aUp[channel].RdOff), aUp->RdOff); +} // rtt_from_target_reset + + + static bool rtt_from_target(uint32_t rtt_cb, uint16_t channel, SEGGER_RTT_BUFFER_UP *aUp, rtt_data_to_host data_to_host, bool *worked) { @@ -376,8 +388,9 @@ static void do_rtt_io(uint32_t rtt_cb) #if INCLUDE_SYSVIEW SEGGER_RTT_BUFFER_UP aUpSysView; // Up buffer, transferring information up from target via debug probe to host SEGGER_RTT_BUFFER_DOWN aDownSysView; // Down buffer, transferring information from host via debug probe to target - ok_sysview_from_target = false; - ok_sysview_to_target = false; + bool ok_sysview_from_target = false; + bool ok_sysview_to_target = false; + bool net_sysview_was_connected = false; #endif bool ok = true; @@ -424,6 +437,10 @@ static void do_rtt_io(uint32_t rtt_cb) if (net_sysview_is_connected()) { bool working_sysview = false; + if ( !net_sysview_was_connected) { + net_sysview_was_connected = true; + rtt_from_target_reset(rtt_cb, RTT_CHANNEL_SYSVIEW, &aUpSysView); + } if (ok_sysview_from_target) ok = ok && rtt_from_target(rtt_cb, RTT_CHANNEL_SYSVIEW, &aUpSysView, net_sysview_send, &working_sysview); @@ -432,6 +449,9 @@ static void do_rtt_io(uint32_t rtt_cb) probe_rtt_cb = probe_rtt_cb && !working_sysview; } + else { + net_sysview_was_connected = false; + } #endif //printf("%d %d\n", ok, probe_rtt_cb); From 0a1378491f140e3c0288bfc159e144aa0f8539e6 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 20:59:07 +0200 Subject: [PATCH 51/64] less debugging --- src/net/tinyusb/ncm_device_simple.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 0e4598a8e..1bc1b7ec0 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -259,7 +259,7 @@ void netd_init(void) * context: TinyUSB */ { - printf("netd_init() [%p]\n", xTaskGetCurrentTaskHandle()); +// printf("netd_init() [%p]\n", xTaskGetCurrentTaskHandle()); tu_memclr(&ncm_interface, sizeof(ncm_interface)); ncm_prepare_for_tx(); @@ -276,7 +276,7 @@ void netd_reset(uint8_t rhport) { (void) rhport; - printf("netd_reset(%d) [%p]\n", rhport, xTaskGetCurrentTaskHandle()); +// printf("netd_reset(%d) [%p]\n", rhport, xTaskGetCurrentTaskHandle()); netd_init(); } @@ -293,7 +293,7 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 // confirm interface hasn't already been allocated TU_ASSERT(0 == ncm_interface.ep_notif, 0); - printf("netd_open(%d,%p,%d) [%p]\n", rhport, itf_desc, max_len, xTaskGetCurrentTaskHandle()); +// printf("netd_open(%d,%p,%d) [%p]\n", rhport, itf_desc, max_len, xTaskGetCurrentTaskHandle()); //------------- Management Interface -------------// ncm_interface.itf_num = itf_desc->bInterfaceNumber; From 817da0e7905886b12697aa8619425b1e8041e791 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 20:59:39 +0200 Subject: [PATCH 52/64] cosmetic changes --- src/rtt_console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rtt_console.c b/src/rtt_console.c index e3887d939..9017e3c5a 100755 --- a/src/rtt_console.c +++ b/src/rtt_console.c @@ -172,7 +172,7 @@ static bool rtt_check_channel_from_target(uint32_t rtt_cb, uint16_t channel, SEG ok = ok && (aUp->SizeOfBuffer > 0 && aUp->SizeOfBuffer < TARGET_RAM_END - TARGET_RAM_START); ok = ok && ((uint32_t)aUp->pBuffer >= TARGET_RAM_START && (uint32_t)aUp->pBuffer + aUp->SizeOfBuffer <= TARGET_RAM_END); if (ok) { - picoprobe_info("rtt_check_channel_from_target: %u %p %u %u %u\n", channel, aUp->pBuffer, aUp->SizeOfBuffer, aUp->RdOff, aUp->WrOff); + picoprobe_info("rtt_check_channel_from_target: %u %p %4u %4u %4u\n", channel, aUp->pBuffer, aUp->SizeOfBuffer, aUp->RdOff, aUp->WrOff); } return ok; } // rtt_check_channel_from_target @@ -191,7 +191,7 @@ static bool rtt_check_channel_to_target(uint32_t rtt_cb, uint16_t channel, SEGGE ok = ok && (aDown->SizeOfBuffer > 0 && aDown->SizeOfBuffer < TARGET_RAM_END - TARGET_RAM_START); ok = ok && ((uint32_t)aDown->pBuffer >= TARGET_RAM_START && (uint32_t)aDown->pBuffer + aDown->SizeOfBuffer <= TARGET_RAM_END); if (ok) { - picoprobe_info("rtt_check_channel_to_target: %u %p %u %u %u\n", channel, aDown->pBuffer, aDown->SizeOfBuffer, aDown->RdOff, aDown->WrOff); + picoprobe_info("rtt_check_channel_to_target : %u %p %4u %4u %4u\n", channel, aDown->pBuffer, aDown->SizeOfBuffer, aDown->RdOff, aDown->WrOff); } return ok; } // rtt_check_channel_to_target From 07952059c8e8c8f6ff48e963600c4496ad261204 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 21:50:18 +0200 Subject: [PATCH 53/64] more cosmetic changes --- src/rtt_console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rtt_console.c b/src/rtt_console.c index 9017e3c5a..de77743cf 100755 --- a/src/rtt_console.c +++ b/src/rtt_console.c @@ -172,7 +172,7 @@ static bool rtt_check_channel_from_target(uint32_t rtt_cb, uint16_t channel, SEG ok = ok && (aUp->SizeOfBuffer > 0 && aUp->SizeOfBuffer < TARGET_RAM_END - TARGET_RAM_START); ok = ok && ((uint32_t)aUp->pBuffer >= TARGET_RAM_START && (uint32_t)aUp->pBuffer + aUp->SizeOfBuffer <= TARGET_RAM_END); if (ok) { - picoprobe_info("rtt_check_channel_from_target: %u %p %4u %4u %4u\n", channel, aUp->pBuffer, aUp->SizeOfBuffer, aUp->RdOff, aUp->WrOff); + picoprobe_info("rtt_check_channel_from_target: %u %p %5u %5u %5u\n", channel, aUp->pBuffer, aUp->SizeOfBuffer, aUp->RdOff, aUp->WrOff); } return ok; } // rtt_check_channel_from_target @@ -191,7 +191,7 @@ static bool rtt_check_channel_to_target(uint32_t rtt_cb, uint16_t channel, SEGGE ok = ok && (aDown->SizeOfBuffer > 0 && aDown->SizeOfBuffer < TARGET_RAM_END - TARGET_RAM_START); ok = ok && ((uint32_t)aDown->pBuffer >= TARGET_RAM_START && (uint32_t)aDown->pBuffer + aDown->SizeOfBuffer <= TARGET_RAM_END); if (ok) { - picoprobe_info("rtt_check_channel_to_target : %u %p %4u %4u %4u\n", channel, aDown->pBuffer, aDown->SizeOfBuffer, aDown->RdOff, aDown->WrOff); + picoprobe_info("rtt_check_channel_to_target : %u %p %5u %5u %5u\n", channel, aDown->pBuffer, aDown->SizeOfBuffer, aDown->RdOff, aDown->WrOff); } return ok; } // rtt_check_channel_to_target From c3862bf024563bcccbf2026b3fa3af609d54a182 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 21:50:54 +0200 Subject: [PATCH 54/64] NCM configuration for Win10/11 --- README.adoc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/README.adoc b/README.adoc index 65e37496b..4fe9fbf61 100644 --- a/README.adoc +++ b/README.adoc @@ -384,8 +384,11 @@ ACTION=="remove", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="file ### Network Configuration -SystemView connectivity over TCP/IP is on most systems not configuration free. On Debian the configuration -is as follows: +SystemView connectivity over TCP/IP is on most systems not configuration free. + +#### Debian + +On Debian the configuration is as follows: * after connecting the probe with the host, `ip a` shows its network interface, e.g. `enxfe`. If the network interface already shows an IP address everything is fine and you are ready @@ -403,6 +406,27 @@ On my system this unfortunately leads to error messages (which are harmless) if The default address of the probe is 192.168.14.1. If there is a collision with the current setup of the host, the probe firmware has to be rebuilt with `-DOPT_NET_192_168=`. +#### Win10 + +A certain version of Win10 is required for USB-NCM connectivity. Exact version is unknown. + +The driver needs to be installed manually. Procedure is roughly as follows: + +* in "Device Manager" search for `YaPicoprobe NCM` with an exclamation mark +* "Update Driver" +* "Browse my computer for drivers" +* "Let me pick..." +* "Network adapters" +* "Microsoft" +* "UsbNcm Host Device" - if this is not available, then the version of Win10 is not ready for USB-NCM +* confirm any dialog boxes +* if `ipconfig` on a command line shows`192.168.14.2` for an Ethernet adapter, the procedure has most likely + succeeded and SystemView is ready for operation + +#### Win11 + +It is said, that USB-NCM is working out of the box. This is not tested. + ### PlatformIO [[platformio]] https://platformio.org/[PlatformIO] configuration in `platformio.ini` is pretty straight forward: From 8ab8605da672898e1788c2af0211c298dc68afc2 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 13 Jul 2023 21:53:15 +0200 Subject: [PATCH 55/64] mini --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 4fe9fbf61..920b35564 100644 --- a/README.adoc +++ b/README.adoc @@ -420,7 +420,7 @@ The driver needs to be installed manually. Procedure is roughly as follows: * "Microsoft" * "UsbNcm Host Device" - if this is not available, then the version of Win10 is not ready for USB-NCM * confirm any dialog boxes -* if `ipconfig` on a command line shows`192.168.14.2` for an Ethernet adapter, the procedure has most likely +* if `ipconfig` on a command line shows `192.168.14.2` for an Ethernet adapter, the procedure has most likely succeeded and SystemView is ready for operation #### Win11 From fbe62223b71c0cff4b957cc5543958143c1f30a9 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 10:23:27 +0200 Subject: [PATCH 56/64] reduce stream size again --- src/cdc/cdc_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdc/cdc_debug.c b/src/cdc/cdc_debug.c index d8225b113..786938d51 100644 --- a/src/cdc/cdc_debug.c +++ b/src/cdc/cdc_debug.c @@ -43,7 +43,7 @@ #include "picoprobe_config.h" -#define STREAM_PRINTF_SIZE 32768 +#define STREAM_PRINTF_SIZE 4096 #define STREAM_PRINTF_TRIGGER 32 static TaskHandle_t task_printf = NULL; From 102801788bb1091eb231e5c7b173dd811070ecfa Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 10:24:03 +0200 Subject: [PATCH 57/64] new OPT_MCU_OVERCLOCK_MHZ --- CMakeLists.txt | 4 ++++ include/picoprobe_config.h | 6 +++--- src/get_config.h | 14 ++++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ef58af3b..de9f07a77 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ option(OPT_PROBE_DEBUG_OUT "Enable CDC for probe debug output" ${DEFAUL option(OPT_SIGROK "Enable sigrok" 0) option(OPT_MSC "Enable Mass Storage Device" 1) option(OPT_MSC_RAM_UF2 "Enable file 'RAM.UF2' on Mass Storage" 1) +set(OPT_MCU_OVERCLOCK_MHZ "240" CACHE STRING "Set processor frequency. Should be a multiple of 24MHz, disable with empty string (=120MHz)") set(OPT_NET "NCM" CACHE STRING "Enable lwIP on the Pico via ECM/NCM/RNDIS, disable NET with empty string") set(OPT_NET_192_168 14 CACHE STRING "Set the subnet of 192.168.x") option(OPT_NET_ECHO_SERVER "Enable echo server for testing" 1) @@ -95,6 +96,9 @@ add_definitions( -DTARGET_BOARD_${PICO_BOARD_UPPER} -DOPT_SPECIAL_CLK_FOR_PIO=${OPT_SPECIAL_CLK_FOR_PIO} ) +if(NOT OPT_MCU_OVERCLOCK_MHZ STREQUAL "") + add_compile_definitions(OPT_MCU_OVERCLOCK_MHZ=${OPT_MCU_OVERCLOCK_MHZ}) +endif() # set version string to "x.yy" # there are perhaps smarter ways... diff --git a/include/picoprobe_config.h b/include/picoprobe_config.h index 14ca1b58c..b1a249089 100755 --- a/include/picoprobe_config.h +++ b/include/picoprobe_config.h @@ -63,10 +63,10 @@ // Base value of sys_clk in khz. Must be <=125Mhz per RP2040 spec and a multiple of 24Mhz // to support integer divisors of the PIO clock and ADC clock (for sigrok) -#if 0 -#define PROBE_CPU_CLOCK_KHZ ((120 + 2*24) * 1000) // overclocked, even 264MHz seems to be no problem +#ifdef OPT_MCU_OVERCLOCK_MHZ + #define PROBE_CPU_CLOCK_KHZ ((OPT_MCU_OVERCLOCK_MHZ) * 1000) // overclocked, even 264MHz seems to be no problem #else -#define PROBE_CPU_CLOCK_KHZ ((120 + 5*24) * 1000) // overclocked, even 264MHz seems to be no problem + #define PROBE_CPU_CLOCK_KHZ ((120 + 0*24) * 1000) #endif diff --git a/src/get_config.h b/src/get_config.h index 7a6c06701..4aa8763f6 100644 --- a/src/get_config.h +++ b/src/get_config.h @@ -109,14 +109,20 @@ /** * CONFIG_BOARD */ +#if defined(OPT_MCU_OVERCLOCK_MHZ) +#define __OPT_MCU_MHZ " @ " xxCoNfSTR(OPT_MCU_OVERCLOCK_MHZ) "MHz" +#else +#define __OPT_MCU_MHZ +#endif + #if defined(TARGET_BOARD_PICO) - #define CONFIG_BOARD() "Pico" + #define CONFIG_BOARD() "Pico" __OPT_MCU_MHZ #elif defined(TARGET_BOARD_PICO_W) - #define CONFIG_BOARD() "Pico_W" + #define CONFIG_BOARD() "Pico_W" __OPT_MCU_MHZ #elif defined(TARGET_BOARD_PICO_DEBUG_PROBE) - #define CONFIG_BOARD() "Pico Debug Probe" + #define CONFIG_BOARD() "Pico Debug Probe" __OPT_MCU_MHZ #else - #define CONFIG_BOARD() "UNKNOWN board" + #define CONFIG_BOARD() "UNKNOWN board" __OPT_MCU_MHZ #endif From 85e53a71ce49f3d530cd6e319255e073d2c5aa5a Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 10:25:02 +0200 Subject: [PATCH 58/64] reorder priorities --- src/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index b52532378..e533bcff8 100644 --- a/src/main.c +++ b/src/main.c @@ -119,14 +119,14 @@ static uint8_t RxDataBuffer[_DAP_PACKET_COUNT_OPENOCD * CFG_TUD_VENDOR_RX_BUFSIZ // prios are critical and determine throughput // there is one more task prio in lwipopts.h -#define PRINT_STATUS_TASK_PRIO (tskIDLE_PRIORITY + 30) // high prio to get status output transferred in (almost) any case -#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 20) // high prio for TinyUSB -#define LED_TASK_PRIO (tskIDLE_PRIORITY + 12) // simple task which may interrupt everything else for periodic blinking +#define LED_TASK_PRIO (tskIDLE_PRIORITY + 30) // simple task which may interrupt everything else for periodic blinking +#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 28) // high prio for TinyUSB +#define CDC_DEBUG_TASK_PRIO (tskIDLE_PRIORITY + 26) // probe debugging output (CDC) +#define PRINT_STATUS_TASK_PRIO (tskIDLE_PRIORITY + 24) // high prio to get status output transferred in (almost) any case #define SIGROK_TASK_PRIO (tskIDLE_PRIORITY + 9) // Sigrok digital/analog signals (does nothing at the moment) #define MSC_WRITER_THREAD_PRIO (tskIDLE_PRIORITY + 8) // this is only running on writing UF2 files #define SYSVIEW_TASK_PRIO (tskIDLE_PRIORITY + 6) // target -> host via SysView (CDC) #define UART_TASK_PRIO (tskIDLE_PRIORITY + 5) // target -> host via UART (CDC) -#define CDC_DEBUG_TASK_PRIO (tskIDLE_PRIORITY + 4) // probe debugging output (CDC) #define DAPV2_TASK_PRIO (tskIDLE_PRIORITY + 3) // DAPv2 execution #define RTT_CONSOLE_TASK_PRIO (tskIDLE_PRIORITY + 1) // target -> host via RTT, ATTENTION: this task can fully load the CPU depending on target RTT output From 256b7d72837a27d70f8af30ab4bf4629e2ac916d Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 12:46:11 +0200 Subject: [PATCH 59/64] lwIP -> TineUSB cleanup --- src/net/net_glue.c | 75 +++++++---------------------- src/net/tinyusb/ncm.h | 4 +- src/net/tinyusb/ncm_device_simple.c | 44 ++++++++--------- 3 files changed, 42 insertions(+), 81 deletions(-) diff --git a/src/net/net_glue.c b/src/net/net_glue.c index 06986d4b1..eef07ae69 100755 --- a/src/net/net_glue.c +++ b/src/net/net_glue.c @@ -43,11 +43,11 @@ #include "tusb.h" #include "device/usbd_pvt.h" // for usbd_defer_func +#include "tinyusb/net_device.h" #define EV_RCVFRAME_READY 1 - /* lwip context */ static struct netif netif_data; @@ -57,7 +57,8 @@ static struct pbuf *received_frame = NULL; static uint8_t rcv_buff[4000]; static uint16_t rcv_buff_len = 0; -static uint8_t xmt_buff[4000]; +/// Buffer for lwIP -> TinyUSB transmission +static uint8_t xmt_buff[CFG_TUD_NET_MTU + 10]; static uint16_t xmt_buff_len = 0; #ifndef OPT_NET_192_168 @@ -181,6 +182,15 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) memcpy(rcv_buff, src, size); rcv_buff_len = size; tcpip_callback_with_block(net_glue_usb_to_lwip, NULL, 0); + + { + static uint16_t max; + + if (rcv_buff_len > max) { + max = rcv_buff_len; + printf("rcv_buff_len: %d\n", max); + } + } } #endif return true; @@ -200,41 +210,18 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) { //printf("!!!!!!!!!!!!!!tud_network_xmit_cb(%p,%p,%u)\n", dst, ref, arg); -#if 0 - struct pbuf *p = (struct pbuf *)ref; - struct pbuf *q; - uint16_t len = 0; - - (void)arg; /* unused for this example */ - - /* traverse the "pbuf chain"; see ./lwip/src/core/pbuf.c for more info */ - for (q = p; q != NULL; q = q->next) - { - memcpy(dst, (char *)q->payload, q->len); - dst += q->len; - len += q->len; - if (q->len == q->tot_len) - break; - } - - return len; -#elif 0 - struct pbuf *p = (struct pbuf *)ref; - - (void)arg; /* unused for this example */ - - return pbuf_copy_partial(p, dst, p->tot_len, 0); -#else uint16_t r = xmt_buff_len; memcpy(dst, xmt_buff, xmt_buff_len); xmt_buff_len = 0; return r; -#endif } // tud_network_xmit_cb static void context_tinyusb_linkoutput(void *param) +/** + * Put \a xmt_buff into TinyUSB (if possible). + */ { if ( !tud_network_can_xmit(xmt_buff_len)) { //printf("context_tinyusb_linkoutput: sleep\n"); @@ -253,34 +240,6 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) * called by lwIP to transmit data to TinyUSB */ { - (void)netif; - -#if 0 - // TODO: interesting: if !can_xmit, then TinyUSB does the transfer in the "background" - // but this is priority dependent. Better sleep here for a short period and then repeat. - for (;;) - { - //printf("linkoutput_fn()\n"); - /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ - if ( !tud_ready()) { - return ERR_USE; - } - - /* if the network driver can accept another packet, we make it happen */ - if (tud_network_can_xmit(p->tot_len)) { - tud_network_xmit(p, 0 /* unused for this example */); - return ERR_OK; - } -// else -// return ERR_USE; -// -// tud_task(); - //printf("linkoutput_fn - sleep\n"); - vTaskDelay(pdMS_TO_TICKS(10)); - } - - return ERR_USE; -#else if ( !tud_ready()) { return ERR_USE; } @@ -289,11 +248,13 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) return ERR_USE; } + // copy data into temp buffer xmt_buff_len = pbuf_copy_partial(p, xmt_buff, p->tot_len, 0); + assert(xmt_buff_len < sizeof(xmt_buff)); + usbd_defer_func(context_tinyusb_linkoutput, NULL, false); return ERR_OK; -#endif } // linkoutput_fn diff --git a/src/net/tinyusb/ncm.h b/src/net/tinyusb/ncm.h index fc0efcade..6f9f064ed 100755 --- a/src/net/tinyusb/ncm.h +++ b/src/net/tinyusb/ncm.h @@ -32,15 +32,17 @@ #ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE + /// must be >> MTU #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 #endif #ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE + /// must be >> MTU #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 #endif #ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB - #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 // TODO should be 8 or so + #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 #endif #ifndef CFG_TUD_NCM_ALIGNMENT diff --git a/src/net/tinyusb/ncm_device_simple.c b/src/net/tinyusb/ncm_device_simple.c index 1bc1b7ec0..041fa4a7a 100755 --- a/src/net/tinyusb/ncm_device_simple.c +++ b/src/net/tinyusb/ncm_device_simple.c @@ -82,18 +82,18 @@ typedef struct { //--------------------------------------------------------------------+ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { - .wLength = sizeof(ntb_parameters_t), - .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported - .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, - .wNdbInDivisor = 4, - .wNdbInPayloadRemainder = 0, - .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, - .wReserved = 0, - .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, - .wNdbOutDivisor = 4, + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, + .wNdbInDivisor = 4, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, - .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 1 // 0=no limit TODO set to 0 + .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 1 // 0=no limit TODO set to 0 }; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb; @@ -118,12 +118,12 @@ tu_static struct ncm_notify_struct ncm_notify_connected = { .header = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, + .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = CDC_NOTIF_NETWORK_CONNECTION, - .wValue = 1 /* Connected */, - .wLength = 0, + .wValue = 1 /* Connected */, + .wLength = 0, }, }; @@ -131,21 +131,21 @@ tu_static struct ncm_notify_struct ncm_notify_speed_change = { .header = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, + .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, - .wLength = 8, + .wLength = 8, }, .downlink = 10000000, - .uplink = 10000000, + .uplink = 10000000, }; void tud_network_recv_renew(void) /** - * context: lwIP & TinyUSB + * context: TinyUSB */ { // printf("tud_network_recv_renew() - [%p]\n", xTaskGetCurrentTaskHandle()); @@ -440,10 +440,9 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t //printf("netd_control_xfer_cb/TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - if (NCM_GET_NTB_PARAMETERS == request->bRequest) { + if (request->bRequest == NCM_GET_NTB_PARAMETERS) { tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); } - break; // unsupported request @@ -502,8 +501,7 @@ bool tud_network_can_xmit(uint16_t size) /** * poll network driver for its ability to accept another packet to transmit * - * context: lwIP - * + * context: TinyUSB */ { //printf("tud_network_can_xmit() %d [%p]\n", ncm_interface.can_xmit, xTaskGetCurrentTaskHandle()); @@ -514,7 +512,7 @@ bool tud_network_can_xmit(uint16_t size) void tud_network_xmit(void *ref, uint16_t arg) /** - * context: lwIP. + * context: TinyUSB. */ { transmit_ntb_t *ntb = &transmit_ntb; From c754db72c8841927f3e308db37fbd5d2f6eb5b25 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 13:13:22 +0200 Subject: [PATCH 60/64] cleanup TinyUSB -> lwIP direction --- src/net/net_glue.c | 110 +++++++++++++++--------------------------- src/net/net_sysview.c | 7 +++ 2 files changed, 46 insertions(+), 71 deletions(-) diff --git a/src/net/net_glue.c b/src/net/net_glue.c index eef07ae69..999f3af6b 100755 --- a/src/net/net_glue.c +++ b/src/net/net_glue.c @@ -26,12 +26,11 @@ //---------------------------------------------------------------------------------------------------------------------- // -// TCP server for SystemView -// - using RNDIS / ECM because it is driver free for Windows / Linux / iOS -// - we leave the IPv6 stuff outside +// Stuff to glue lwIP and TinyUSB together. +// Code might be confusing because it is trying hard to call everything in the right context. +// It is assumed that net_glue is running in a FreeRTOS environment. // - #include #include #include @@ -42,27 +41,23 @@ #include "dhserver.h" #include "tusb.h" -#include "device/usbd_pvt.h" // for usbd_defer_func +#include "device/usbd_pvt.h" // for usbd_defer_func #include "tinyusb/net_device.h" -#define EV_RCVFRAME_READY 1 - -/* lwip context */ +/// lwIP context static struct netif netif_data; -/* shared between tud_network_recv_cb() and service_traffic() */ -static struct pbuf *received_frame = NULL; - -static uint8_t rcv_buff[4000]; +/// Buffer for lwIP <- TinyUSB transmission +static uint8_t rcv_buff[CFG_TUD_NET_MTU + 10]; // MTU plus some margin static uint16_t rcv_buff_len = 0; /// Buffer for lwIP -> TinyUSB transmission -static uint8_t xmt_buff[CFG_TUD_NET_MTU + 10]; +static uint8_t xmt_buff[CFG_TUD_NET_MTU + 10]; // MTU plus some margin static uint16_t xmt_buff_len = 0; #ifndef OPT_NET_192_168 - #define OPT_NET_192_168 10 + #define OPT_NET_192_168 14 #endif /* network parameters of this MCU */ @@ -74,17 +69,21 @@ static const ip4_addr_t gateway = IPADDR4_INIT_BYTES(0, 0, 0, 0); static dhcp_entry_t entries[] = { /* mac ip address lease time */ - { {0}, IPADDR4_INIT_BYTES(192, 168, OPT_NET_192_168, 2), 24 * 60 * 60 }, + { + .mac = {0}, + .addr = IPADDR4_INIT_BYTES(192, 168, OPT_NET_192_168, 2), + .lease = 24 * 60 * 60 + }, }; static const dhcp_config_t dhcp_config = { - .router = IPADDR4_INIT_BYTES(0, 0, 0, 0), // router address (if any) - .port = 67, // listen port - .dns = IPADDR4_INIT_BYTES(0, 0, 0, 0), // dns server - NULL, // dns suffix: specify NULL, otherwise /etc/resolv.conf will be changed - TU_ARRAY_SIZE(entries), // num entry - entries // entries + .router = IPADDR4_INIT_BYTES(0, 0, 0, 0), // router address (if any) + .port = 67, // listen port + .dns = IPADDR4_INIT_BYTES(0, 0, 0, 0), // dns server + .domain = NULL, // dns suffix: specify NULL, otherwise /etc/resolv.conf will be changed + .num_entry = TU_ARRAY_SIZE(entries), // num entry + .entries = entries // entries }; @@ -94,17 +93,18 @@ void tud_network_init_cb(void) * initialize any network state back to the beginning */ { - /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ - if (received_frame != NULL) - { - pbuf_free(received_frame); - received_frame = NULL; - } + rcv_buff_len = 0; + xmt_buff_len = 0; } // tud_network_init_cb static void context_tinyusb_tud_network_recv_renew(void *param) +/** + * Reenable reception logic in TinyUSB. + * + * Context: TinyUSB + */ { tud_network_recv_renew(); } // context_tinyusb_tud_network_recv_renew @@ -113,19 +113,13 @@ static void context_tinyusb_tud_network_recv_renew(void *param) static void net_glue_usb_to_lwip(void *ptr) /** - * handle any packet received by tud_network_recv_cb() in context of lwIP + * Handle any packet received by tud_network_recv_cb() + * + * Context: lwIP */ { //printf("net_glue_usb_to_lwip\n"); -#if 0 - if (received_frame != NULL) { - ethernet_input(received_frame, &netif_data); - pbuf_free(received_frame); - received_frame = NULL; - tud_network_recv_renew(); - } -#else if (rcv_buff_len != 0) { struct pbuf *p = pbuf_alloc(PBUF_RAW, rcv_buff_len, PBUF_POOL); @@ -134,15 +128,9 @@ static void net_glue_usb_to_lwip(void *ptr) ethernet_input(p, &netif_data); pbuf_free(p); rcv_buff_len = 0; -#if 0 - tud_network_recv_renew(); -#else - // did not change anything usbd_defer_func(context_tinyusb_tud_network_recv_renew, NULL, false); -#endif } } -#endif } // net_glue_usb_to_lwip @@ -150,30 +138,14 @@ static void net_glue_usb_to_lwip(void *ptr) bool tud_network_recv_cb(const uint8_t *src, uint16_t size) /** * Copy buffer (host ->) TinyUSB -> lwIP (-> application) + * + * Context: TinyUSB + * * \return false if the packet buffer was not accepted */ { //printf("tud_network_recv_cb(%p,%u)\n", src, size); -#if 0 - /* this shouldn't happen, but if we get another packet before - parsing the previous, we must signal our inability to accept it */ - if (received_frame) - return false; - - if (size) { - struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); - - if (p) { - /* pbuf_alloc() has already initialized struct; all we need to do is copy the data */ - memcpy(p->payload, src, size); - - /* store away the pointer for service_traffic() to later handle */ - received_frame = p; - tcpip_callback_with_block(net_glue_usb_to_lwip, NULL, 0); - } - } -#else if (rcv_buff_len != 0) return false; @@ -182,17 +154,7 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) memcpy(rcv_buff, src, size); rcv_buff_len = size; tcpip_callback_with_block(net_glue_usb_to_lwip, NULL, 0); - - { - static uint16_t max; - - if (rcv_buff_len > max) { - max = rcv_buff_len; - printf("rcv_buff_len: %d\n", max); - } - } } -#endif return true; } // tud_network_recv_cb @@ -205,6 +167,8 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) * * (application ->) lwIP -> TinyUSB (-> host) * + * Context: TinyUSB + * * \return number of bytes copied */ { @@ -221,6 +185,8 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) static void context_tinyusb_linkoutput(void *param) /** * Put \a xmt_buff into TinyUSB (if possible). + * + * Context: TinyUSB */ { if ( !tud_network_can_xmit(xmt_buff_len)) { @@ -238,6 +204,8 @@ static void context_tinyusb_linkoutput(void *param) static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) /** * called by lwIP to transmit data to TinyUSB + * + * Context: lwIP */ { if ( !tud_ready()) { diff --git a/src/net/net_sysview.c b/src/net/net_sysview.c index ce6217ed7..c0e71a625 100755 --- a/src/net/net_sysview.c +++ b/src/net/net_sysview.c @@ -23,6 +23,12 @@ * */ +//---------------------------------------------------------------------------------------------------------------------- +// +// TCP server for SystemView +// - using NCM because it is driver free for Windows / Linux / iOS +// - we leave the IPv6 stuff outside +// #include "FreeRTOS.h" #include "stream_buffer.h" @@ -284,6 +290,7 @@ static err_t sysview_accept(void *arg, struct tcp_pcb *newpcb, err_t err) return ERR_OK; } // sysview_accept +// TODO recheck here bool net_sysview_is_connected(void) From d58f71f6d491f92b5ec7354dc66d978de5f8b5c7 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 17:57:36 +0200 Subject: [PATCH 61/64] minor --- src/main.c | 8 ++++++++ src/net/net_sysview.c | 2 +- src/net/tinyusb/ncm_device.c | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index e533bcff8..64ff3bf34 100644 --- a/src/main.c +++ b/src/main.c @@ -398,6 +398,14 @@ void print_task_stat(void *ptr) for (;;) { printf("---------------------------------------\n"); +#if LWIP_STATS + { + extern void stats_display(void); + stats_display(); + printf("---------------------------------------\n"); + } +#endif + printf("TinyUSB counter : %lu\n", tusb_count - prev_tusb_count); prev_tusb_count = tusb_count; vPortGetHeapStats( &heap_status); diff --git a/src/net/net_sysview.c b/src/net/net_sysview.c index c0e71a625..4414359d8 100755 --- a/src/net/net_sysview.c +++ b/src/net/net_sysview.c @@ -157,7 +157,7 @@ static void sysview_try_send(void *ctx) else { // printf("sysview_try_send: no tcp_sndbuf!!!!\n"); if ( !block_call_to_tcp_output) { - printf("sysview_try_send: flush\n"); + //printf("sysview_try_send: flush\n"); block_call_to_tcp_output = true; tcp_output(m_pcb_client); } diff --git a/src/net/tinyusb/ncm_device.c b/src/net/tinyusb/ncm_device.c index d729ce23c..ef2ddb8c3 100755 --- a/src/net/tinyusb/ncm_device.c +++ b/src/net/tinyusb/ncm_device.c @@ -28,6 +28,8 @@ #include "tusb_option.h" +#warning "Don't use this driver because it is (very) buggy. It is for reference only." + #if ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) #if ECLIPSE_GUI From d588ade6a8dfb471f74e3029b319f4de2456c6cb Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 17:58:01 +0200 Subject: [PATCH 62/64] performance optimization --- include/FreeRTOSConfig.h | 2 +- include/lwipopts.h | 42 ++++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/include/FreeRTOSConfig.h b/include/FreeRTOSConfig.h index 53ca2c208..0656d4549 100644 --- a/include/FreeRTOSConfig.h +++ b/include/FreeRTOSConfig.h @@ -78,7 +78,7 @@ /* Memory allocation related definitions. */ #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configTOTAL_HEAP_SIZE (150*1024) +#define configTOTAL_HEAP_SIZE (90*1024) #define configAPPLICATION_ALLOCATED_HEAP 0 /* Hook function related definitions. */ diff --git a/include/lwipopts.h b/include/lwipopts.h index 315e3acef..aee081c8d 100755 --- a/include/lwipopts.h +++ b/include/lwipopts.h @@ -65,45 +65,49 @@ //-------------------------------------- -// performance tuning (do not change without extensive testing, optimized for ECM) -#define TCP_MSS (1500 - 20 - 20) // MTU minus header sizes (best value til now) -#define TCP_SND_BUF (4 * TCP_MSS) // good tuning +// performance tuning (do not change without extensive testing, optimized for ECM/NCM) +#define TCP_MSS (1500 - 20 - 20) // MTU minus header sizes (best value til now) +#define TCP_SND_BUF (8 * TCP_MSS) // good tuning -//#define TCP_WND (2 * TCP_MSS) -//#define TCP_OVERSIZE TCP_MSS // til now no good value found - -//#define TCP_TMR_INTERVAL 50 // TODO just a test (default: 250) -//#define TCP_FAST_INTERVAL 250 -//#define TCP_SLOW_INTERVAL 100 +//#define TCP_WND TCP_SND_BUF // til now no good value found +#define TCP_SND_QUEUELEN 16 +#define TCP_SNDQUEUELOWAT (TCP_SND_QUEUELEN / 2) +#define MEMP_NUM_TCP_SEG 32 //-------------------------------------- // memory -#define MEM_SIZE 20000 -//#define MEM_LIBC_MALLOC 1 -//#define MEMP_MEM_MALLOC 1 +#define MEM_SIZE 20000 +//#define MEMP_OVERFLOW_CHECK 1 //#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 1 //-------------------------------------- // for freertos mode -#define TCPIP_MBOX_SIZE 64 -#define TCPIP_THREAD_STACKSIZE 8192 -#define TCPIP_THREAD_PRIO 11 +#define TCPIP_MBOX_SIZE 64 +#define TCPIP_THREAD_STACKSIZE 8192 +#define TCPIP_THREAD_PRIO 11 //-------------------------------------- // trying... #define LWIP_PROVIDE_ERRNO 1 #if LWIP_SOCKET - #define LWIP_TIMEVAL_PRIVATE 0 // required for LWIP_SOCKET + #define LWIP_TIMEVAL_PRIVATE 0 // required for LWIP_SOCKET #endif //-------------------------------------- // statistics -//#define LWIP_STATS 1 -//#define LWIP_STATS_DISPLAY 1 -//#define LINK_STATS 1 +// use stats_display() for display +#define LWIP_STATS 0 +#define LWIP_STATS_DISPLAY 0 +#define ETHARP_STATS 0 // do not display the topics below +#define ICMP_STATS 0 +#define IPFRAG_STATS 0 +#define LINK_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define UDP_STATS 0 //-------------------------------------- From b987f0c20cdc266c229c946798e4e834e566607d Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 18:24:21 +0200 Subject: [PATCH 63/64] raised prio of lwIP --- include/lwipopts.h | 2 +- src/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/lwipopts.h b/include/lwipopts.h index aee081c8d..9e306efc0 100755 --- a/include/lwipopts.h +++ b/include/lwipopts.h @@ -85,7 +85,7 @@ // for freertos mode #define TCPIP_MBOX_SIZE 64 #define TCPIP_THREAD_STACKSIZE 8192 -#define TCPIP_THREAD_PRIO 11 +#define TCPIP_THREAD_PRIO 27 //-------------------------------------- diff --git a/src/main.c b/src/main.c index 64ff3bf34..6cd27a4ec 100644 --- a/src/main.c +++ b/src/main.c @@ -118,9 +118,9 @@ static uint8_t RxDataBuffer[_DAP_PACKET_COUNT_OPENOCD * CFG_TUD_VENDOR_RX_BUFSIZ // prios are critical and determine throughput -// there is one more task prio in lwipopts.h #define LED_TASK_PRIO (tskIDLE_PRIORITY + 30) // simple task which may interrupt everything else for periodic blinking #define TUD_TASK_PRIO (tskIDLE_PRIORITY + 28) // high prio for TinyUSB +//#define TCPIP_THREAD_PRIO (27) // defined in lwipopts.h #define CDC_DEBUG_TASK_PRIO (tskIDLE_PRIORITY + 26) // probe debugging output (CDC) #define PRINT_STATUS_TASK_PRIO (tskIDLE_PRIORITY + 24) // high prio to get status output transferred in (almost) any case #define SIGROK_TASK_PRIO (tskIDLE_PRIORITY + 9) // Sigrok digital/analog signals (does nothing at the moment) From 6918f36af99e1c98441a6775c92133987b928d72 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 14 Jul 2023 19:10:59 +0200 Subject: [PATCH 64/64] docu --- CMakeLists.txt | 2 +- doc/lwIP-notes.adoc | 68 ++++++++++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de9f07a77..eae8b133d 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ option(OPT_SIGROK "Enable sigrok" 0) option(OPT_MSC "Enable Mass Storage Device" 1) option(OPT_MSC_RAM_UF2 "Enable file 'RAM.UF2' on Mass Storage" 1) set(OPT_MCU_OVERCLOCK_MHZ "240" CACHE STRING "Set processor frequency. Should be a multiple of 24MHz, disable with empty string (=120MHz)") -set(OPT_NET "NCM" CACHE STRING "Enable lwIP on the Pico via ECM/NCM/RNDIS, disable NET with empty string") +set(OPT_NET "NCM" CACHE STRING "Enable lwIP on the Pico via NCM/ECM/RNDIS, disable NET with empty string") set(OPT_NET_192_168 14 CACHE STRING "Set the subnet of 192.168.x") option(OPT_NET_ECHO_SERVER "Enable echo server for testing" 1) option(OPT_NET_IPERF_SERVER "Enable iperf server for tuning" 1) diff --git a/doc/lwIP-notes.adoc b/doc/lwIP-notes.adoc index e2b49ba34..e02114ccd 100755 --- a/doc/lwIP-notes.adoc +++ b/doc/lwIP-notes.adoc @@ -9,8 +9,9 @@ ## Some lwIP Notes lwIP is used for creation of a network interface of YAPicoprobe to avoid -an uncountable number of additional CDC com ports. + -Currently just a Segger SysView server is listening on port 19111. +an uncountable number of additional CDC COM ports. + +Currently a Segger SysView server is listening on port 19111. But I guess there is more to come. @@ -64,19 +65,7 @@ messages even when the device has `allow-hotplug`. Unfortunately RNDIS seems to manipulate routing in a way that the default route on my Linux wants to go through the probe. Not really what I want... - -* *NCM*: is said to be the best choice. I did not manage to get an - acceptable throughput. Transfer seems to get stuck from time to time - and SystemView aborts. So also not the favorite. + - `iperf` is running fast, it seems that `ncm_device.c` output is triggered - by incoming packets. -* *ECM*: works good, packets are transferred continuously, throughput - also seems to be ok. So this is the way to go. + - Unfortunately there is no driver integrated into Win10, so possible - extra trouble appears. Yes... extra trouble: cannot find a driver - for Win10. - [NOTE] ==== RNDIS on Win10 works only, if RNDIS on the probe is the only USB class selected. @@ -85,6 +74,20 @@ like SystemView, but you cannot have a probe which does SystemView and CMSIS-DAP This is not a fault of lwIP, it is a bug in the Win10 driver(?). ==== +* *ECM*: works good, packets are transferred continuously, throughput + also seems to be ok. So this is the way to go. + + Unfortunately there is no driver integrated into Win10, so possible + extra trouble appears. Yes... extra trouble: cannot find a driver + for Win10. + +* *NCM*: is said to be the best choice. And in fact it is. + At least after creation of a `ncm_device_simple.c` driver which is a + stripped down version of `ncm_simple.c` which revealed as very buggy. + + Now thoughput under Linux and Windows is ok. Operation with SystemView + works without glitches, `iperf` tests sometimes crashes the probe. + So consider this driver as beta and work in progress. + + ## Performance @@ -104,9 +107,29 @@ Good test cases are the following command lines: Monitor performance/errors with Wireshark. -## Some words about ncm_device.c and net_glue.c +## Some words about... + +### ... `net_glue.c` + +I'm really trying hard to switch context betwenn lwIP and TinyUSB correctly. This leads +to some kind of delayed call chains and also does not make the code neither nice nor +very much maintainable. + -### Remarks about possible Bugs +### ... `ncm_device_simple.c` + +`ncm_device_simple.c` is actually a mixture of `ecm_rndis_device.c` and `ncm_device.c`. +From `ecm_rndis_device.c` the structure has been inherited and from `ncm_device.c` the +functionality. + +The driver can be considered work in progress, because in conjunction with `iperf` +crashes sometimes happen. But for operation with SystemView quality seems to be good enough. + + +### ... possible Bugs in `ncm_device.c` + +This is more or less obsoleted by `ncm_device_simple.c`. But as a short summary: the original +driver is very buggy. Perhaps it is working in certain scenarios, but for sure not together with +SystemView. * not sure, but perhaps it is best to call all functions within ncm_device in the FreeRTOS context of TinyUSB @@ -116,21 +139,22 @@ Monitor performance/errors with Wireshark. ** `wNtbOutMaxDatagrams == 0` generates a lot of retries with iperf * I guess that the *major problem* lies within handle_incoming_datagram() because it changes values on an incoming packet although tud_network_recv_renew() is still handling the old one -* is there multicore a problem!? I have seen retries with multicore even with +* is there multicore a problem!? (14.7.2023: no!) I have seen retries with multicore even with `wNtbOutMaxDatagrams = 1` * I think it is assumed, that TinyUSB and lwIP are running in the same task (but in my scenario they don't) * if removing debug messages, then the receive path seems to work better, which indicates a race condition somewhere +There is an open issue in the TinyUSB repo for this issue: https://github.com/hathach/tinyusb/issues/2068 -### Remarks about Functionality -* tud_network_xmit() puts the data to be transmitted into a buffer (out of two). - After copying the contents, it tries to start transmission via ncm_start_tx() - which checks if there is an ongoing transmission +## Log +### 2023-07-14 -## Log +* did some performance tuning with lwIP and TinyUSB +* stripped sources +* BUG: `ncm_device_simple` sometimes crashes with `iperf` ### 2023-06-30