From 798ff807b3361a5859945cb23c3d0fd7d1a5679f Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 11 Aug 2023 18:04:34 +0200 Subject: removed obsolete tud_network_link_state_cb() --- src/class/net/ncm_device.c | 7 ------- src/class/net/net_device.h | 5 ----- 2 files changed, 12 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 226c42c4e..dc086cf5c 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -337,11 +337,6 @@ static void ncm_report(void) } } -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) @@ -381,8 +376,6 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t ncm_report(); } } - - tud_network_link_state_cb(ncm_interface.itf_data_alt); } tud_control_status(rhport, request); diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 399916355..454fde861 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -96,11 +96,6 @@ void tud_network_init_cb(void); // 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 //--------------------------------------------------------------------+ -- cgit v1.3.1 From fca08c939c0d04b9485413166b69f8abac6fb083 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: files taken from yapicoprobe --- src/class/net/ncm.h | 106 +++- src/class/net/ncm_device.c | 1281 +++++++++++++++++++++++++++++++------------- src/class/net/net_device.h | 24 +- 3 files changed, 997 insertions(+), 414 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index 96ba11fbc..313237747 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -30,10 +30,47 @@ #include "common/tusb_common.h" -#ifdef __cplusplus - extern "C" { + +#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_OUT_NTB_N + /// number of ntb buffers for reception side + /// 1 - good performance + /// 2 - up to 30% more performance with iperf with small packets + /// >2 - no performance gain + #define CFG_TUD_NCM_OUT_NTB_N 2 +#endif + +#ifndef CFG_TUD_NCM_IN_NTB_N + /// number of ntb buffers for transmission side + /// 1 - good performance but SystemView shows lost events (on load test) + /// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" + /// happens from time to time with SystemView + /// 3 - "tud_network_can_xmit: request blocked" never happens + /// >2 - no performance gain + #define CFG_TUD_NCM_IN_NTB_N 3 +#endif + +#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + /// this is for the transmission size for allocation of \a ndp16_datagram_t + #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 +#endif + +#ifndef CFG_TUD_NCM_ALIGNMENT + #define CFG_TUD_NCM_ALIGNMENT 4 +#endif +#if (CFG_TUD_NCM_ALIGNMENT != 4) + #error "CFG_TUD_NCM_ALIGNMENT must be 4, otherwise the headers and start of datagrams have to be aligned (which they are currently not)" #endif + // Table 4.3 Data Class Interface Protocol Codes typedef enum { @@ -62,8 +99,67 @@ 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; + ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1]; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; +} xmit_ntb_t; + +typedef union TU_ATTR_PACKED { + struct { + nth16_t nth; + // only the header is at a guaranteed position + }; + uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; +} recv_ntb_t; + +struct ncm_notify_t { + tusb_control_request_t header; + uint32_t downlink, uplink; +}; + #endif diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 226c42c4e..f7a236e69 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,9 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2020 Jacob Berg Potter - * Copyright (c) 2020 Peter Lawrence - * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2023 Hardy Griech * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,493 +24,1004 @@ * This file is part of the TinyUSB stack. */ +/** + * Small Glossary (from the spec) + * -------------- + * Datagram - A collection of bytes forming a single item of information, passed as a unit from source to destination. + * NCM - Network Control Model + * NDP - NCM Datagram Pointer: NTB structure that delineates Datagrams (typically Ethernet frames) within an NTB + * NTB - NCM Transfer Block: a data structure for efficient USB encapsulation of one or more datagrams + * Each NTB is designed to be a single USB transfer + * NTH - NTB Header: a data structure at the front of each NTB, which provides the information needed to validate + * the NTB and begin decoding + * + * Some explanations + * ----------------- + * - rhport is the USB port of the device, in most cases "0" + * - itf_data_alt if != 0 -> data xmit/recv are allowed (see spec) + * - ep_in IN endpoints take data from the device intended to go in to the host (the device transmits) + * - ep_out OUT endpoints send data out of the host to the device (the device receives) + */ + #include "tusb_option.h" -#if ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + +#include +#include +#include #include "device/usbd.h" #include "device/usbd_pvt.h" + #include "net_device.h" +#include "ncm.h" + + +#if !defined(tu_static) || ECLIPSE_GUI + // TinyUSB <=0.15.0 does not know "tu_static" + #define tu_static static +#endif -// Level where CFG_TUSB_DEBUG must be at least for this driver is logged -#ifndef CFG_TUD_NCM_LOG_LEVEL - #define CFG_TUD_NCM_LOG_LEVEL CFG_TUD_LOG_LEVEL +#if 0 + #define DEBUG_OUT(...) printf(__VA_ARGS__) + #define DEBUG_OUT_ENABLED +#else + #define DEBUG_OUT(...) #endif -#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__) +#if 0 + #define INFO_OUT(...) printf(__VA_ARGS__) +#else + #define INFO_OUT(...) +#endif + +#if 1 + #define ERROR_OUT(...) printf(__VA_ARGS__) +#else + #define ERROR_OUT(...) +#endif + +// calculate alignment of xmit datagrams within an NTB +#define XMIT_ALIGN_OFFSET(x) ((CFG_TUD_NCM_ALIGNMENT - ((x) & (CFG_TUD_NCM_ALIGNMENT - 1))) & (CFG_TUD_NCM_ALIGNMENT - 1)) + +//----------------------------------------------------------------------------- +// +// Module global things +// +#define XMIT_NTB_N CFG_TUD_NCM_IN_NTB_N +#define RECV_NTB_N CFG_TUD_NCM_OUT_NTB_N + +typedef struct { + // general + uint8_t ep_in; //!< endpoint for outgoing datagrams (naming is a little bit confusing) + uint8_t ep_out; //!< endpoint for incoming datagrams (naming is a little bit confusing) + uint8_t ep_notif; //!< endpoint for notifications + uint8_t itf_num; //!< interface number + uint8_t itf_data_alt; //!< ==0 -> no endpoints, i.e. no network traffic, ==1 -> normal operation with two endpoints (spec, chapter 5.3) + uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it + + // recv handling + recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs + recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs + recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic + recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver + recv_ntb_t *recv_glue_ntb; //!< buffer for the running transfer driver -> glue logic + uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram + + // xmit handling + xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs + xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs + xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB + xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB + xmit_ntb_t *xmit_glue_ntb; //!< buffer for the running transfer glue logic -> driver + uint16_t xmit_sequence; //!< NTB sequence counter + uint16_t xmit_glue_ntb_datagram_ndx; //!< index into \a xmit_glue_ntb_datagram + + // notification handling + enum { + NOTIFICATION_SPEED, + NOTIFICATION_CONNECTED, + NOTIFICATION_DONE + } notification_xmit_state; //!< state of notification transmission + bool notification_xmit_is_running; //!< notification is currently transmitted +} ncm_interface_t; + -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; -#define NTH16_SIGNATURE 0x484D434E -#define NDP16_SIGNATURE_NCM0 0x304D434E -#define NDP16_SIGNATURE_NCM1 0x314D434E -typedef struct TU_ATTR_PACKED +/** + * This is the NTB parameter structure + * + * \attention + * We are lucky, that byte order is correct + */ +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, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 6 // 0=no limit +}; + +// Some confusing remarks about wNtbOutMaxDatagrams... +// ==1 -> SystemView packets/s goes up to 2000 and events are lost during startup +// ==0 -> SystemView runs fine, iperf shows in wireshark a lot of error +// ==6 -> SystemView runs fine, iperf also +// >6 -> iperf starts to show errors +// -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? +// switch \a INFO_OUT on to see interesting values for this. +// +// iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done +// sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 +// + +//----------------------------------------------------------------------------- +// +// everything about notifications +// +tu_static struct ncm_notify_t 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_t 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, +}; + + + +static void notification_xmit(uint8_t rhport, bool force_next) +/** + * Transmit next notification to the host (if appropriate). + * Notifications are transferred to the host once during connection setup. + */ { - 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 + DEBUG_OUT("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); + + if ( !force_next && ncm_interface.notification_xmit_is_running) { + return; + } + + if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { + DEBUG_OUT(" NOTIFICATION_SPEED\n"); + 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.notification_xmit_state = NOTIFICATION_CONNECTED; + ncm_interface.notification_xmit_is_running = true; + } + else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { + DEBUG_OUT(" NOTIFICATION_CONNECTED\n"); + 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.notification_xmit_state = NOTIFICATION_DONE; + ncm_interface.notification_xmit_is_running = true; + } + else { + DEBUG_OUT(" NOTIFICATION_FINISHED\n"); + } +} // notification_xmit + + +//----------------------------------------------------------------------------- +// +// everything about packet transmission (driver -> TinyUSB) +// + + +static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) +/** + * Put NTB into the transmitter free list. + */ { - uint32_t dwSignature; - uint16_t wHeaderLength; - uint16_t wSequence; - uint16_t wBlockLength; - uint16_t wNdpIndex; -} nth16_t; - -typedef struct TU_ATTR_PACKED + DEBUG_OUT("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); + + if (free_ntb == NULL) { + // can happen due to ZLPs + return; + } + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] == NULL) { + ncm_interface.xmit_free_ntb[i] = free_ntb; + return; + } + } + ERROR_OUT("xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen +} // xmit_put_ntb_into_free_list + + + +static xmit_ntb_t *xmit_get_free_ntb(void) +/** + * Get an NTB from the free list + */ { - uint16_t wDatagramIndex; - uint16_t wDatagramLength; -} ndp16_datagram_t; + DEBUG_OUT("xmit_get_free_ntb()\n"); + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] != NULL) { + xmit_ntb_t *free = ncm_interface.xmit_free_ntb[i]; + ncm_interface.xmit_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // xmit_get_free_ntb -typedef struct TU_ATTR_PACKED + + +static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) +/** + * Put a filled NTB into the ready list + */ { - 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 + INFO_OUT("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->len); + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_ready_ntb[i] == NULL) { + ncm_interface.xmit_ready_ntb[i] = ready_ntb; + return; + } + } + ERROR_OUT("xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen +} // xmit_put_ntb_into_ready_list + + + +static xmit_ntb_t *xmit_get_next_ready_ntb(void) +/** + * Get the next NTB from the ready list (and remove it from the list). + * If the ready list is empty, return NULL. + */ { - tusb_control_request_t header; - uint32_t downlink, uplink; -}; + xmit_ntb_t *r = NULL; -typedef struct + r = ncm_interface.xmit_ready_ntb[0]; + memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); + + DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); + return r; +} // xmit_get_next_ready_ntb + + + +static bool xmit_insert_required_zlp(uint8_t rhport, uint16_t xferred_bytes) +/** + * Transmit a ZLP if required + * + * \note + * Insertion of the ZLPs is a little bit different then described in the spec. + * But the below implementation actually works. Don't know if this is a spec + * or TinyUSB issue. + * + * \pre + * This must be called from netd_xfer_cb() so that ep_in is ready + */ { - 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 + DEBUG_OUT("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); - uint8_t ep_notif; - uint8_t ep_in; - uint8_t ep_out; + if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { + return false; + } - const ndp16_t *ndp; - uint8_t num_datagrams, current_datagram_index; + TU_ASSERT(ncm_interface.itf_data_alt == 1, false); + TU_ASSERT( !usbd_edpt_busy(rhport, ncm_interface.ep_in), false); - enum { - REPORT_SPEED, - REPORT_CONNECTED, - REPORT_DONE - } report_state; - bool report_pending; + INFO_OUT("xmit_insert_required_zlp! (%u)\n", (unsigned)xferred_bytes); - 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 + // start transmission of the ZLP + usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); - uint16_t nth_sequence; // Sequence number counter for transmitted NTBs + return true; +} // xmit_insert_required_zlp - bool transferring; -} ncm_interface_t; -//--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION -//--------------------------------------------------------------------+ - -CFG_TUD_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 -}; +static void xmit_start_if_possible(uint8_t rhport) +/** + * Start transmission if it there is a waiting packet and if can be done from interface side. + */ +{ + DEBUG_OUT("xmit_start_if_possible()\n"); -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; + if (ncm_interface.xmit_tinyusb_ntb != NULL) { + DEBUG_OUT(" !xmit_start_if_possible 1\n"); + return; + } + if (ncm_interface.itf_data_alt != 1) { + ERROR_OUT(" !xmit_start_if_possible 2\n"); + return; + } + if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { + INFO_OUT(" !xmit_start_if_possible 3\n"); + return; + } -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; + ncm_interface.xmit_tinyusb_ntb = xmit_get_next_ready_ntb(); + if (ncm_interface.xmit_tinyusb_ntb == NULL) { + if (ncm_interface.xmit_glue_ntb == NULL || ncm_interface.xmit_glue_ntb_datagram_ndx == 0) { + // -> really nothing is waiting + return; + } + ncm_interface.xmit_tinyusb_ntb = ncm_interface.xmit_glue_ntb; + ncm_interface.xmit_glue_ntb = NULL; + } + +#if DEBUG_OUT_ENABLED + { + uint16_t len = ncm_interface.xmit_tinyusb_ntb->ntb.nth.wBlockLength; + DEBUG_OUT(" %d\n", len); + for (int i = 0; i < len; ++i) { + DEBUG_OUT(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); + } + DEBUG_OUT("\n"); + } +#endif + + if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { + DEBUG_OUT(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->len, ncm_interface.xmit_glue_ntb_datagram_ndx); + } -tu_static ncm_interface_t ncm_interface; + // Kick off an endpoint transfer + usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); +} // xmit_start_if_possible -/* - * Set up the NTB state in ncm_interface to be ready to add datagrams. + + +static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size) +/** + * check if a new datagram fits into the current NTB */ -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)); -} +{ + DEBUG_OUT("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); -/* - * If not already transmitting, start sending the current NTB to the host and swap buffers - * to start filling the other one with datagrams. + if (ncm_interface.xmit_glue_ntb == NULL) { + return false; + } + if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB) { + return false; + } + if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + return false; + } + return true; +} // xmit_requested_datagram_fits_into_current_ntb + + + +static bool xmit_setup_next_glue_ntb(void) +/** + * Setup an NTB for the glue logic */ -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, - }, -}; + DEBUG_OUT("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); + + if (ncm_interface.xmit_glue_ntb != NULL) { + // put NTB into waiting list (the new datagram did not fit in) + xmit_put_ntb_into_ready_list(ncm_interface.xmit_glue_ntb); + } + + ncm_interface.xmit_glue_ntb = xmit_get_free_ntb(); // get next buffer (if any) + if (ncm_interface.xmit_glue_ntb == NULL) { + DEBUG_OUT(" xmit_setup_next_glue_ntb - nothing free\n"); // should happen rarely + return false; + } + + ncm_interface.xmit_glue_ntb_datagram_ndx = 0; + + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(ntb->nth); + ntb->nth.wSequence = ncm_interface.xmit_sequence++; + ntb->nth.wBlockLength = sizeof(ntb->nth) + sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->nth.wNdpIndex = sizeof(ntb->nth); + + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->ndp.wNextNdpIndex = 0; + + memset(ntb->ndp_datagram, 0, sizeof(ntb->ndp_datagram)); + return true; +} // xmit_setup_next_glue_ntb + -tu_static struct ecm_notify_struct ncm_notify_speed_change = +//----------------------------------------------------------------------------- +// +// all the recv_*() stuff (TinyUSB -> driver -> glue logic) +// + + +static recv_ntb_t *recv_get_free_ntb(void) +/** + * Return pointer to an available receive buffer or NULL. + * Returned buffer (if any) has the size \a CFG_TUD_NCM_OUT_NTB_MAX_SIZE. + */ { - .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, -}; + DEBUG_OUT("recv_get_free_ntb()\n"); -void tud_network_recv_renew(void) + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] != NULL) { + recv_ntb_t *free = ncm_interface.recv_free_ntb[i]; + ncm_interface.recv_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // recv_get_free_ntb + + + +static recv_ntb_t *recv_get_next_ready_ntb(void) +/** + * Get the next NTB from the ready list (and remove it from the list). + * If the ready list is empty, return NULL. + */ { - if (!ncm_interface.num_datagrams) - { - usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); - return; - } + recv_ntb_t *r = NULL; - const ndp16_t *ndp = ncm_interface.ndp; - const int i = ncm_interface.current_datagram_index; - ncm_interface.current_datagram_index++; - ncm_interface.num_datagrams--; + r = ncm_interface.recv_ready_ntb[0]; + memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); - tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); -} + DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); + return r; +} // recv_get_next_ready_ntb -//--------------------------------------------------------------------+ -// USBD Driver API -//--------------------------------------------------------------------+ -void netd_init(void) + +static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) +/** + * + */ { - 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(); -} + DEBUG_OUT("recv_put_ntb_into_free_list(%p)\n", free_ntb); -void netd_reset(uint8_t rhport) + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] == NULL) { + ncm_interface.recv_free_ntb[i] = free_ntb; + return; + } + } + ERROR_OUT("recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen +} // recv_put_ntb_into_free_list + + + +static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) +/** + * The \a ncm_interface.recv_tinyusb_ntb is filled, + * put this buffer into the waiting list and free the receive logic. + */ { - (void) rhport; + DEBUG_OUT("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->len); + + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_ready_ntb[i] == NULL) { + ncm_interface.recv_ready_ntb[i] = ready_ntb; + return; + } + } + ERROR_OUT("recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen +} // recv_put_ntb_into_ready_list + - netd_init(); -} -uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +static void recv_try_to_start_new_reception(uint8_t rhport) +/** + * If possible, start a new reception TinyUSB -> driver. + * Return value is actually not of interest. + */ { - // confirm interface hasn't already been allocated - TU_ASSERT(0 == ncm_interface.ep_notif, 0); + DEBUG_OUT("recv_try_to_start_new_reception(%d)\n", rhport); - //------------- Management Interface -------------// - ncm_interface.itf_num = itf_desc->bInterfaceNumber; + if (ncm_interface.itf_data_alt != 1) { + return; + } + if (ncm_interface.recv_tinyusb_ntb != NULL) { + return; + } + if (usbd_edpt_busy(ncm_interface.rhport, ncm_interface.ep_out)) { + return; + } - uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const * p_desc = tu_desc_next( itf_desc ); + ncm_interface.recv_tinyusb_ntb = recv_get_free_ntb(); + if (ncm_interface.recv_tinyusb_ntb == NULL) { + return; + } - // 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); - } + // initiate transfer + DEBUG_OUT(" start reception\n"); + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + if ( !r) { + recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); + ncm_interface.recv_tinyusb_ntb = NULL; + } +} // recv_try_to_start_new_reception - // 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); - } +static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) +/** + * Validate incoming datagram. + * \return true if valid + * + * \note + * \a ndp16->wNextNdpIndex != 0 is not supported + */ +{ + const nth16_t *nth16 = &(ntb->nth); - //------------- 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); + DEBUG_OUT("recv_validate_datagram(%p)\n", ntb); - 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); + // + // check header + // + if (nth16->wHeaderLength != sizeof(nth16_t)) + { + ERROR_OUT(" ill nth16 length: %d\n", nth16->wHeaderLength); + return false; + } + if (nth16->dwSignature != NTH16_SIGNATURE) { + ERROR_OUT(" ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); + return false; + } + if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + ERROR_OUT(" ill min len: %d\n", len); + return false; + } + if (nth16->wBlockLength > len) { + ERROR_OUT(" ill block length: %d > %d\n", nth16->wBlockLength, len); + return false; + } + if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + ERROR_OUT(" ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + return false; + } + if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t))) { + ERROR_OUT(" ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + return false; + } - 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)); + // + // check (first) NDP(16) + // + const ndp16_t *ndp16 = (ndp16_t *)(ntb->data + nth16->wNdpIndex); - // Pair of endpoints - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); + if (ndp16->wLength < sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + ERROR_OUT(" ill ndp16 length: %d\n", ndp16->wLength); + return false; + } + if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { + ERROR_OUT(" ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); + return false; + } + if (ndp16->wNextNdpIndex != 0) { + ERROR_OUT(" cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + return false; + } - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in) ); + const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *)(ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); + int ndx = 0; + int max_ndx = (ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t); - drv_len += 2*sizeof(tusb_desc_endpoint_t); + if (max_ndx > 2) { + // number of datagrams in NTB > 1 + INFO_OUT("<< %d (%d)\n", max_ndx - 1, ntb->len); + } + if (ndp16_datagram[max_ndx-1].wDatagramIndex != 0 || ndp16_datagram[max_ndx-1].wDatagramLength != 0) { + INFO_OUT(" max_ndx != 0\n"); + return false; + } + while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { + DEBUG_OUT(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); + if (ndp16_datagram[ndx].wDatagramIndex > len) { + ERROR_OUT(" ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + return false; + } + if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { + ERROR_OUT(" ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + return false; + } + ++ndx; + } + + for (int i = 0; i < len; ++i) { + DEBUG_OUT(" %02x", ntb->data[i]); + } + DEBUG_OUT("\n"); + + // -> ntb contains a valid packet structure + // ok... I did not check for garbage within the datagram indices... + return true; +} // recv_validate_datagram - 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) +static void recv_transfer_datagram_to_glue_logic(void) +/** + * Transfer the next (pending) datagram to the glue logic and return receive buffer if empty. + */ { - 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); + DEBUG_OUT("recv_transfer_datagram_to_glue_logic()\n"); + + if (ncm_interface.recv_glue_ntb == NULL) { + ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); + DEBUG_OUT(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb_datagram_ndx = 0; + } + + if (ncm_interface.recv_glue_ntb != NULL) { + const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *)(ncm_interface.recv_glue_ntb->data + + ncm_interface.recv_glue_ntb->nth.wNdpIndex + + sizeof(ndp16_t)); + + if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { + ERROR_OUT(" SOMETHING WENT WRONG 1\n"); } - 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(); - } + else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { + ERROR_OUT(" SOMETHING WENT WRONG 2\n"); + } + else { + uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; + uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; + + DEBUG_OUT(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); + if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { + // + // send datagram successfully to glue logic + // + DEBUG_OUT(" OK\n"); + datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; + datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; + + if (datagramIndex != 0 && datagramLength != 0) { + // -> next datagram + ++ncm_interface.recv_glue_ntb_datagram_ndx; + } + else { + // end of datagrams reached + recv_put_ntb_into_free_list(ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb = NULL; + } } + } + } +} // recv_transfer_datagram_to_glue_logic - tud_network_link_state_cb(ncm_interface.itf_data_alt); - } - tud_control_status(rhport, request); - } - break; +//----------------------------------------------------------------------------- +// +// all the tud_network_*() stuff (glue logic -> driver) +// + + +bool tud_network_can_xmit(uint16_t size) +/** + * Check if the glue logic is allowed to call tud_network_xmit(). + * This function also fetches a next buffer if required, so that tud_network_xmit() is ready for copy + * and transmission operation. + */ +{ + DEBUG_OUT("tud_network_can_xmit(%d)\n", size); + + TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)), false); + + if (xmit_requested_datagram_fits_into_current_ntb(size) || xmit_setup_next_glue_ntb()) { + // -> everything is fine + return true; + } + xmit_start_if_possible(ncm_interface.rhport); + ERROR_OUT(" tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + return false; +} // tud_network_can_xmit - // 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)); - } +void tud_network_xmit(void *ref, uint16_t arg) +/** + * Put a datagram into a waiting NTB. + * If currently no transmission is started, then initiate transmission. + */ +{ + DEBUG_OUT("tud_network_xmit(%p, %d)\n", ref, arg); + + if (ncm_interface.xmit_glue_ntb == NULL) { + ERROR_OUT("tud_network_xmit: no buffer\n"); // must not happen (really) + return; + } + + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + + // copy new datagram to the end of the current NTB + uint16_t size = tud_network_xmit_cb(ntb->data + ntb->nth.wBlockLength, ref, arg); + + // correct NTB internals + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramIndex = ntb->nth.wBlockLength; + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; + ncm_interface.xmit_glue_ntb_datagram_ndx += 1; - break; + ntb->nth.wBlockLength += size + XMIT_ALIGN_OFFSET(size); - // unsupported request - default: return false; - } + if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + ERROR_OUT("tud_network_xmit: buffer overflow\n"); // must not happen (really) + return; + } + + xmit_start_if_possible(ncm_interface.rhport); +} // tud_network_xmit - return true; -} -static void handle_incoming_datagram(uint32_t len) + +void tud_network_recv_renew(void) +/** + * Keep the receive logic busy and transfer pending packets to the glue logic. + */ { - uint32_t size = len; + DEBUG_OUT("tud_network_recv_renew()\n"); - if (len == 0) { - return; - } + recv_transfer_datagram_to_glue_logic(); + recv_try_to_start_new_reception(ncm_interface.rhport); +} // tud_network_recv_renew - 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, ); +void tud_network_recv_renew_r(uint8_t rhport) +/** + * Same as tud_network_recv_renew() but knows \a rhport + */ +{ + DEBUG_OUT("tud_network_recv_renew_r(%d)\n", rhport); - 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++; - } + ncm_interface.rhport = rhport; + tud_network_recv_renew(); +} // 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) +//----------------------------------------------------------------------------- +// +// all the netd_*() stuff (interface TinyUSB -> driver) +// +void netd_init(void) +/** + * Initialize the driver data structures. + * Might be called several times. + */ { - (void) rhport; - (void) result; + DEBUG_OUT("netd_init()\n"); - /* new datagram receive_ntb */ - if (ep_addr == ncm_interface.ep_out ) - { - handle_incoming_datagram(xferred_bytes); - } + memset( &ncm_interface, 0, sizeof(ncm_interface)); - /* data transmission finished */ - if (ep_addr == ncm_interface.ep_in ) - { - if (ncm_interface.transferring) { - ncm_interface.transferring = false; + for (int i = 0; i < XMIT_NTB_N; ++i) { + ncm_interface.xmit_free_ntb[i] = ncm_interface.xmit_ntb + i; } + for (int i = 0; i < RECV_NTB_N; ++i) { + ncm_interface.recv_free_ntb[i] = ncm_interface.recv_ntb + i; + } +} // netd_init + - // 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(); + +void netd_reset(uint8_t rhport) +/** + * Resets the port. + * In this driver this is the same as netd_init() + */ +{ + DEBUG_OUT("netd_reset(%d)\n", rhport); + + netd_init(); +} // netd_reset + + + +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +/** + * Open the USB interface. + * - parse the USB descriptor \a TUD_CDC_NCM_DESCRIPTOR for itfnum and endpoints + * - a specific order of elements in the descriptor is tested. + * + * \note + * Actually all of the information could be read directly from \a itf_desc, because the + * structure and the values are well known. But we do it this way. + * + * \post + * - \a itf_num set + * - \a ep_notif, \a ep_in and \a ep_out are set + * - USB interface is open + */ +{ + DEBUG_OUT("netd_open(%d,%p,%d)\n", rhport, itf_desc, max_len); + + TU_ASSERT(ncm_interface.ep_notif == 0, 0); // assure that the interface is only opened once + + ncm_interface.itf_num = itf_desc->bInterfaceNumber; // management interface + + // + // skip the two first entries and the following TUSB_DESC_CS_INTERFACE entries + // + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const *p_desc = tu_desc_next(itf_desc); + while (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && drv_len <= max_len) { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); } - } - if (ep_addr == ncm_interface.ep_notif ) - { - ncm_interface.report_pending = false; - ncm_report(); - } + // + // get notification endpoint + // + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); + 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); - return true; -} + // + // skip the following TUSB_DESC_INTERFACE entries (which must be TUSB_CLASS_CDC_DATA) + // + while (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && drv_len <= max_len) { + tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const*)p_desc; + TU_ASSERT(data_itf_desc->bInterfaceClass == TUSB_CLASS_CDC_DATA, 0); -// poll network driver for its ability to accept another packet to transmit -bool tud_network_can_xmit(uint16_t size) + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // + // a TUSB_DESC_ENDPOINT (actually two) must follow, open these endpoints + // + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 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; +} // netd_open + + + +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +/** + * Handle TinyUSB requests to process transfer events. + */ { - TU_VERIFY(ncm_interface.itf_data_alt == 1); + DEBUG_OUT("netd_xfer_cb(%d,%d,%d,%u)\n", rhport, ep_addr, result, (unsigned)xferred_bytes); + + if (ep_addr == ncm_interface.ep_out) { + // + // new NTB received + // - make the NTB valid + // - if ready transfer datagrams to the glue logic for further processing + // - if there is a free receive buffer, initiate reception + // + DEBUG_OUT(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); + if ( !recv_validate_datagram( ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { + // verification failed: ignore NTB and return it to free + ERROR_OUT(" VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + } + else { + // packet ok -> put it into ready list + recv_put_ntb_into_ready_list(ncm_interface.recv_tinyusb_ntb); + } + ncm_interface.recv_tinyusb_ntb = NULL; + tud_network_recv_renew_r(rhport); + } + else if (ep_addr == ncm_interface.ep_in) { + // + // transmission of an NTB finished + // - free the transmitted NTB buffer + // - insert ZLPs when necessary + // - if there is another transmit NTB waiting, try to start transmission + // + DEBUG_OUT(" EP_IN %d %u\n", ncm_interface.itf_data_alt, (unsigned)xferred_bytes); + xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); + ncm_interface.xmit_tinyusb_ntb = NULL; + if ( !xmit_insert_required_zlp(rhport, xferred_bytes)) { + xmit_start_if_possible(rhport); + } + } + else if (ep_addr == ncm_interface.ep_notif) { + // + // next transfer on notification channel + // + DEBUG_OUT(" EP_NOTIF\n"); + notification_xmit(rhport, true); + } - if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { - TU_LOG_DRV("NTB full [by count]\r\n"); - return false; - } + return true; +} // netd_xfer_cb - size_t next_datagram_offset = ncm_interface.next_datagram_offset; - if (next_datagram_offset + size > ncm_interface.ntb_in_size) { - TU_LOG_DRV("ntb full [by size]\r\n"); - return false; - } - return true; -} -void tud_network_xmit(void *ref, uint16_t arg) +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +/** + * Respond to TinyUSB control requests. + * At startup transmission of notification packets are done here. + */ { - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t next_datagram_offset = ncm_interface.next_datagram_offset; + DEBUG_OUT("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, request); - uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); + if (stage != CONTROL_STAGE_SETUP) { + return true; + } - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; + switch (request->bmRequestType_bit.type) { + case TUSB_REQ_TYPE_STANDARD: + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); + + DEBUG_OUT(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + } + break; + + case TUSB_REQ_SET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); + + ncm_interface.itf_data_alt = request->wValue; + DEBUG_OUT(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); + + if (ncm_interface.itf_data_alt == 1) { + tud_network_recv_renew_r(rhport); + notification_xmit(rhport, false); + } + tud_control_status(rhport, request); + } + break; + + // unsupported request + default: + return false; + } + break; - ncm_interface.datagram_count++; - next_datagram_offset += size; + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - // 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); + DEBUG_OUT(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - ncm_interface.next_datagram_offset = next_datagram_offset; + if (request->bRequest == NCM_GET_NTB_PARAMETERS) { + // transfer NTB parameters to host. + // TODO can one assume, that tud_control_xfer() succeeds? + DEBUG_OUT(" NCM_GET_NTB_PARAMETERS\n"); + tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } + break; - ncm_start_tx(); -} + // unsupported request + default: + return false ; + } -#endif + return true; +} // netd_control_xfer_cb + +#endif // ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 399916355..111c822fb 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -28,14 +28,13 @@ #ifndef _TUSB_NET_DEVICE_H_ #define _TUSB_NET_DEVICE_H_ +#include #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) @@ -44,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 8 -#endif - -#ifndef CFG_TUD_NCM_ALIGNMENT -#define CFG_TUD_NCM_ALIGNMENT 4 -#endif #ifdef __cplusplus extern "C" { @@ -92,12 +76,6 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); // 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); -- cgit v1.3.1 From d5da303f450ce0e1004121af4a40a512371e9353 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: moved some declarations --- src/class/net/ncm.h | 7 ------- src/class/net/net_device.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index 313237747..c768192a5 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -71,13 +71,6 @@ #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 { diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 111c822fb..3342dac3d 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -44,6 +44,13 @@ #endif +// Table 4.3 Data Class Interface Protocol Codes +typedef enum +{ + NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 +} ncm_data_interface_protocol_code_t; + + #ifdef __cplusplus extern "C" { #endif @@ -76,6 +83,10 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); // 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]; + // callback to client providing optional indication of internal state of network driver void tud_network_link_state_cb(bool state); -- cgit v1.3.1 From e4c18c101cf5dc78f6bd1034aae7f0f7e22b7e47 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: Copyright --- src/class/net/ncm_device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index f7a236e69..28066b6af 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2023 Hardy Griech + * 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 -- cgit v1.3.1 From 28107326da6cbc462bf6644f1f6edd5d0bcb43b8 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: bug fix recv/xmit_get_next_ready_ntb() --- src/class/net/ncm_device.c | 58 ++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 28 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 28066b6af..65543fcab 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -254,7 +254,7 @@ static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) return; } } - ERROR_OUT("xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen + ERROR_OUT("(EE) xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen } // xmit_put_ntb_into_free_list @@ -283,7 +283,7 @@ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) * Put a filled NTB into the ready list */ { - INFO_OUT("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->len); + INFO_OUT("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); for (int i = 0; i < XMIT_NTB_N; ++i) { if (ncm_interface.xmit_ready_ntb[i] == NULL) { @@ -291,7 +291,7 @@ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) return; } } - ERROR_OUT("xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen + ERROR_OUT("(EE) xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen } // xmit_put_ntb_into_ready_list @@ -306,6 +306,7 @@ static xmit_ntb_t *xmit_get_next_ready_ntb(void) r = ncm_interface.xmit_ready_ntb[0]; memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); + ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); return r; @@ -357,7 +358,7 @@ static void xmit_start_if_possible(uint8_t rhport) return; } if (ncm_interface.itf_data_alt != 1) { - ERROR_OUT(" !xmit_start_if_possible 2\n"); + ERROR_OUT("(II) !xmit_start_if_possible 2\n"); return; } if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { @@ -375,9 +376,9 @@ static void xmit_start_if_possible(uint8_t rhport) ncm_interface.xmit_glue_ntb = NULL; } -#if DEBUG_OUT_ENABLED +#ifdef DEBUG_OUT_ENABLED { - uint16_t len = ncm_interface.xmit_tinyusb_ntb->ntb.nth.wBlockLength; + uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; DEBUG_OUT(" %d\n", len); for (int i = 0; i < len; ++i) { DEBUG_OUT(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); @@ -387,7 +388,7 @@ static void xmit_start_if_possible(uint8_t rhport) #endif if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { - DEBUG_OUT(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->len, ncm_interface.xmit_glue_ntb_datagram_ndx); + DEBUG_OUT(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); } // Kick off an endpoint transfer @@ -492,6 +493,7 @@ static recv_ntb_t *recv_get_next_ready_ntb(void) r = ncm_interface.recv_ready_ntb[0]; memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); + ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); return r; @@ -512,7 +514,7 @@ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) return; } } - ERROR_OUT("recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen + ERROR_OUT("(EE) recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen } // recv_put_ntb_into_free_list @@ -523,7 +525,7 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) * put this buffer into the waiting list and free the receive logic. */ { - DEBUG_OUT("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->len); + DEBUG_OUT("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_ready_ntb[i] == NULL) { @@ -531,7 +533,7 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) return; } } - ERROR_OUT("recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen + ERROR_OUT("(EE) recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen } // recv_put_ntb_into_ready_list @@ -588,27 +590,27 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) // if (nth16->wHeaderLength != sizeof(nth16_t)) { - ERROR_OUT(" ill nth16 length: %d\n", nth16->wHeaderLength); + ERROR_OUT("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); return false; } if (nth16->dwSignature != NTH16_SIGNATURE) { - ERROR_OUT(" ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); + ERROR_OUT("(EE) ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); return false; } if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - ERROR_OUT(" ill min len: %d\n", len); + ERROR_OUT("(EE) ill min len: %d\n", len); return false; } if (nth16->wBlockLength > len) { - ERROR_OUT(" ill block length: %d > %d\n", nth16->wBlockLength, len); + ERROR_OUT("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); return false; } if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - ERROR_OUT(" ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + ERROR_OUT("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); return false; } if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t))) { - ERROR_OUT(" ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + ERROR_OUT("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); return false; } @@ -618,15 +620,15 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) const ndp16_t *ndp16 = (ndp16_t *)(ntb->data + nth16->wNdpIndex); if (ndp16->wLength < sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - ERROR_OUT(" ill ndp16 length: %d\n", ndp16->wLength); + ERROR_OUT("(EE) ill ndp16 length: %d\n", ndp16->wLength); return false; } if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { - ERROR_OUT(" ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); + ERROR_OUT("(EE) ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); return false; } if (ndp16->wNextNdpIndex != 0) { - ERROR_OUT(" cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + ERROR_OUT("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); return false; } @@ -636,7 +638,7 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) if (max_ndx > 2) { // number of datagrams in NTB > 1 - INFO_OUT("<< %d (%d)\n", max_ndx - 1, ntb->len); + INFO_OUT("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); } if (ndp16_datagram[max_ndx-1].wDatagramIndex != 0 || ndp16_datagram[max_ndx-1].wDatagramLength != 0) { INFO_OUT(" max_ndx != 0\n"); @@ -645,11 +647,11 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { DEBUG_OUT(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); if (ndp16_datagram[ndx].wDatagramIndex > len) { - ERROR_OUT(" ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + ERROR_OUT("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); return false; } if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { - ERROR_OUT(" ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + ERROR_OUT("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); return false; } ++ndx; @@ -686,10 +688,10 @@ static void recv_transfer_datagram_to_glue_logic(void) + sizeof(ndp16_t)); if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { - ERROR_OUT(" SOMETHING WENT WRONG 1\n"); + ERROR_OUT("(EE) SOMETHING WENT WRONG 1\n"); } else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { - ERROR_OUT(" SOMETHING WENT WRONG 2\n"); + ERROR_OUT("(EE) SOMETHING WENT WRONG 2\n"); } else { uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; @@ -741,7 +743,7 @@ bool tud_network_can_xmit(uint16_t size) return true; } xmit_start_if_possible(ncm_interface.rhport); - ERROR_OUT(" tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + ERROR_OUT("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit @@ -756,7 +758,7 @@ void tud_network_xmit(void *ref, uint16_t arg) DEBUG_OUT("tud_network_xmit(%p, %d)\n", ref, arg); if (ncm_interface.xmit_glue_ntb == NULL) { - ERROR_OUT("tud_network_xmit: no buffer\n"); // must not happen (really) + ERROR_OUT("(EE) tud_network_xmit: no buffer\n"); // must not happen (really) return; } @@ -773,7 +775,7 @@ void tud_network_xmit(void *ref, uint16_t arg) ntb->nth.wBlockLength += size + XMIT_ALIGN_OFFSET(size); if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - ERROR_OUT("tud_network_xmit: buffer overflow\n"); // must not happen (really) + ERROR_OUT("(II) tud_network_xmit: buffer overflow\n"); // must not happen (really) return; } @@ -925,7 +927,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ DEBUG_OUT(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); if ( !recv_validate_datagram( ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { // verification failed: ignore NTB and return it to free - ERROR_OUT(" VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + ERROR_OUT("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); } else { // packet ok -> put it into ready list -- cgit v1.3.1 From 2c1addff4f853586c8d9590e3f93d79fc7c6e250 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:27:06 +0200 Subject: defined(ECLIPSE_GUI) --- src/class/net/ncm_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 65543fcab..1c6f888cd 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -46,7 +46,7 @@ #include "tusb_option.h" -#if ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if defined(ECLIPSE_GUI) || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) #include #include -- cgit v1.3.1 From 1dd9fa3f307e6f3a847619d587529ea17608c1a3 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 31 Aug 2023 20:24:56 +0200 Subject: code review: changed to TinyUSB log system --- src/class/net/ncm_device.c | 205 +++++++++++++++++++++------------------------ 1 file changed, 96 insertions(+), 109 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 1c6f888cd..d0832cf73 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -59,30 +59,11 @@ #include "ncm.h" -#if !defined(tu_static) || ECLIPSE_GUI +#if !defined(tu_static) || defined(ECLIPSE_GUI) // TinyUSB <=0.15.0 does not know "tu_static" #define tu_static static #endif -#if 0 - #define DEBUG_OUT(...) printf(__VA_ARGS__) - #define DEBUG_OUT_ENABLED -#else - #define DEBUG_OUT(...) -#endif - -#if 0 - #define INFO_OUT(...) printf(__VA_ARGS__) -#else - #define INFO_OUT(...) -#endif - -#if 1 - #define ERROR_OUT(...) printf(__VA_ARGS__) -#else - #define ERROR_OUT(...) -#endif - // calculate alignment of xmit datagrams within an NTB #define XMIT_ALIGN_OFFSET(x) ((CFG_TUD_NCM_ALIGNMENT - ((x) & (CFG_TUD_NCM_ALIGNMENT - 1))) & (CFG_TUD_NCM_ALIGNMENT - 1)) @@ -103,7 +84,7 @@ typedef struct { uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it // recv handling - recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver @@ -111,7 +92,7 @@ typedef struct { uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram // xmit handling - xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB @@ -159,7 +140,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par // ==6 -> SystemView runs fine, iperf also // >6 -> iperf starts to show errors // -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? -// switch \a INFO_OUT on to see interesting values for this. +// switch \a TU_LOG2 on to see interesting values for this. // // iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done // sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 @@ -192,8 +173,8 @@ tu_static struct ncm_notify_t ncm_notify_speed_change = { .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wLength = 8, }, - .downlink = 1000000, - .uplink = 1000000, + .downlink = 12000000, + .uplink = 12000000, }; @@ -204,28 +185,28 @@ static void notification_xmit(uint8_t rhport, bool force_next) * Notifications are transferred to the host once during connection setup. */ { - DEBUG_OUT("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); + TU_LOG3("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); if ( !force_next && ncm_interface.notification_xmit_is_running) { return; } if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { - DEBUG_OUT(" NOTIFICATION_SPEED\n"); + TU_LOG3(" NOTIFICATION_SPEED\n"); 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.notification_xmit_state = NOTIFICATION_CONNECTED; ncm_interface.notification_xmit_is_running = true; } else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { - DEBUG_OUT(" NOTIFICATION_CONNECTED\n"); + TU_LOG3(" NOTIFICATION_CONNECTED\n"); 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.notification_xmit_state = NOTIFICATION_DONE; ncm_interface.notification_xmit_is_running = true; } else { - DEBUG_OUT(" NOTIFICATION_FINISHED\n"); + TU_LOG3(" NOTIFICATION_FINISHED\n"); } } // notification_xmit @@ -241,7 +222,7 @@ static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) * Put NTB into the transmitter free list. */ { - DEBUG_OUT("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); + TU_LOG3("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); if (free_ntb == NULL) { // can happen due to ZLPs @@ -254,7 +235,7 @@ static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) return; } } - ERROR_OUT("(EE) xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen + TU_LOG1("(EE) xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen } // xmit_put_ntb_into_free_list @@ -264,7 +245,7 @@ static xmit_ntb_t *xmit_get_free_ntb(void) * Get an NTB from the free list */ { - DEBUG_OUT("xmit_get_free_ntb()\n"); + TU_LOG3("xmit_get_free_ntb()\n"); for (int i = 0; i < XMIT_NTB_N; ++i) { if (ncm_interface.xmit_free_ntb[i] != NULL) { @@ -283,7 +264,7 @@ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) * Put a filled NTB into the ready list */ { - INFO_OUT("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); + TU_LOG2("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); for (int i = 0; i < XMIT_NTB_N; ++i) { if (ncm_interface.xmit_ready_ntb[i] == NULL) { @@ -291,7 +272,7 @@ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) return; } } - ERROR_OUT("(EE) xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen + TU_LOG1("(EE) xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen } // xmit_put_ntb_into_ready_list @@ -308,13 +289,13 @@ static xmit_ntb_t *xmit_get_next_ready_ntb(void) memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; - DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); + TU_LOG3("recv_get_next_ready_ntb: %p\n", r); return r; } // xmit_get_next_ready_ntb -static bool xmit_insert_required_zlp(uint8_t rhport, uint16_t xferred_bytes) +static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) /** * Transmit a ZLP if required * @@ -327,7 +308,7 @@ static bool xmit_insert_required_zlp(uint8_t rhport, uint16_t xferred_bytes) * This must be called from netd_xfer_cb() so that ep_in is ready */ { - DEBUG_OUT("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); + TU_LOG3("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { return false; @@ -336,7 +317,7 @@ static bool xmit_insert_required_zlp(uint8_t rhport, uint16_t xferred_bytes) TU_ASSERT(ncm_interface.itf_data_alt == 1, false); TU_ASSERT( !usbd_edpt_busy(rhport, ncm_interface.ep_in), false); - INFO_OUT("xmit_insert_required_zlp! (%u)\n", (unsigned)xferred_bytes); + TU_LOG2("xmit_insert_required_zlp! (%u)\n", (unsigned)xferred_bytes); // start transmission of the ZLP usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); @@ -351,18 +332,18 @@ static void xmit_start_if_possible(uint8_t rhport) * Start transmission if it there is a waiting packet and if can be done from interface side. */ { - DEBUG_OUT("xmit_start_if_possible()\n"); + TU_LOG3("xmit_start_if_possible()\n"); if (ncm_interface.xmit_tinyusb_ntb != NULL) { - DEBUG_OUT(" !xmit_start_if_possible 1\n"); + TU_LOG3(" !xmit_start_if_possible 1\n"); return; } if (ncm_interface.itf_data_alt != 1) { - ERROR_OUT("(II) !xmit_start_if_possible 2\n"); + TU_LOG1("(II) !xmit_start_if_possible 2\n"); return; } if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { - INFO_OUT(" !xmit_start_if_possible 3\n"); + TU_LOG2(" !xmit_start_if_possible 3\n"); return; } @@ -379,16 +360,16 @@ static void xmit_start_if_possible(uint8_t rhport) #ifdef DEBUG_OUT_ENABLED { uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; - DEBUG_OUT(" %d\n", len); + TU_LOG3(" %d\n", len); for (int i = 0; i < len; ++i) { - DEBUG_OUT(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); + TU_LOG3(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); } - DEBUG_OUT("\n"); + TU_LOG3("\n"); } #endif if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { - DEBUG_OUT(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); + TU_LOG3(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); } // Kick off an endpoint transfer @@ -402,7 +383,7 @@ static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size * check if a new datagram fits into the current NTB */ { - DEBUG_OUT("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); + TU_LOG3("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); if (ncm_interface.xmit_glue_ntb == NULL) { return false; @@ -423,7 +404,7 @@ static bool xmit_setup_next_glue_ntb(void) * Setup an NTB for the glue logic */ { - DEBUG_OUT("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); + TU_LOG3("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); if (ncm_interface.xmit_glue_ntb != NULL) { // put NTB into waiting list (the new datagram did not fit in) @@ -432,7 +413,7 @@ static bool xmit_setup_next_glue_ntb(void) ncm_interface.xmit_glue_ntb = xmit_get_free_ntb(); // get next buffer (if any) if (ncm_interface.xmit_glue_ntb == NULL) { - DEBUG_OUT(" xmit_setup_next_glue_ntb - nothing free\n"); // should happen rarely + TU_LOG3(" xmit_setup_next_glue_ntb - nothing free\n"); // should happen rarely return false; } @@ -469,7 +450,7 @@ static recv_ntb_t *recv_get_free_ntb(void) * Returned buffer (if any) has the size \a CFG_TUD_NCM_OUT_NTB_MAX_SIZE. */ { - DEBUG_OUT("recv_get_free_ntb()\n"); + TU_LOG3("recv_get_free_ntb()\n"); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_free_ntb[i] != NULL) { @@ -495,7 +476,7 @@ static recv_ntb_t *recv_get_next_ready_ntb(void) memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; - DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); + TU_LOG3("recv_get_next_ready_ntb: %p\n", r); return r; } // recv_get_next_ready_ntb @@ -506,7 +487,7 @@ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) * */ { - DEBUG_OUT("recv_put_ntb_into_free_list(%p)\n", free_ntb); + TU_LOG3("recv_put_ntb_into_free_list(%p)\n", free_ntb); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_free_ntb[i] == NULL) { @@ -514,7 +495,7 @@ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) return; } } - ERROR_OUT("(EE) recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen + TU_LOG1("(EE) recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen } // recv_put_ntb_into_free_list @@ -525,7 +506,7 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) * put this buffer into the waiting list and free the receive logic. */ { - DEBUG_OUT("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); + TU_LOG3("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_ready_ntb[i] == NULL) { @@ -533,7 +514,7 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) return; } } - ERROR_OUT("(EE) recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen + TU_LOG1("(EE) recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen } // recv_put_ntb_into_ready_list @@ -544,7 +525,7 @@ static void recv_try_to_start_new_reception(uint8_t rhport) * Return value is actually not of interest. */ { - DEBUG_OUT("recv_try_to_start_new_reception(%d)\n", rhport); + TU_LOG3("recv_try_to_start_new_reception(%d)\n", rhport); if (ncm_interface.itf_data_alt != 1) { return; @@ -552,7 +533,7 @@ static void recv_try_to_start_new_reception(uint8_t rhport) if (ncm_interface.recv_tinyusb_ntb != NULL) { return; } - if (usbd_edpt_busy(ncm_interface.rhport, ncm_interface.ep_out)) { + if (usbd_edpt_busy(rhport, ncm_interface.ep_out)) { return; } @@ -562,8 +543,8 @@ static void recv_try_to_start_new_reception(uint8_t rhport) } // initiate transfer - DEBUG_OUT(" start reception\n"); - bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + TU_LOG3(" start reception\n"); + bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); if ( !r) { recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); ncm_interface.recv_tinyusb_ntb = NULL; @@ -572,7 +553,7 @@ static void recv_try_to_start_new_reception(uint8_t rhport) -static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) +static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) /** * Validate incoming datagram. * \return true if valid @@ -583,84 +564,86 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) { const nth16_t *nth16 = &(ntb->nth); - DEBUG_OUT("recv_validate_datagram(%p)\n", ntb); + TU_LOG3("recv_validate_datagram(%p)\n", ntb); // // check header // if (nth16->wHeaderLength != sizeof(nth16_t)) { - ERROR_OUT("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); + TU_LOG1("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); return false; } if (nth16->dwSignature != NTH16_SIGNATURE) { - ERROR_OUT("(EE) ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); + TU_LOG1("(EE) ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); return false; } if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - ERROR_OUT("(EE) ill min len: %d\n", len); + TU_LOG1("(EE) ill min len: %d\n", len); return false; } if (nth16->wBlockLength > len) { - ERROR_OUT("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); + TU_LOG1("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); return false; } if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - ERROR_OUT("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + TU_LOG1("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); return false; } if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t))) { - ERROR_OUT("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + TU_LOG1("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); return false; } // // check (first) NDP(16) // - const ndp16_t *ndp16 = (ndp16_t *)(ntb->data + nth16->wNdpIndex); + const ndp16_t *ndp16 = (const ndp16_t *)(ntb->data + nth16->wNdpIndex); if (ndp16->wLength < sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - ERROR_OUT("(EE) ill ndp16 length: %d\n", ndp16->wLength); + TU_LOG1("(EE) ill ndp16 length: %d\n", ndp16->wLength); return false; } if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { - ERROR_OUT("(EE) ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); + TU_LOG1("(EE) ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); return false; } if (ndp16->wNextNdpIndex != 0) { - ERROR_OUT("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + TU_LOG1("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); return false; } - const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *)(ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); + const ndp16_datagram_t *ndp16_datagram = (const ndp16_datagram_t *)(ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); int ndx = 0; - int max_ndx = (ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t); + uint16_t max_ndx = (uint16_t)((ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t)); if (max_ndx > 2) { // number of datagrams in NTB > 1 - INFO_OUT("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); + TU_LOG2("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); } if (ndp16_datagram[max_ndx-1].wDatagramIndex != 0 || ndp16_datagram[max_ndx-1].wDatagramLength != 0) { - INFO_OUT(" max_ndx != 0\n"); + TU_LOG2(" max_ndx != 0\n"); return false; } while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { - DEBUG_OUT(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); + TU_LOG3(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); if (ndp16_datagram[ndx].wDatagramIndex > len) { - ERROR_OUT("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + TU_LOG1("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); return false; } if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { - ERROR_OUT("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + TU_LOG1("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); return false; } ++ndx; } - for (int i = 0; i < len; ++i) { - DEBUG_OUT(" %02x", ntb->data[i]); +#if CFG_TUSB_DEBUG >= 3 + for (uint32_t i = 0; i < len; ++i) { + TU_LOG3(" %02x", ntb->data[i]); } - DEBUG_OUT("\n"); + TU_LOG3("\n"); +#endif // -> ntb contains a valid packet structure // ok... I did not check for garbage within the datagram indices... @@ -674,11 +657,11 @@ static void recv_transfer_datagram_to_glue_logic(void) * Transfer the next (pending) datagram to the glue logic and return receive buffer if empty. */ { - DEBUG_OUT("recv_transfer_datagram_to_glue_logic()\n"); + TU_LOG3("recv_transfer_datagram_to_glue_logic()\n"); if (ncm_interface.recv_glue_ntb == NULL) { ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); - DEBUG_OUT(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); + TU_LOG3(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); ncm_interface.recv_glue_ntb_datagram_ndx = 0; } @@ -688,21 +671,21 @@ static void recv_transfer_datagram_to_glue_logic(void) + sizeof(ndp16_t)); if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { - ERROR_OUT("(EE) SOMETHING WENT WRONG 1\n"); + TU_LOG1("(EE) SOMETHING WENT WRONG 1\n"); } else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { - ERROR_OUT("(EE) SOMETHING WENT WRONG 2\n"); + TU_LOG1("(EE) SOMETHING WENT WRONG 2\n"); } else { uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; - DEBUG_OUT(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); + TU_LOG3(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { // // send datagram successfully to glue logic // - DEBUG_OUT(" OK\n"); + TU_LOG3(" OK\n"); datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; @@ -734,7 +717,7 @@ bool tud_network_can_xmit(uint16_t size) * and transmission operation. */ { - DEBUG_OUT("tud_network_can_xmit(%d)\n", size); + TU_LOG3("tud_network_can_xmit(%d)\n", size); TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)), false); @@ -743,7 +726,7 @@ bool tud_network_can_xmit(uint16_t size) return true; } xmit_start_if_possible(ncm_interface.rhport); - ERROR_OUT("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + TU_LOG1("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit @@ -755,10 +738,10 @@ void tud_network_xmit(void *ref, uint16_t arg) * If currently no transmission is started, then initiate transmission. */ { - DEBUG_OUT("tud_network_xmit(%p, %d)\n", ref, arg); + TU_LOG3("tud_network_xmit(%p, %d)\n", ref, arg); if (ncm_interface.xmit_glue_ntb == NULL) { - ERROR_OUT("(EE) tud_network_xmit: no buffer\n"); // must not happen (really) + TU_LOG1("(EE) tud_network_xmit: no buffer\n"); // must not happen (really) return; } @@ -772,10 +755,10 @@ void tud_network_xmit(void *ref, uint16_t arg) ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; ncm_interface.xmit_glue_ntb_datagram_ndx += 1; - ntb->nth.wBlockLength += size + XMIT_ALIGN_OFFSET(size); + ntb->nth.wBlockLength += (uint16_t)(size + XMIT_ALIGN_OFFSET(size)); if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - ERROR_OUT("(II) tud_network_xmit: buffer overflow\n"); // must not happen (really) + TU_LOG1("(II) tud_network_xmit: buffer overflow\n"); // must not happen (really) return; } @@ -789,7 +772,7 @@ void tud_network_recv_renew(void) * Keep the receive logic busy and transfer pending packets to the glue logic. */ { - DEBUG_OUT("tud_network_recv_renew()\n"); + TU_LOG3("tud_network_recv_renew()\n"); recv_transfer_datagram_to_glue_logic(); recv_try_to_start_new_reception(ncm_interface.rhport); @@ -802,7 +785,7 @@ void tud_network_recv_renew_r(uint8_t rhport) * Same as tud_network_recv_renew() but knows \a rhport */ { - DEBUG_OUT("tud_network_recv_renew_r(%d)\n", rhport); + TU_LOG3("tud_network_recv_renew_r(%d)\n", rhport); ncm_interface.rhport = rhport; tud_network_recv_renew(); @@ -819,7 +802,7 @@ void netd_init(void) * Might be called several times. */ { - DEBUG_OUT("netd_init()\n"); + TU_LOG3("netd_init()\n"); memset( &ncm_interface, 0, sizeof(ncm_interface)); @@ -839,7 +822,9 @@ void netd_reset(uint8_t rhport) * In this driver this is the same as netd_init() */ { - DEBUG_OUT("netd_reset(%d)\n", rhport); + (void)rhport; + + TU_LOG3("netd_reset(%d)\n", rhport); netd_init(); } // netd_reset @@ -862,7 +847,7 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 * - USB interface is open */ { - DEBUG_OUT("netd_open(%d,%p,%d)\n", rhport, itf_desc, max_len); + TU_LOG3("netd_open(%d,%p,%d)\n", rhport, itf_desc, max_len); TU_ASSERT(ncm_interface.ep_notif == 0, 0); // assure that the interface is only opened once @@ -915,7 +900,9 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ * Handle TinyUSB requests to process transfer events. */ { - DEBUG_OUT("netd_xfer_cb(%d,%d,%d,%u)\n", rhport, ep_addr, result, (unsigned)xferred_bytes); + (void)result; + + TU_LOG3("netd_xfer_cb(%d,%d,%d,%u)\n", rhport, ep_addr, result, (unsigned)xferred_bytes); if (ep_addr == ncm_interface.ep_out) { // @@ -924,10 +911,10 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // - if ready transfer datagrams to the glue logic for further processing // - if there is a free receive buffer, initiate reception // - DEBUG_OUT(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); + TU_LOG3(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); if ( !recv_validate_datagram( ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { // verification failed: ignore NTB and return it to free - ERROR_OUT("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + TU_LOG1("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); } else { // packet ok -> put it into ready list @@ -943,7 +930,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // - insert ZLPs when necessary // - if there is another transmit NTB waiting, try to start transmission // - DEBUG_OUT(" EP_IN %d %u\n", ncm_interface.itf_data_alt, (unsigned)xferred_bytes); + TU_LOG3(" EP_IN %d %u\n", ncm_interface.itf_data_alt, (unsigned)xferred_bytes); xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); ncm_interface.xmit_tinyusb_ntb = NULL; if ( !xmit_insert_required_zlp(rhport, xferred_bytes)) { @@ -954,7 +941,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // // next transfer on notification channel // - DEBUG_OUT(" EP_NOTIF\n"); + TU_LOG3(" EP_NOTIF\n"); notification_xmit(rhport, true); } @@ -969,7 +956,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t * At startup transmission of notification packets are done here. */ { - DEBUG_OUT("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, request); + TU_LOG3("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, request); if (stage != CONTROL_STAGE_SETUP) { return true; @@ -981,7 +968,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case TUSB_REQ_GET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); - DEBUG_OUT(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); + TU_LOG3(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); } break; @@ -989,8 +976,8 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case TUSB_REQ_SET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); - ncm_interface.itf_data_alt = request->wValue; - DEBUG_OUT(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); + ncm_interface.itf_data_alt = (uint8_t)request->wValue; + TU_LOG3(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); if (ncm_interface.itf_data_alt == 1) { tud_network_recv_renew_r(rhport); @@ -1009,12 +996,12 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case TUSB_REQ_TYPE_CLASS: TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - DEBUG_OUT(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); + TU_LOG3(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); if (request->bRequest == NCM_GET_NTB_PARAMETERS) { // transfer NTB parameters to host. // TODO can one assume, that tud_control_xfer() succeeds? - DEBUG_OUT(" NCM_GET_NTB_PARAMETERS\n"); + TU_LOG3(" NCM_GET_NTB_PARAMETERS\n"); tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); } break; -- cgit v1.3.1 From 51ea467350f84b92439d0890a4b12bd55e2eff91 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 31 Aug 2023 20:34:12 +0200 Subject: removed debug comment --- src/class/net/ncm_device.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index d0832cf73..9adb3df0d 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -134,18 +134,6 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNtbOutMaxDatagrams = 6 // 0=no limit }; -// Some confusing remarks about wNtbOutMaxDatagrams... -// ==1 -> SystemView packets/s goes up to 2000 and events are lost during startup -// ==0 -> SystemView runs fine, iperf shows in wireshark a lot of error -// ==6 -> SystemView runs fine, iperf also -// >6 -> iperf starts to show errors -// -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? -// switch \a TU_LOG2 on to see interesting values for this. -// -// iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done -// sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 -// - //----------------------------------------------------------------------------- // // everything about notifications -- cgit v1.3.1 From f1d3663d24f04dbb68732f8287c516abd0b7ecfb Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 8 Sep 2023 07:01:13 +0200 Subject: minor changes to comments and debug output --- src/class/net/ncm_device.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 9adb3df0d..d803d6429 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -59,11 +59,6 @@ #include "ncm.h" -#if !defined(tu_static) || defined(ECLIPSE_GUI) - // TinyUSB <=0.15.0 does not know "tu_static" - #define tu_static static -#endif - // calculate alignment of xmit datagrams within an NTB #define XMIT_ALIGN_OFFSET(x) ((CFG_TUD_NCM_ALIGNMENT - ((x) & (CFG_TUD_NCM_ALIGNMENT - 1))) & (CFG_TUD_NCM_ALIGNMENT - 1)) @@ -84,7 +79,7 @@ typedef struct { uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it // recv handling - CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver @@ -92,7 +87,7 @@ typedef struct { uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram // xmit handling - CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB @@ -327,7 +322,7 @@ static void xmit_start_if_possible(uint8_t rhport) return; } if (ncm_interface.itf_data_alt != 1) { - TU_LOG1("(II) !xmit_start_if_possible 2\n"); + TU_LOG1("(EE) !xmit_start_if_possible 2\n"); return; } if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { @@ -472,7 +467,7 @@ static recv_ntb_t *recv_get_next_ready_ntb(void) static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) /** - * + * Put NTB into the receiver free list. */ { TU_LOG3("recv_put_ntb_into_free_list(%p)\n", free_ntb); @@ -490,8 +485,8 @@ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) /** - * The \a ncm_interface.recv_tinyusb_ntb is filled, - * put this buffer into the waiting list and free the receive logic. + * \a ready_ntb holds a validated NTB, + * put this buffer into the waiting list. */ { TU_LOG3("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); @@ -510,7 +505,6 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) static void recv_try_to_start_new_reception(uint8_t rhport) /** * If possible, start a new reception TinyUSB -> driver. - * Return value is actually not of interest. */ { TU_LOG3("recv_try_to_start_new_reception(%d)\n", rhport); @@ -552,7 +546,7 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { const nth16_t *nth16 = &(ntb->nth); - TU_LOG3("recv_validate_datagram(%p)\n", ntb); + TU_LOG3("recv_validate_datagram(%p, %d)\n", ntb, (int)len); // // check header @@ -714,7 +708,7 @@ bool tud_network_can_xmit(uint16_t size) return true; } xmit_start_if_possible(ncm_interface.rhport); - TU_LOG1("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + TU_LOG2("tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit @@ -746,7 +740,7 @@ void tud_network_xmit(void *ref, uint16_t arg) ntb->nth.wBlockLength += (uint16_t)(size + XMIT_ALIGN_OFFSET(size)); if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - TU_LOG1("(II) tud_network_xmit: buffer overflow\n"); // must not happen (really) + TU_LOG1("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) return; } -- cgit v1.3.1 From 3e8cf3ec8c861233c2a15750a38c38deb2302094 Mon Sep 17 00:00:00 2001 From: Ryan Solorzano Date: Tue, 12 Sep 2023 11:32:23 -0700 Subject: Add HID Lighting and Illumination functionality --- src/class/hid/hid.h | 96 +++++++++++++++++--------- src/class/hid/hid_device.h | 165 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+), 30 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index fbd3eef38..ecc9c04a7 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -684,32 +684,33 @@ enum { /// HID Usage Table - Table 1: Usage Page Summary enum { - HID_USAGE_PAGE_DESKTOP = 0x01, - HID_USAGE_PAGE_SIMULATE = 0x02, - HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, - HID_USAGE_PAGE_SPORT = 0x04, - HID_USAGE_PAGE_GAME = 0x05, - HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, - HID_USAGE_PAGE_KEYBOARD = 0x07, - HID_USAGE_PAGE_LED = 0x08, - HID_USAGE_PAGE_BUTTON = 0x09, - HID_USAGE_PAGE_ORDINAL = 0x0a, - HID_USAGE_PAGE_TELEPHONY = 0x0b, - HID_USAGE_PAGE_CONSUMER = 0x0c, - HID_USAGE_PAGE_DIGITIZER = 0x0d, - HID_USAGE_PAGE_PID = 0x0f, - HID_USAGE_PAGE_UNICODE = 0x10, - HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, - HID_USAGE_PAGE_MEDICAL = 0x40, - HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 - HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 - HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, - HID_USAGE_PAGE_SCALE = 0x8d, - HID_USAGE_PAGE_MSR = 0x8e, - HID_USAGE_PAGE_CAMERA = 0x90, - HID_USAGE_PAGE_ARCADE = 0x91, - HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page - HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF + HID_USAGE_PAGE_DESKTOP = 0x01, + HID_USAGE_PAGE_SIMULATE = 0x02, + HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, + HID_USAGE_PAGE_SPORT = 0x04, + HID_USAGE_PAGE_GAME = 0x05, + HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, + HID_USAGE_PAGE_KEYBOARD = 0x07, + HID_USAGE_PAGE_LED = 0x08, + HID_USAGE_PAGE_BUTTON = 0x09, + HID_USAGE_PAGE_ORDINAL = 0x0a, + HID_USAGE_PAGE_TELEPHONY = 0x0b, + HID_USAGE_PAGE_CONSUMER = 0x0c, + HID_USAGE_PAGE_DIGITIZER = 0x0d, + HID_USAGE_PAGE_PID = 0x0f, + HID_USAGE_PAGE_UNICODE = 0x10, + HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, + HID_USAGE_PAGE_MEDICAL = 0x40, + HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59, + HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 + HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 + HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, + HID_USAGE_PAGE_SCALE = 0x8d, + HID_USAGE_PAGE_MSR = 0x8e, + HID_USAGE_PAGE_CAMERA = 0x90, + HID_USAGE_PAGE_ARCADE = 0x91, + HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; /// HID Usage Table - Table 6: Generic Desktop Page @@ -788,8 +789,7 @@ enum { /// HID Usage Table: Consumer Page (0x0C) /// Only contains controls that supported by Windows (whole list is too long) -enum -{ +enum { // Generic Control HID_USAGE_CONSUMER_CONTROL = 0x0001, @@ -845,9 +845,45 @@ enum HID_USAGE_CONSUMER_AC_PAN = 0x0238, }; +/// HID Usage Table - Lighting And Illumination Page (0x59) +enum { + HID_USAGE_LIGHTING_LAMP_ARRAY = 0x01, + HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT = 0x02, + HID_USAGE_LIGHTING_LAMP_COUNT = 0x03, + HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS = 0x04, + HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS = 0x05, + HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS = 0x06, + HID_USAGE_LIGHTING_LAMP_ARRAY_KIND = 0x07, + HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS = 0x08, + HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT = 0x20, + HID_USAGE_LIGHTING_LAMP_ID = 0x21, + HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT = 0x22, + HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS = 0x23, + HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS = 0x24, + HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS = 0x25, + HID_USAGE_LIGHTING_LAMP_PURPOSES = 0x26, + HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS = 0x27, + HID_USAGE_LIGHTING_RED_LEVEL_COUNT = 0x28, + HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT = 0x29, + HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT = 0x2A, + HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT = 0x2B, + HID_USAGE_LIGHTING_IS_PROGRAMMABLE = 0x2C, + HID_USAGE_LIGHTING_INPUT_BINDING = 0x2D, + HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT = 0x50, + HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL = 0x51, + HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL = 0x52, + HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL = 0x53, + HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL = 0x54, + HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS = 0x55, + HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT = 0x60, + HID_USAGE_LIGHTING_LAMP_ID_START = 0x61, + HID_USAGE_LIGHTING_LAMP_ID_END = 0x62, + HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT = 0x70, + HID_USAGE_LIGHTING_AUTONOMOUS_MODE = 0x71, +}; + /// HID Usage Table: FIDO Alliance Page (0xF1D0) -enum -{ +enum { HID_USAGE_FIDO_U2FHID = 0x01, // U2FHID usage for top-level collection HID_USAGE_FIDO_DATA_IN = 0x20, // Raw IN data report HID_USAGE_FIDO_DATA_OUT = 0x21 // Raw OUT data report diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 17b24def1..276db894d 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -402,6 +402,171 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END \ +// HID Lighting and Illumination Report Descriptor Template +// - 1st parameter is report id HID_REPORT_ID(n) (optional) +#define TUD_HID_REPORT_DESC_LIGHTING(report_id) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY ),\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ + /* Lamp Array Attributes Report */ \ + HID_REPORT_ID (report_id ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_COUNT ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_KIND ),\ + HID_USAGE ( HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 2147483647, 3 ),\ + HID_REPORT_SIZE ( 32 ),\ + HID_REPORT_COUNT ( 5 ),\ + HID_FEATURE ( HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Attributes Request Report */ \ + HID_REPORT_ID ( report_id + 1 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Attributes Response Report */ \ + HID_REPORT_ID ( report_id + 2 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_PURPOSES ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 2147483647, 3 ),\ + HID_REPORT_SIZE ( 32 ),\ + HID_REPORT_COUNT ( 5 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_IS_PROGRAMMABLE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INPUT_BINDING ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 6 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Multi-Update Report */ \ + HID_REPORT_ID ( report_id + 3 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 8 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 2 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 8 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 32 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Range Update Report */ \ + HID_REPORT_ID ( report_id + 4 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 8 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID_START ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID_END ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 2 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 4 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Array Control Report */ \ + HID_REPORT_ID ( report_id + 5 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_AUTONOMOUS_MODE ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 1 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + HID_COLLECTION_END \ + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -- cgit v1.3.1 From a3d9eb43f1f0bd1632e4d8fe4fb3f3fc57778f16 Mon Sep 17 00:00:00 2001 From: Ryan Solorzano Date: Tue, 12 Sep 2023 12:09:39 -0700 Subject: Update Lighting Descriptor Template comment --- src/class/hid/hid_device.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 276db894d..966cfd9d1 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -403,7 +403,14 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_COLLECTION_END \ // HID Lighting and Illumination Report Descriptor Template -// - 1st parameter is report id HID_REPORT_ID(n) (optional) +// - 1st parameter is report id (required) +// Creates 6 report ids for lighting HID usages in the following order: +// report_id+0: HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT +// report_id+1: HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT +// report_id+2: HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT +// report_id+3: HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT +// report_id+4: HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT +// report_id+5: HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT #define TUD_HID_REPORT_DESC_LIGHTING(report_id) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY ),\ -- cgit v1.3.1 From 11fba8433474a0653047823a25a749183a7d1ac2 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Wed, 13 Sep 2023 21:29:04 +0000 Subject: Error handling on transfer --- src/class/hid/hid_device.c | 25 +++++++++++++++++++++---- src/class/hid/hid_device.h | 4 ++++ 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 5637ea6b4..8bedb6395 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -381,8 +381,6 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) result; - uint8_t instance = 0; hidd_interface_t * p_hid = _hidd_itf; @@ -394,6 +392,25 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } TU_ASSERT(instance < CFG_TUD_HID); + // Check if there was a problem + if (XFER_RESULT_SUCCESS != result) + { + // Inform application about the issue + if (tud_hid_report_issue_cb) + { + tud_hid_report_issue_cb(instance, ep_addr, result, xferred_bytes); + } + + // Allow a new transfer to be received if issue happened on an OUT endpoint + if (ep_addr == p_hid->ep_out) + { + // Prepare the OUT endpoint to be able to receive a new transfer + TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); + } + + return true; + } + // Sent report successfully if (ep_addr == p_hid->ep_in) { @@ -402,10 +419,10 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); } } - // Received report + // Received report successfully else if (ep_addr == p_hid->ep_out) { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, (uint16_t) xferred_bytes); + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t) xferred_bytes); TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 17b24def1..056727378 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -118,6 +118,8 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Note: For composite reports, report[0] is report ID TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); +// Invoked when a transfer wasn't successful +TU_ATTR_WEAK void tud_hid_report_issue_cb(uint8_t instance, uint8_t ep_addr, xfer_result_t result, uint16_t xferred_bytes); //--------------------------------------------------------------------+ // Inline Functions @@ -411,6 +413,8 @@ uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void test(void); + #ifdef __cplusplus } #endif -- cgit v1.3.1 From 81e63ed6d865d43b634ed6bf2d3df3ae29135913 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Wed, 13 Sep 2023 22:03:44 +0000 Subject: Fixing warning --- src/class/hid/hid_device.c | 2 +- src/class/hid/hid_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 8bedb6395..564ad12f6 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -398,7 +398,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Inform application about the issue if (tud_hid_report_issue_cb) { - tud_hid_report_issue_cb(instance, ep_addr, result, xferred_bytes); + tud_hid_report_issue_cb(instance, ep_addr, result, (uint16_t) xferred_bytes); } // Allow a new transfer to be received if issue happened on an OUT endpoint diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 056727378..a934753eb 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -119,7 +119,7 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); // Invoked when a transfer wasn't successful -TU_ATTR_WEAK void tud_hid_report_issue_cb(uint8_t instance, uint8_t ep_addr, xfer_result_t result, uint16_t xferred_bytes); +TU_ATTR_WEAK void tud_hid_report_issue_cb(uint8_t instance, uint8_t ep_addr, xfer_result_t result, uint16_t len); //--------------------------------------------------------------------+ // Inline Functions -- cgit v1.3.1 From f88a5bb03b2504df272d2cd285b17e66f11dfc64 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Tue, 17 Oct 2023 19:26:11 -0700 Subject: hid_device: use separate buffer for SET_REPORT instead of epout --- src/class/hid/hid_device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 2d46d760f..c939c0117 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -52,6 +52,7 @@ typedef struct CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t set_report_buf[CFG_TUD_HID_EP_BUFSIZE]; // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration @@ -307,15 +308,15 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t case HID_REQ_CONTROL_SET_REPORT: if ( stage == CONTROL_STAGE_SETUP ) { - TU_VERIFY(request->wLength <= sizeof(p_hid->epout_buf)); - tud_control_xfer(rhport, request, p_hid->epout_buf, request->wLength); + TU_VERIFY(request->wLength <= sizeof(p_hid->set_report_buf)); + tud_control_xfer(rhport, request, p_hid->set_report_buf, request->wLength); } else if ( stage == CONTROL_STAGE_ACK ) { uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t const* report_buf = p_hid->epout_buf; + uint8_t const* report_buf = p_hid->set_report_buf; uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); // If host request a specific Report ID, extract report ID in buffer before invoking callback -- cgit v1.3.1 From 5ce7b147117826dd75c2d7b347df80b0177e7252 Mon Sep 17 00:00:00 2001 From: Tommie Gannert Date: Mon, 26 Feb 2024 11:41:50 +0100 Subject: add notification support for device class USBTMC. The ep_int_in is already used for responding to USB488 READ_STATUS_BYTE requests, but that EP is defined for all of USBTMC. This extends the functionality to let callers send notifications and receive ACKs. --- src/class/usbtmc/usbtmc.h | 25 +++++++++++++++++++++++++ src/class/usbtmc/usbtmc_device.c | 16 +++++++++++++++- src/class/usbtmc/usbtmc_device.h | 20 +++++++++++++++----- 3 files changed, 55 insertions(+), 6 deletions(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 090ab3c4a..327de087c 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -183,6 +183,23 @@ typedef enum { } usmtmc_request_type_enum; +typedef enum { + // The last and first valid bNotify1 for use by the USBTMC class specification. + USBTMC_bNOTIFY1_USBTMC_FIRST = 0x00, + USBTMC_bNOTIFY1_USBTMC_LAST = 0x3F, + + // The last and first valid bNotify1 for use by vendors. + USBTMC_bNOTIFY1_VENDOR_SPECIFIC_FIRST = 0x40, + USBTMC_bNOTIFY1_VENDOR_SPECIFIC_LAST = 0x7F, + + // The last and first valid bNotify1 for use by USBTMC subclass specifications. + USBTMC_bNOTIFY1_SUBCLASS_FIRST = 0x80, + USBTMC_bNOTIFY1_SUBCLASS_LAST = 0xFF, + + // From the USB488 Subclass Specification, Section 3.4. + USB488_bNOTIFY1_SRQ = 0x81, +} usbtmc_int_in_payload_format; + typedef enum { USBTMC_STATUS_SUCCESS = 0x01, USBTMC_STATUS_PENDING = 0x02, @@ -303,6 +320,14 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length"); +typedef struct TU_ATTR_PACKED +{ + uint8_t bNotify1; // Must be USB488_bNOTIFY1_SRQ + uint8_t StatusByte; +} usbtmc_srq_interrupt_488_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_srq_interrupt_488_t) == 2u, "struct wrong length"); + typedef struct TU_ATTR_PACKED { struct TU_ATTR_PACKED diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 573654d58..debe445fd 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -240,6 +240,18 @@ bool tud_usbtmc_transmit_dev_msg_data( return true; } +bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) +{ +#ifndef NDEBUG + TU_ASSERT(len >= 1); + TU_ASSERT(usbtmc_state.ep_int_in != 0); +#endif + if (usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)) return false; + + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)data, len)); + return true; +} + void usbtmcd_init_cb(void) { usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); @@ -578,7 +590,9 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint } } else if (ep_addr == usbtmc_state.ep_int_in) { - // Good? + if (tud_usbtmc_notification_complete_cb) { + TU_VERIFY(tud_usbtmc_notification_complete_cb()); + } return true; } return false; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index c1298ddb8..2f3c91dbd 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -73,6 +73,10 @@ bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp); bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp); bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); +// The interrupt-IN endpoint buffer was transmitted to the host. Use +// tud_usbtmc_transmit_notification_data to send another notification. +TU_ATTR_WEAK bool tud_usbtmc_notification_complete_cb(void); + // Indicator pulse should be 0.5 to 1.0 seconds long TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); @@ -93,6 +97,17 @@ bool tud_usbtmc_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); +// Buffers a notification to be sent to the host. The buffer must be +// valid until the tud_usbtmc_notification_complete_cb callback. The +// data starts with the bNotify1 field, see the USBTMC Specification, +// Table 13. +// +// If the previous notification data has not yet been sent, this +// returns false. +// +// Requires an interrupt endpoint in the interface. +bool tud_usbtmc_transmit_notification_data(const void * data, size_t len); + bool tud_usbtmc_start_bus_read(void); @@ -104,9 +119,4 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); void usbtmcd_init_cb(void); -/************************************************************ - * USBTMC Descriptor Templates - *************************************************************/ - - #endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */ -- cgit v1.3.1 From 9e674fa109348d97fb4280ac534be665f619a4d8 Mon Sep 17 00:00:00 2001 From: Tommie Gannert Date: Fri, 15 Mar 2024 15:02:13 +0100 Subject: [usbtmc] cast to uintptr_t to get rid of const for usbd_edpt_xfer. --- src/class/usbtmc/usbtmc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index debe445fd..4092c37ea 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -248,7 +248,7 @@ bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) #endif if (usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)) return false; - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)data, len)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)(uintptr_t) data, len)); return true; } -- cgit v1.3.1 From c8805c61f9b0e3c03d8d3592127b1239a45c9880 Mon Sep 17 00:00:00 2001 From: acscd Date: Fri, 22 Mar 2024 20:05:52 -0500 Subject: Add files via upload --- src/class/msc/msc_device.c | 18 ++++++++++++++++++ src/class/msc/msc_device.h | 3 +++ 2 files changed, 21 insertions(+) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index c145d86a6..19e97a50f 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -685,6 +685,24 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ } break; + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + resplen = 0; + + if (tud_msc_prevent_allow_medium_removal_cb) + { + scsi_prevent_allow_medium_removal_t const * prevent_allow = (scsi_prevent_allow_medium_removal_t const *) scsi_cmd; + if ( !tud_msc_prevent_allow_medium_removal_cb(lun, prevent_allow->prohibit_removal, prevent_allow->control) ) + { + // Failed status response + resplen = - 1; + + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); + } + } + break; + + case SCSI_CMD_READ_CAPACITY_10: { uint32_t block_count; diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 72f95be06..c4632b4b7 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -131,6 +131,9 @@ TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void); // - Start = 1 : active mode, if load_eject = 1 : load disk storage TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject); +//Invoked when we receive the Prevent / Allow Medium Removal command +TU_ATTR_WEAK bool tud_msc_prevent_allow_medium_removal_cb(uint8_t lun, uint8_t prohibit_removal, uint8_t control); + // Invoked when received REQUEST_SENSE TU_ATTR_WEAK int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize); -- cgit v1.3.1 From b0568e32a5d3ad427d296e0d3bcb1020d54d25a3 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 10:47:06 +0200 Subject: Fix tud_video_n_streaming check --- src/class/video/video_device.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index d0a88eb17..4218835aa 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -763,8 +763,8 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); /* Only ISO endpoints needs to be closed */ if(ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { - usbd_edpt_close(rhport, ep->bEndpointAddress); stm->desc.ep[i] = 0; + usbd_edpt_close(rhport, ep->bEndpointAddress); TU_LOG_DRV(" close EP%02x\r\n", ep->bEndpointAddress); } } @@ -1186,6 +1186,16 @@ bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx); if (!stm || !stm->desc.ep[0]) return false; if (stm->state == VS_STATE_PROBING) return false; + +#ifdef TUP_DCD_EDPT_ISO_ALLOC + uint8_t const *desc = _videod_itf[stm->index_vc].beg; + uint_fast16_t ofs_ep = stm->desc.ep[0]; + tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); + if (ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { + if (stm->state == VS_STATE_COMMITTED) return false; + } +#endif + return true; } -- cgit v1.3.1 From 804a73a454f382ef7dd5377e6a564f516196fa5d Mon Sep 17 00:00:00 2001 From: Luke A Date: Mon, 14 Aug 2023 21:58:20 -0400 Subject: Adding tuh_hid_get_report(...) to hid_host.h This allows USB host functionality to call HID_REQ_CONTROL_GET_REPORT on the IN Endpoint, and read the report buffer in the callback. --- src/class/hid/hid_host.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/class/hid/hid_host.h | 8 ++++++++ 2 files changed, 52 insertions(+) (limited to 'src/class') diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 621fb2a55..115a8a4df 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -222,6 +222,50 @@ bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol) { return _hidh_set_protocol(daddr, p_hid->itf_num, protocol, set_protocol_complete, 0); } +static void get_report_complete(tuh_xfer_t* xfer) { + TU_LOG_DRV("HID Get Report complete\r\n"); + + if (tuh_hid_get_report_complete_cb) { + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); + + uint8_t const report_type = tu_u16_high(xfer->setup->wValue); + uint8_t const report_id = tu_u16_low(xfer->setup->wValue); + + tuh_hid_get_report_complete_cb(xfer->daddr, idx, report_id, report_type, + (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); + } +} + +bool tuh_hid_get_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) { + hidh_interface_t* p_hid = get_hid_itf(daddr, idx); + TU_VERIFY(p_hid); + TU_LOG_DRV("HID Get Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); + + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HID_REQ_CONTROL_GET_REPORT, + .wValue = tu_htole16(tu_u16(report_type, report_id)), + .wIndex = tu_htole16((uint16_t) p_hid->itf_num), + .wLength = len + }; + + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = report, + .complete_cb = get_report_complete, + .user_data = 0 + }; + + return tuh_control_xfer(&xfer); +} + static void set_report_complete(tuh_xfer_t* xfer) { TU_LOG_DRV("HID Set Report complete\r\n"); diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 0902bf1af..9681c704b 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -105,6 +105,10 @@ void tuh_hid_set_default_protocol(uint8_t protocol); // This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE) bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t idx, uint8_t protocol); +// Get Report using control endpoint +// report_type is either Input, Output or Feature, (value from hid_report_type_t) +bool tuh_hid_get_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); + // Set Report using control endpoint // report_type is either Input, Output or Feature, (value from hid_report_type_t) bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, @@ -153,6 +157,10 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* re // Invoked when sent report to device successfully via interrupt endpoint TU_ATTR_WEAK void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len); +// Invoked when Get Report to device via either control endpoint +// len = 0 indicate there is error in the transfer e.g stalled response +TU_ATTR_WEAK void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); + // Invoked when Sent Report to device via either control endpoint // len = 0 indicate there is error in the transfer e.g stalled response TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); -- cgit v1.3.1 From 62331f02070bdb1bec2890885008e9f88b06bdb6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 15:55:50 +0700 Subject: fix nrfx v3 spim freq when init fix clang build with nrf --- examples/host/cdc_msc_hid/src/msc_app.c | 4 ++-- hw/bsp/nrf/boards/pca10059/pca10059.ld | 8 +++++++- hw/bsp/nrf/boards/pca10095/board.cmake | 1 - hw/bsp/nrf/boards/pca10100/board.cmake | 1 - hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake | 1 - hw/bsp/nrf/family.c | 6 ++++-- hw/bsp/nrf/family.cmake | 18 +++++++++--------- hw/bsp/nrf/linker/nrf52833_xxaa.ld | 20 ++++++++++++++++++++ hw/bsp/nrf/linker/nrf5340_xxaa_application.ld | 21 +++++++++++++++++++++ src/class/cdc/cdc_host.c | 4 ++-- src/host/usbh.c | 2 +- 11 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 hw/bsp/nrf/linker/nrf52833_xxaa.ld create mode 100644 hw/bsp/nrf/linker/nrf5340_xxaa_application.ld (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/msc_app.c b/examples/host/cdc_msc_hid/src/msc_app.c index e9c9676b8..1d7e18e6e 100644 --- a/examples/host/cdc_msc_hid/src/msc_app.c +++ b/examples/host/cdc_msc_hid/src/msc_app.c @@ -48,8 +48,8 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size)); - printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size)); + printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); return true; } diff --git a/hw/bsp/nrf/boards/pca10059/pca10059.ld b/hw/bsp/nrf/boards/pca10059/pca10059.ld index 510bfdd8c..adc80f3c4 100644 --- a/hw/bsp/nrf/boards/pca10059/pca10059.ld +++ b/hw/bsp/nrf/boards/pca10059/pca10059.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { @@ -11,3 +11,9 @@ MEMORY INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index ca5399a3a..95dd30969 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf5340_application) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) function(update_board TARGET) target_sources(${TARGET} PRIVATE diff --git a/hw/bsp/nrf/boards/pca10100/board.cmake b/hw/bsp/nrf/boards/pca10100/board.cmake index c30026815..a925dae80 100644 --- a/hw/bsp/nrf/boards/pca10100/board.cmake +++ b/hw/bsp/nrf/boards/pca10100/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf52833) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52833_xxaa.ld) function(update_board TARGET) endfunction() diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake index 693d7beed..cc370aac8 100644 --- a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake +++ b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf52840) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) function(update_board TARGET) endfunction() diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index deae64f05..aff851ddc 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -356,20 +356,22 @@ static void max3421_init(void) { .miso_pin = MAX3421_MISO_PIN, #if NRFX_VER <= 2 .ss_pin = NRFX_SPIM_PIN_NOT_USED, + .frequency = NRF_SPIM_FREQ_4M, #else .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, + .frequency = 4000000u, #endif .ss_active_high = false, .irq_priority = 3, .orc = 0xFF, // default setting 4 Mhz, Mode 0, MSB first - .frequency = NRF_SPIM_FREQ_4M, .mode = NRF_SPIM_MODE_0, .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, + .miso_pull = NRF_GPIO_PIN_NOPULL, }; // no handler --> blocking - nrfx_spim_init(&_spi, &cfg, NULL, NULL); + TU_ASSERT(NRFX_SUCCESS == nrfx_spim_init(&_spi, &cfg, NULL, NULL), ); // max3421e interrupt pin #if NRFX_VER <= 2 diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 52a6fc196..56ff62bc4 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -30,8 +30,14 @@ set(FAMILY_MCUS NRF5X CACHE INTERNAL "") # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) + if (MCU_VARIANT STREQUAL "nrf5340_application") + set(MCU_VARIANT_XXAA "nrf5340_xxaa_application") + else () + set(MCU_VARIANT_XXAA "${MCU_VARIANT}_xxaa") + endif () + if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT}_xxaa.ld) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_XXAA}.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) @@ -50,19 +56,13 @@ function(add_board_target BOARD_TARGET) ${NRFX_DIR}/soc/nrfx_atomic.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) + string(TOUPPER "${MCU_VARIANT_XXAA}" MCU_VARIANT_XXAA_UPPER) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS CONFIG_GPIO_AS_PINRESET + ${MCU_VARIANT_XXAA_UPPER} ) - if (MCU_VARIANT STREQUAL "nrf52840") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52840_XXAA) - elseif (MCU_VARIANT STREQUAL "nrf52833") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52833_XXAA) - elseif (MCU_VARIANT STREQUAL "nrf5340_application") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF5340_XXAA NRF5340_XXAA_APPLICATION) - endif () - if (TRACE_ETM STREQUAL "1") # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace target_compile_definitions(${BOARD_TARGET} PUBLIC ENABLE_TRACE) diff --git a/hw/bsp/nrf/linker/nrf52833_xxaa.ld b/hw/bsp/nrf/linker/nrf52833_xxaa.ld new file mode 100644 index 000000000..ae4d0e5b3 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf52833_xxaa.ld @@ -0,0 +1,20 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 + CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x20000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld b/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld new file mode 100644 index 000000000..31762d0b2 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld @@ -0,0 +1,21 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + EXTFLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x8000000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + RAM1 (rwx) : ORIGIN = 0x20040000, LENGTH = 0x3F000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 5bdd41f1f..133a10f6e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1079,7 +1079,7 @@ static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) { static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate); - TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); + TU_LOG_DRV("CDC FTDI Set BaudRate = %" PRIu32 ", divisor = 0x%04x\r\n", baudrate, divisor); p_cdc->user_control_cb = complete_cb; p_cdc->requested_line_coding.bit_rate = baudrate; @@ -1222,7 +1222,7 @@ static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t co } static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_LOG_DRV("CDC CP210x Set BaudRate = %lu\r\n", baudrate); + TU_LOG_DRV("CDC CP210x Set BaudRate = %" PRIu32 "\r\n", baudrate); uint32_t baud_le = tu_htole32(baudrate); p_cdc->user_control_cb = complete_cb; return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4, diff --git a/src/host/usbh.c b/src/host/usbh.c index f8fddf394..7a47f5056 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -704,7 +704,7 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %" PRIu32 "\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG_BUF_USBH(request, 8); // terminate transfer if any stage failed -- cgit v1.3.1 From c097c85dcf8e0ef3ea052c146c5f514101827251 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 16:17:22 +0700 Subject: fix print lu format warnings with clang --- examples/device/audio_test_multi_rate/src/main.c | 2 +- examples/device/cdc_uac2/src/uac2_app.c | 4 ++-- examples/device/uac2_headset/src/main.c | 4 ++-- examples/host/bare_api/src/main.c | 2 +- examples/host/cdc_msc_hid_freertos/src/cdc_app.c | 4 ++-- examples/host/cdc_msc_hid_freertos/src/msc_app.c | 4 ++-- examples/host/msc_file_explorer/src/msc_app.c | 6 +++--- src/CMakeLists.txt | 2 +- src/class/cdc/cdc_device.c | 13 ++++++------- src/class/usbtmc/usbtmc_device.c | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 2 +- tools/get_deps.py | 3 ++- 12 files changed, 24 insertions(+), 24 deletions(-) (limited to 'src/class') diff --git a/examples/device/audio_test_multi_rate/src/main.c b/examples/device/audio_test_multi_rate/src/main.c index 3e7f40dac..2ff7f10bd 100644 --- a/examples/device/audio_test_multi_rate/src/main.c +++ b/examples/device/audio_test_multi_rate/src/main.c @@ -272,7 +272,7 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * sampFreq = (uint32_t)((audio_control_cur_4_t *)pBuff)->bCur; - TU_LOG2("Clock set current freq: %lu\r\n", sampFreq); + TU_LOG2("Clock set current freq: %" PRIu32 "\r\n", sampFreq); return true; break; diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c index 98659ea68..c57d98a1a 100644 --- a/examples/device/cdc_uac2/src/uac2_app.c +++ b/examples/device/cdc_uac2/src/uac2_app.c @@ -69,7 +69,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { if (request->bRequest == AUDIO_CS_REQ_CUR) { - TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); + TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); @@ -118,7 +118,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur; - TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate); + TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index fbd7ffe22..0ea6e7025 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -157,7 +157,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { if (request->bRequest == AUDIO_CS_REQ_CUR) { - TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); + TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); @@ -206,7 +206,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur; - TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate); + TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 14725996d..940840a30 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -420,5 +420,5 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_len) { _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); ((uint8_t*) temp_buf)[utf8_len] = '\0'; - printf((char*)temp_buf); + printf("%s", (char*)temp_buf); } diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c index 6ff513be1..7d246af67 100644 --- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c @@ -117,7 +117,7 @@ void tuh_cdc_rx_cb(uint8_t idx) { uint32_t count = tuh_cdc_read(idx, buf, bufsize); buf[count] = 0; - printf((char *) buf); + printf("%s", (char *) buf); } void tuh_cdc_mount_cb(uint8_t idx) { @@ -131,7 +131,7 @@ void tuh_cdc_mount_cb(uint8_t idx) { // otherwise you need to call tuh_cdc_set_line_coding() first cdc_line_coding_t line_coding = { 0 }; if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { - printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); + printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } #endif diff --git a/examples/host/cdc_msc_hid_freertos/src/msc_app.c b/examples/host/cdc_msc_hid_freertos/src/msc_app.c index ee02ba917..9ffd5d965 100644 --- a/examples/host/cdc_msc_hid_freertos/src/msc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/msc_app.c @@ -47,8 +47,8 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_dat uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024 * 1024) / block_size)); - printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024 * 1024) / block_size)); + printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); return true; } diff --git a/examples/host/msc_file_explorer/src/msc_app.c b/examples/host/msc_file_explorer/src/msc_app.c index ecea614a2..f323e30f0 100644 --- a/examples/host/msc_file_explorer/src/msc_app.c +++ b/examples/host/msc_file_explorer/src/msc_app.c @@ -114,7 +114,7 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size)); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size)); // printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); // For simplicity: we only mount 1 LUN per device @@ -541,10 +541,10 @@ void cli_cmd_ls(EmbeddedCli *cli, char *args, void *context) printf("%-40s", fno.fname); if (fno.fsize < 1024) { - printf("%lu B\r\n", fno.fsize); + printf("%" PRIu32 " B\r\n", fno.fsize); }else { - printf("%lu KB\r\n", fno.fsize / 1024); + printf("%" PRIu32 " KB\r\n", fno.fsize / 1024); } } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 076e1e1eb..272962332 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,7 +41,7 @@ function(add_tinyusb TARGET) ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../lib/networking ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") target_compile_options(${TARGET} PRIVATE -Wall -Wextra diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 7ef0530ec..2e0a0c30d 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -43,10 +43,7 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -enum -{ - BULK_PACKET_SIZE = (TUD_OPT_HIGH_SPEED ? 512 : 64) -}; +#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) typedef struct { @@ -176,9 +173,11 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); // flush if queue more than packet size - // may need to suppress -Wunreachable-code since most of the time CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - if ( (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE) || ((CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE) && tu_fifo_full(&p_cdc->tx_ff)) ) - { + if ( tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE + #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE + || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size + #endif + ) { tud_cdc_n_write_flush(itf); } diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 286cbe108..f6cddfbd7 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -360,7 +360,7 @@ uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, // processing a command (such as a clear). Returns true if it was // in the NAK state and successfully transitioned to the ACK wait // state. -bool tud_usbtmc_start_bus_read() +bool tud_usbtmc_start_bus_read(void) { usbtmcd_state_enum oldState = usbtmc_state.state; switch(oldState) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 56e7f39a0..2fe721d6b 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -147,7 +147,7 @@ static void start_dma(volatile uint32_t* reg_startep) { static void edpt_dma_start(volatile uint32_t* reg_startep) { if (atomic_flag_test_and_set(&_dcd.dma_running)) { - usbd_defer_func((osal_task_func_t) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); + usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); } else { start_dma(reg_startep); } diff --git a/tools/get_deps.py b/tools/get_deps.py index cfa60002a..e08246178 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -177,7 +177,8 @@ deps_optional = { '20285262657d1b482d132d20d755c8c330d55c1f', 'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2x' 'stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5' - 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb'], + 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb' + 'sam3x samd11 samd21 samd51 same5x same7x saml2x samg'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], -- cgit v1.3.1 From 13bde7af403c4f6f3ff6381e23202fc433bffdb2 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 23 Apr 2024 21:36:05 +0200 Subject: uac2: return on clear_feature. --- src/class/audio/audio_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9050b462a..9ba38a20c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2015,7 +2015,10 @@ static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const case TUSB_REQ_SET_INTERFACE: return audiod_set_interface(rhport, p_request); - // Unknown/Unsupported request + case TUSB_REQ_CLEAR_FEATURE: + return true; + + // Unknown/Unsupported request default: TU_BREAKPOINT(); return false; } } -- cgit v1.3.1 From 7fb8d3341ce2feb46b0bce0bef069d31cf080168 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 13:40:13 +0200 Subject: use separate buffer for ctrl transfer. --- src/class/hid/hid_device.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index ba77d3c5f..a5c709d4c 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -52,7 +52,7 @@ typedef struct CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t set_report_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration @@ -296,7 +296,7 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t* report_buf = p_hid->epin_buf; + uint8_t* report_buf = p_hid->ctrl_buf; uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); uint16_t xferlen = 0; @@ -313,22 +313,22 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); TU_ASSERT( xferlen > 0 ); - tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); } break; case HID_REQ_CONTROL_SET_REPORT: if ( stage == CONTROL_STAGE_SETUP ) { - TU_VERIFY(request->wLength <= sizeof(p_hid->set_report_buf)); - tud_control_xfer(rhport, request, p_hid->set_report_buf, request->wLength); + TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); } else if ( stage == CONTROL_STAGE_ACK ) { uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t const* report_buf = p_hid->set_report_buf; + uint8_t const* report_buf = p_hid->ctrl_buf; uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); // If host request a specific Report ID, extract report ID in buffer before invoking callback -- cgit v1.3.1 From 1661acf82f8e01392de0c18c3472d016679c707d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 13:42:20 +0200 Subject: Add missing alignment. --- src/class/hid/hid_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index a5c709d4c..c66a4597e 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -46,9 +46,9 @@ typedef struct uint8_t ep_out; // optional Out endpoint uint8_t itf_protocol; // Boot mouse or keyboard - uint8_t protocol_mode; // Boot (0) or Report protocol (1) - uint8_t idle_rate; // up to application to handle idle rate uint16_t report_desc_len; + CFG_TUSB_MEM_ALIGN uint8_t protocol_mode; // Boot (0) or Report protocol (1) + CFG_TUSB_MEM_ALIGN uint8_t idle_rate; // up to application to handle idle rate CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; -- cgit v1.3.1 From 4af67dd0078009c1378612440afd5806e84a81c7 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 17:45:14 +0200 Subject: Simplify transfer failure cb. --- .clang-format | 6 ++++++ src/class/hid/hid_device.c | 6 ++++-- src/class/hid/hid_device.h | 3 +-- 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 .clang-format (limited to 'src/class') diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..4369c29fe --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +--- +BreakBeforeBraces: Linux +ColumnLimit: '200' +ReflowComments: 'true' + +... diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 564ad12f6..637bc7f61 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -381,6 +381,8 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) result; + uint8_t instance = 0; hidd_interface_t * p_hid = _hidd_itf; @@ -396,9 +398,9 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (XFER_RESULT_SUCCESS != result) { // Inform application about the issue - if (tud_hid_report_issue_cb) + if (tud_hid_report_fail_cb) { - tud_hid_report_issue_cb(instance, ep_addr, result, (uint16_t) xferred_bytes); + tud_hid_report_fail_cb(instance, ep_addr, (uint16_t) xferred_bytes); } // Allow a new transfer to be received if issue happened on an OUT endpoint diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index a934753eb..9206d67f8 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -119,7 +119,7 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); // Invoked when a transfer wasn't successful -TU_ATTR_WEAK void tud_hid_report_issue_cb(uint8_t instance, uint8_t ep_addr, xfer_result_t result, uint16_t len); +TU_ATTR_WEAK void tud_hid_report_fail_cb(uint8_t instance, uint8_t ep_addr, uint16_t len); //--------------------------------------------------------------------+ // Inline Functions @@ -413,7 +413,6 @@ uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void test(void); #ifdef __cplusplus } -- cgit v1.3.1 From 24339dbcce5c5374e0abedf605471753484e4a56 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 18:01:02 +0200 Subject: Code format. --- src/class/hid/hid_device.c | 355 +++++++++++++++++++-------------------------- 1 file changed, 153 insertions(+), 202 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 45c10862b..ada01582e 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -39,12 +39,11 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_in; - uint8_t ep_out; // optional Out endpoint - uint8_t itf_protocol; // Boot mouse or keyboard + uint8_t ep_out; // optional Out endpoint + uint8_t itf_protocol; // Boot mouse or keyboard uint16_t report_desc_len; CFG_TUSB_MEM_ALIGN uint8_t protocol_mode; // Boot (0) or Report protocol (1) @@ -56,7 +55,7 @@ typedef struct // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration - tusb_hid_descriptor_hid_t const * hid_descriptor; + tusb_hid_descriptor_hid_t const *hid_descriptor; } hidd_interface_t; CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; @@ -64,12 +63,12 @@ CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; /*------------- Helpers -------------*/ static inline uint8_t get_index_by_itfnum(uint8_t itf_num) { - for (uint8_t i=0; i < CFG_TUD_HID; i++ ) - { - if ( itf_num == _hidd_itf[i].itf_num ) return i; - } + for (uint8_t i = 0; i < CFG_TUD_HID; i++) { + if (itf_num == _hidd_itf[i].itf_num) + return i; + } - return 0xFF; + return 0xFF; } //--------------------------------------------------------------------+ @@ -82,37 +81,29 @@ bool tud_hid_n_ready(uint8_t instance) return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len) +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) { uint8_t const rhport = 0; - hidd_interface_t * p_hid = &_hidd_itf[instance]; + hidd_interface_t *p_hid = &_hidd_itf[instance]; // claim endpoint - TU_VERIFY( usbd_edpt_claim(rhport, p_hid->ep_in) ); + TU_VERIFY(usbd_edpt_claim(rhport, p_hid->ep_in)); // prepare data - if (report_id) - { + if (report_id) { p_hid->epin_buf[0] = report_id; - TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf+1, CFG_TUD_HID_EP_BUFSIZE-1, report, len)); + TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf + 1, CFG_TUD_HID_EP_BUFSIZE - 1, report, len)); len++; - }else - { + } else { TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf, CFG_TUD_HID_EP_BUFSIZE, report, len)); } return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); } -uint8_t tud_hid_n_interface_protocol(uint8_t instance) -{ - return _hidd_itf[instance].itf_protocol; -} +uint8_t tud_hid_n_interface_protocol(uint8_t instance) { return _hidd_itf[instance].itf_protocol; } -uint8_t tud_hid_n_get_protocol(uint8_t instance) -{ - return _hidd_itf[instance].protocol_mode; -} +uint8_t tud_hid_n_get_protocol(uint8_t instance) { return _hidd_itf[instance].protocol_mode; } bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { @@ -121,27 +112,23 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi report.modifier = modifier; report.reserved = 0; - if ( keycode ) - { + if (keycode) { memcpy(report.keycode, keycode, sizeof(report.keycode)); - }else - { + } else { tu_memclr(report.keycode, 6); } return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, - uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) +bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { - hid_mouse_report_t report = - { + hid_mouse_report_t report = { .buttons = buttons, - .x = x, - .y = y, - .wheel = vertical, - .pan = horizontal + .x = x, + .y = y, + .wheel = vertical, + .pan = horizontal }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); @@ -149,29 +136,27 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { - hid_abs_mouse_report_t report = - { + hid_abs_mouse_report_t report = { .buttons = buttons, - .x = x, - .y = y, - .wheel = vertical, - .pan = horizontal + .x = x, + .y = y, + .wheel = vertical, + .pan = horizontal }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, - int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { - hid_gamepad_report_t report = - { - .x = x, - .y = y, - .z = z, - .rz = rz, - .rx = rx, - .ry = ry, - .hat = hat, - .buttons = buttons, +bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) +{ + hid_gamepad_report_t report = { + .x = x, + .y = y, + .z = z, + .rz = rz, + .rx = rx, + .ry = ry, + .hat = hat, + .buttons = buttons, }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); @@ -180,67 +165,64 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, //--------------------------------------------------------------------+ // USBD-CLASS API //--------------------------------------------------------------------+ -void hidd_init(void) { +void hidd_init(void) +{ hidd_reset(0); } -bool hidd_deinit(void) { +bool hidd_deinit(void) +{ return true; } void hidd_reset(uint8_t rhport) { - (void) rhport; + (void)rhport; tu_memclr(_hidd_itf, sizeof(_hidd_itf)); } -uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) - { +uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) +{ TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints - uint16_t const drv_len = - (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + - desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + uint16_t const drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface - hidd_interface_t * p_hid = NULL; + hidd_interface_t *p_hid = NULL; uint8_t hid_id; - for(hid_id=0; hid_idhid_descriptor = (tusb_hid_descriptor_hid_t const *) p_desc; + p_hid->hid_descriptor = (tusb_hid_descriptor_hid_t const *)p_desc; //------------- Endpoint Descriptor -------------// p_desc = tu_desc_next(p_desc); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in), 0); - if ( desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT ) p_hid->itf_protocol = desc_itf->bInterfaceProtocol; + if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) + p_hid->itf_protocol = desc_itf->bInterfaceProtocol; p_hid->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode - p_hid->itf_num = desc_itf->bInterfaceNumber; + p_hid->itf_num = desc_itf->bInterfaceNumber; // Use offsetof to avoid pointer to the odd/misaligned address - p_hid->report_desc_len = tu_unaligned_read16((uint8_t const*) p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); + p_hid->report_desc_len = tu_unaligned_read16((uint8_t const *)p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); // Prepare for output endpoint - if (p_hid->ep_out) - { - if ( !usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf)) ) - { + if (p_hid->ep_out) { + if (!usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))) { TU_LOG_FAILED(); TU_BREAKPOINT(); } @@ -252,144 +234,120 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint1 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); - uint8_t const hid_itf = get_index_by_itfnum((uint8_t) request->wIndex); + uint8_t const hid_itf = get_index_by_itfnum((uint8_t)request->wIndex); TU_VERIFY(hid_itf < CFG_TUD_HID); - hidd_interface_t* p_hid = &_hidd_itf[hid_itf]; + hidd_interface_t *p_hid = &_hidd_itf[hid_itf]; - if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) - { + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { //------------- STD Request -------------// - if ( stage == CONTROL_STAGE_SETUP ) - { - uint8_t const desc_type = tu_u16_high(request->wValue); - //uint8_t const desc_index = tu_u16_low (request->wValue); + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const desc_type = tu_u16_high(request->wValue); + // uint8_t const desc_index = tu_u16_low (request->wValue); - if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) - { + if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) { TU_VERIFY(p_hid->hid_descriptor); - TU_VERIFY(tud_control_xfer(rhport, request, (void*)(uintptr_t) p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); - } - else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) - { - uint8_t const * desc_report = tud_hid_descriptor_report_cb(hid_itf); - tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_report, p_hid->report_desc_len); - } - else - { + TU_VERIFY(tud_control_xfer(rhport, request, (void *)(uintptr_t)p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); + } else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { + uint8_t const *desc_report = tud_hid_descriptor_report_cb(hid_itf); + tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_report, p_hid->report_desc_len); + } else { return false; // stall unsupported request } } - } - else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) - { + } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { //------------- Class Specific Request -------------// - switch( request->bRequest ) - { - case HID_REQ_CONTROL_GET_REPORT: - if ( stage == CONTROL_STAGE_SETUP ) - { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); + switch (request->bRequest) { + case HID_REQ_CONTROL_GET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t* report_buf = p_hid->ctrl_buf; - uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + uint8_t *report_buf = p_hid->ctrl_buf; + uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - uint16_t xferlen = 0; + uint16_t xferlen = 0; - // If host request a specific Report ID, add ID to as 1 byte of response - if ( (report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1) ) - { - *report_buf++ = report_id; - req_len--; + // If host request a specific Report ID, add ID to as 1 byte of response + if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { + *report_buf++ = report_id; + req_len--; - xferlen++; - } + xferlen++; + } - xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); - TU_ASSERT( xferlen > 0 ); + xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, req_len); + TU_ASSERT(xferlen > 0); - tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); - } + tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); + } break; - case HID_REQ_CONTROL_SET_REPORT: - if ( stage == CONTROL_STAGE_SETUP ) - { - TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); - tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); - } - else if ( stage == CONTROL_STAGE_ACK ) - { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - - uint8_t const* report_buf = p_hid->ctrl_buf; - uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - // If host request a specific Report ID, extract report ID in buffer before invoking callback - if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0]) ) - { - report_buf++; - report_len--; - } - - tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); + case HID_REQ_CONTROL_SET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); + } else if (stage == CONTROL_STAGE_ACK) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t const *report_buf = p_hid->ctrl_buf; + uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + + // If host request a specific Report ID, extract report ID in buffer before invoking callback + if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { + report_buf++; + report_len--; } + + tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, report_len); + } break; - case HID_REQ_CONTROL_SET_IDLE: - if ( stage == CONTROL_STAGE_SETUP ) - { - p_hid->idle_rate = tu_u16_high(request->wValue); - if ( tud_hid_set_idle_cb ) - { - // stall request if callback return false - TU_VERIFY( tud_hid_set_idle_cb( hid_itf, p_hid->idle_rate) ); - } - - tud_control_status(rhport, request); + case HID_REQ_CONTROL_SET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + p_hid->idle_rate = tu_u16_high(request->wValue); + if (tud_hid_set_idle_cb) { + // stall request if callback return false + TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); } + + tud_control_status(rhport, request); + } break; - case HID_REQ_CONTROL_GET_IDLE: - if ( stage == CONTROL_STAGE_SETUP ) - { - // TODO idle rate of report - tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); - } + case HID_REQ_CONTROL_GET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + // TODO idle rate of report + tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); + } break; - case HID_REQ_CONTROL_GET_PROTOCOL: - if ( stage == CONTROL_STAGE_SETUP ) - { - tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); - } + case HID_REQ_CONTROL_GET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); + } break; - case HID_REQ_CONTROL_SET_PROTOCOL: - if ( stage == CONTROL_STAGE_SETUP ) - { - tud_control_status(rhport, request); - } - else if ( stage == CONTROL_STAGE_ACK ) - { - p_hid->protocol_mode = (uint8_t) request->wValue; - if (tud_hid_set_protocol_cb) - { - tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); - } + case HID_REQ_CONTROL_SET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_status(rhport, request); + } else if (stage == CONTROL_STAGE_ACK) { + p_hid->protocol_mode = (uint8_t)request->wValue; + if (tud_hid_set_protocol_cb) { + tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); } + } break; - default: return false; // stall unsupported request + default: + return false; // stall unsupported request } - }else - { + } else { return false; // stall unsupported request } @@ -398,31 +356,27 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) result; + (void)result; uint8_t instance = 0; - hidd_interface_t * p_hid = _hidd_itf; + hidd_interface_t *p_hid = _hidd_itf; // Identify which interface to use - for (instance = 0; instance < CFG_TUD_HID; instance++) - { + for (instance = 0; instance < CFG_TUD_HID; instance++) { p_hid = &_hidd_itf[instance]; - if ( (ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in) ) break; + if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) + break; } TU_ASSERT(instance < CFG_TUD_HID); // Check if there was a problem - if (XFER_RESULT_SUCCESS != result) - { - // Inform application about the issue - if (tud_hid_report_fail_cb) - { - tud_hid_report_fail_cb(instance, ep_addr, (uint16_t) xferred_bytes); + if (XFER_RESULT_SUCCESS != result) { // Inform application about the issue + if (tud_hid_report_fail_cb) { + tud_hid_report_fail_cb(instance, ep_addr, (uint16_t)xferred_bytes); } // Allow a new transfer to be received if issue happened on an OUT endpoint - if (ep_addr == p_hid->ep_out) - { + if (ep_addr == p_hid->ep_out) { // Prepare the OUT endpoint to be able to receive a new transfer TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } @@ -431,17 +385,14 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } // Sent report successfully - if (ep_addr == p_hid->ep_in) - { - if (tud_hid_report_complete_cb) - { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); + if (ep_addr == p_hid->ep_in) { + if (tud_hid_report_complete_cb) { + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t)xferred_bytes); } } // Received report successfully - else if (ep_addr == p_hid->ep_out) - { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t) xferred_bytes); + else if (ep_addr == p_hid->ep_out) { + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } -- cgit v1.3.1 From 98e85a296deb89dbcc05033bda26e3c9581d535b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:09:05 +0200 Subject: bulk_in: copy buffer to ensure alignment correctness. --- src/class/usbtmc/usbtmc_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 4092c37ea..81e969732 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -552,9 +552,10 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_TX_INITIATED: if(usbtmc_state.transfer_size_remaining >= sizeof(usbtmc_state.ep_bulk_in_buf)) { - // FIXME! This removes const below! + // Copy buffer to ensure alignment correctness + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, - (void*)(uintptr_t) usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf))); + usbtmc_state.ep_bulk_in_buf, sizeof(usbtmc_state.ep_bulk_in_buf))); usbtmc_state.devInBuffer += sizeof(usbtmc_state.ep_bulk_in_buf); usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.ep_bulk_in_buf); usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.ep_bulk_in_buf); -- cgit v1.3.1 From fdb431b5c70ff605eebda8988e1728e7118b4ab4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:12:00 +0200 Subject: Buffer int msg to ensure alignment and placement correctness. --- src/class/usbtmc/usbtmc_device.c | 18 +++++++++++++----- src/class/usbtmc/usbtmc_device.h | 17 ++++++----------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 81e969732..59d9b184e 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -86,6 +86,11 @@ tu_static char logMsg[150]; // imposes a minimum buffer size of 32 bytes. #define USBTMCD_BUFFER_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Interrupt endpoint buffer size, default to 2 bytes as USB488 specification. +#ifndef CFG_TUD_USBTMC_INT_EP_SIZE +#define CFG_TUD_USBTMC_INT_EP_SIZE 2 +#endif + /* * The state machine does not allow simultaneous reading and writing. This is * consistent with USBTMC. @@ -124,13 +129,15 @@ typedef struct uint8_t ep_bulk_in; uint8_t ep_bulk_out; uint8_t ep_int_in; + uint32_t ep_bulk_in_wMaxPacketSize; + uint32_t ep_bulk_out_wMaxPacketSize; // IN buffer is only used for first packet, not the remainder // in order to deal with prepending header CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_BUFFER_SIZE]; - uint32_t ep_bulk_in_wMaxPacketSize; // OUT buffer receives one packet at a time CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_BUFFER_SIZE]; - uint32_t ep_bulk_out_wMaxPacketSize; + // Buffer int msg to ensure alignment and placement correctness + CFG_TUSB_MEM_ALIGN uint8_t ep_int_in_buf[CFG_TUD_USBTMC_INT_EP_SIZE]; uint32_t transfer_size_remaining; // also used for requested length for bulk IN. uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes) @@ -243,12 +250,13 @@ bool tud_usbtmc_transmit_dev_msg_data( bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) { #ifndef NDEBUG - TU_ASSERT(len >= 1); + TU_ASSERT(len > 0); TU_ASSERT(usbtmc_state.ep_int_in != 0); #endif - if (usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)) return false; + TU_VERIFY(usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)); - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)(uintptr_t) data, len)); + TU_VERIFY(tu_memcpy_s(usbtmc_state.ep_int_in_buf, sizeof(usbtmc_state.ep_int_in_buf), data, len) == 0); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_state.ep_int_in_buf, len)); return true; } diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 2f3c91dbd..af7ea6ec9 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -86,21 +86,16 @@ TU_ATTR_WEAK bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(); #endif -/******************************************* - * Called from app - * - * We keep a reference to the buffer, so it MUST not change until the app is - * notified that the transfer is complete. - ******************************************/ - +// Called from app +// +// We keep a reference to the buffer, so it MUST not change until the app is +// notified that the transfer is complete. bool tud_usbtmc_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); -// Buffers a notification to be sent to the host. The buffer must be -// valid until the tud_usbtmc_notification_complete_cb callback. The -// data starts with the bNotify1 field, see the USBTMC Specification, -// Table 13. +// Buffers a notification to be sent to the host. The data starts +// with the bNotify1 field, see the USBTMC Specification, Table 13. // // If the previous notification data has not yet been sent, this // returns false. -- cgit v1.3.1 From bd033a2d531d09478ddd947121e12aa6ece86d56 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:24:19 +0200 Subject: Fix CI. --- src/class/usbtmc/usbtmc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 59d9b184e..f80abdaf3 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -256,7 +256,7 @@ bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) TU_VERIFY(usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)); TU_VERIFY(tu_memcpy_s(usbtmc_state.ep_int_in_buf, sizeof(usbtmc_state.ep_int_in_buf), data, len) == 0); - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_state.ep_int_in_buf, len)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_state.ep_int_in_buf, (uint16_t)len)); return true; } -- cgit v1.3.1 From 327e3ec4bd1908e57e2ecd90738f01fc04a17ba1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Apr 2024 21:59:54 +0200 Subject: Stall unsupported class request. --- src/class/net/ncm_device.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 14ace9d8e..829161865 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -947,7 +947,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } switch (request->bmRequestType_bit.type) { - case TUSB_REQ_TYPE_STANDARD: + case TUSB_REQ_TYPE_STANDARD: { switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); @@ -975,14 +975,15 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t default: return false; } - break; + } + break; - case TUSB_REQ_TYPE_CLASS: + case TUSB_REQ_TYPE_CLASS: { TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - + switch (request->bRequest) { TU_LOG3(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - if (request->bRequest == NCM_GET_NTB_PARAMETERS) { + case NCM_GET_NTB_PARAMETERS: { // transfer NTB parameters to host. // TODO can one assume, that tud_control_xfer() succeeds? TU_LOG3(" NCM_GET_NTB_PARAMETERS\n"); @@ -990,6 +991,13 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } break; + // unsupported request + default: + return false ; + + } + } + break; // unsupported request default: return false ; -- cgit v1.3.1 From ea55537fb2a42e112c8d4f714c71c51b2faa88d6 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 5 May 2024 20:33:01 +0200 Subject: minor changes due to CR with HiFiPhile --- src/class/net/ncm.h | 50 ++++++++++++++++++++++++++-------------------- src/class/net/ncm_device.c | 6 +++--- 2 files changed, 31 insertions(+), 25 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index c768192a5..cf4daf96c 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) + * Copyright (c) 2024, Hardy Griech * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,42 +30,47 @@ #define _TUSB_NCM_H_ #include "common/tusb_common.h" - +#include "lwipopts.h" #ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE - /// must be >> MTU - #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100) #endif #ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE - /// must be >> MTU - #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 + #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100) #endif #ifndef CFG_TUD_NCM_OUT_NTB_N - /// number of ntb buffers for reception side - /// 1 - good performance - /// 2 - up to 30% more performance with iperf with small packets - /// >2 - no performance gain - #define CFG_TUD_NCM_OUT_NTB_N 2 + /// number of NTB buffers for reception side + /// 1 - good performance + /// 2 - up to 30% more performance with iperf with small packets + /// >2 - no performance gain + /// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements + #define CFG_TUD_NCM_OUT_NTB_N 1 #endif #ifndef CFG_TUD_NCM_IN_NTB_N - /// number of ntb buffers for transmission side - /// 1 - good performance but SystemView shows lost events (on load test) - /// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" - /// happens from time to time with SystemView - /// 3 - "tud_network_can_xmit: request blocked" never happens - /// >2 - no performance gain - #define CFG_TUD_NCM_IN_NTB_N 3 + /// number of NTB buffers for transmission side + /// 1 - good performance but SystemView shows lost events (on load test) + /// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" + /// happens from time to time with SystemView + /// 3 - "tud_network_can_xmit: request blocked" never happens + /// >2 - no performance gain + /// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements + #define CFG_TUD_NCM_IN_NTB_N 1 +#endif + +#ifndef CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + /// this is for the transmission side for allocation of \a ndp16_datagram_t + #define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8 #endif -#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB - /// this is for the transmission size for allocation of \a ndp16_datagram_t - #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 +#ifndef CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB + /// this tells the host how many datagrams it is allowed to put into an NTB + #define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6 #endif #ifndef CFG_TUD_NCM_ALIGNMENT - #define CFG_TUD_NCM_ALIGNMENT 4 + #define CFG_TUD_NCM_ALIGNMENT 4 #endif #if (CFG_TUD_NCM_ALIGNMENT != 4) #error "CFG_TUD_NCM_ALIGNMENT must be 4, otherwise the headers and start of datagrams have to be aligned (which they are currently not)" @@ -136,7 +142,7 @@ typedef union TU_ATTR_PACKED { struct { nth16_t nth; ndp16_t ndp; - ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1]; + ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1]; }; uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; } xmit_ntb_t; diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 829161865..40f70dc3f 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,8 +1,8 @@ /* * The MIT License (MIT) * - * Copyright (c) 2023 Hardy Griech * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2024 Hardy Griech * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -126,7 +126,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 = 6 // 0=no limit + .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, }; //----------------------------------------------------------------------------- @@ -371,7 +371,7 @@ static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size if (ncm_interface.xmit_glue_ntb == NULL) { return false; } - if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB) { + if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB) { return false; } if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { -- cgit v1.3.1 From cc70958c16f4b88c0e48590d32189c870091547e Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 5 May 2024 21:18:57 +0200 Subject: mostly comments --- src/class/net/ncm_device.c | 56 +++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 40f70dc3f..05cebf94e 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -79,7 +79,7 @@ typedef struct { uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it // recv handling - CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver @@ -87,7 +87,7 @@ typedef struct { uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram // xmit handling - CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB @@ -129,6 +129,18 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, }; +// Some confusing remarks about wNtbOutMaxDatagrams... +// ==1 -> SystemView packets/s goes up to 2000 and events are lost during startup +// ==0 -> SystemView runs fine, iperf shows in wireshark a lot of error +// ==6 -> SystemView runs fine, iperf also +// >6 -> iperf starts to show errors +// -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? +// switch \a TU_LOG2 on to see interesting values for this. +// +// iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done +// sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 +// + //----------------------------------------------------------------------------- // // everything about notifications @@ -340,7 +352,7 @@ static void xmit_start_if_possible(uint8_t rhport) ncm_interface.xmit_glue_ntb = NULL; } -#ifdef DEBUG_OUT_ENABLED +#if CFG_TUSB_DEBUG >= 3 { uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; TU_LOG3(" %d\n", len); @@ -708,7 +720,7 @@ bool tud_network_can_xmit(uint16_t size) return true; } xmit_start_if_possible(ncm_interface.rhport); - TU_LOG2("tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + TU_LOG2("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit @@ -796,10 +808,18 @@ void netd_init(void) } } // netd_init -bool netd_deinit(void) { - return true; + + +bool netd_deinit(void) +/** + * Deinit driver + */ +{ + return true; } + + void netd_reset(uint8_t rhport) /** * Resets the port. @@ -947,12 +967,14 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } switch (request->bmRequestType_bit.type) { - case TUSB_REQ_TYPE_STANDARD: { + case TUSB_REQ_TYPE_STANDARD: + TU_LOG3(" TUSB_REQ_TYPE_STANDARD: %d\n", request->bRequest); + switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); - TU_LOG3(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); + TU_LOG3(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); } break; @@ -961,7 +983,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); ncm_interface.itf_data_alt = (uint8_t)request->wValue; - TU_LOG3(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); + TU_LOG3(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); if (ncm_interface.itf_data_alt == 1) { tud_network_recv_renew_r(rhport); @@ -975,15 +997,14 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t default: return false; } - } - break; + break; - case TUSB_REQ_TYPE_CLASS: { + case TUSB_REQ_TYPE_CLASS: TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - switch (request->bRequest) { + TU_LOG3(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - case NCM_GET_NTB_PARAMETERS: { + if (request->bRequest == NCM_GET_NTB_PARAMETERS) { // transfer NTB parameters to host. // TODO can one assume, that tud_control_xfer() succeeds? TU_LOG3(" NCM_GET_NTB_PARAMETERS\n"); @@ -991,13 +1012,6 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } break; - // unsupported request - default: - return false ; - - } - } - break; // unsupported request default: return false ; -- cgit v1.3.1 From 91d69fa942c8a450c9816595f0d19138964533ef Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:10:26 +0200 Subject: Reformat NCM class. --- src/class/net/ncm.h | 141 +++-- src/class/net/ncm_device.c | 1270 ++++++++++++++++++++------------------------ 2 files changed, 640 insertions(+), 771 deletions(-) (limited to 'src/class') diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index cf4daf96c..1b987fca0 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -25,58 +25,59 @@ * This file is part of the TinyUSB stack. */ - #ifndef _TUSB_NCM_H_ #define _TUSB_NCM_H_ #include "common/tusb_common.h" -#include "lwipopts.h" -#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE - #define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100) -#endif +// NTB buffers size for reception side, must be >> MTU to avoid TCP retransmission (driver issue ?) +// Linux use 2048 as minimal size #ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE - #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100) + #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 +#endif + +// NTB buffers size for reception side, must be > MTU +// Linux use 2048 as minimal size +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 #endif +// Number of NTB buffers for reception side +// Depending on the configuration, this parameter could be increased with the cost of additional RAM requirements +// On Full-Speed (RP2040) : +// 1 - good performance +// 2 - up to 30% more performance with iperf with small packets +// >2 - no performance gain +// On High-Speed (STM32F7) : +// No performance gain #ifndef CFG_TUD_NCM_OUT_NTB_N - /// number of NTB buffers for reception side - /// 1 - good performance - /// 2 - up to 30% more performance with iperf with small packets - /// >2 - no performance gain - /// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements - #define CFG_TUD_NCM_OUT_NTB_N 1 + #define CFG_TUD_NCM_OUT_NTB_N 1 #endif +// Number of NTB buffers for transmission side +// Depending on the configuration, this parameter could be increased with the cost of additional RAM requirements +// On Full-Speed (RP2040) : +// 1 - good performance but SystemView shows lost events (on load test) +// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" +// happens from time to time with SystemView +// 3 - "tud_network_can_xmit: request blocked" never happens +// >3 - no performance gain +// On High-Speed (STM32F7) : +// No performance gain #ifndef CFG_TUD_NCM_IN_NTB_N - /// number of NTB buffers for transmission side - /// 1 - good performance but SystemView shows lost events (on load test) - /// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" - /// happens from time to time with SystemView - /// 3 - "tud_network_can_xmit: request blocked" never happens - /// >2 - no performance gain - /// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements - #define CFG_TUD_NCM_IN_NTB_N 1 + #define CFG_TUD_NCM_IN_NTB_N 1 #endif +// How many datagrams it is allowed to put into an NTB for transmission side #ifndef CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB - /// this is for the transmission side for allocation of \a ndp16_datagram_t - #define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8 + #define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8 #endif +// This tells the host how many datagrams it is allowed to put into an NTB #ifndef CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB - /// this tells the host how many datagrams it is allowed to put into an NTB - #define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6 + #define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6 #endif -#ifndef CFG_TUD_NCM_ALIGNMENT - #define CFG_TUD_NCM_ALIGNMENT 4 -#endif -#if (CFG_TUD_NCM_ALIGNMENT != 4) - #error "CFG_TUD_NCM_ALIGNMENT must be 4, otherwise the headers and start of datagrams have to be aligned (which they are currently not)" -#endif - - // Table 6.2 Class-Specific Request Codes for Network Control Model subclass typedef enum { @@ -98,67 +99,65 @@ typedef enum NCM_SET_CRC_MODE = 0x8A, } ncm_request_code_t; - -#define NTH16_SIGNATURE 0x484D434E +#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; + 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; + 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; + 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[]; + 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; - ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1]; - }; - uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; + struct { + nth16_t nth; + ndp16_t ndp; + ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1]; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; } xmit_ntb_t; typedef union TU_ATTR_PACKED { - struct { - nth16_t nth; - // only the header is at a guaranteed position - }; - uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; + struct { + nth16_t nth; + // only the header is at a guaranteed position + }; + uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; } recv_ntb_t; struct ncm_notify_t { - tusb_control_request_t header; - uint32_t downlink, uplink; + tusb_control_request_t header; + uint32_t downlink, uplink; }; - #endif diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 05cebf94e..4b237e4cf 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -46,7 +46,7 @@ #include "tusb_option.h" -#if defined(ECLIPSE_GUI) || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if (CFG_TUD_ENABLED && CFG_TUD_NCM) #include #include @@ -55,59 +55,65 @@ #include "device/usbd.h" #include "device/usbd_pvt.h" -#include "net_device.h" #include "ncm.h" +#include "net_device.h" + +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUD_NCM_LOG_LEVEL + #define CFG_TUD_NCM_LOG_LEVEL CFG_TUD_LOG_LEVEL +#endif +#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__) +// Alignment must be 4 +#define TUD_NCM_ALIGNMENT 4 // calculate alignment of xmit datagrams within an NTB -#define XMIT_ALIGN_OFFSET(x) ((CFG_TUD_NCM_ALIGNMENT - ((x) & (CFG_TUD_NCM_ALIGNMENT - 1))) & (CFG_TUD_NCM_ALIGNMENT - 1)) +#define XMIT_ALIGN_OFFSET(x) ((TUD_NCM_ALIGNMENT - ((x) & (TUD_NCM_ALIGNMENT - 1))) & (TUD_NCM_ALIGNMENT - 1)) //----------------------------------------------------------------------------- // // Module global things // -#define XMIT_NTB_N CFG_TUD_NCM_IN_NTB_N -#define RECV_NTB_N CFG_TUD_NCM_OUT_NTB_N +#define XMIT_NTB_N CFG_TUD_NCM_IN_NTB_N +#define RECV_NTB_N CFG_TUD_NCM_OUT_NTB_N typedef struct { - // general - uint8_t ep_in; //!< endpoint for outgoing datagrams (naming is a little bit confusing) - uint8_t ep_out; //!< endpoint for incoming datagrams (naming is a little bit confusing) - uint8_t ep_notif; //!< endpoint for notifications - uint8_t itf_num; //!< interface number - uint8_t itf_data_alt; //!< ==0 -> no endpoints, i.e. no network traffic, ==1 -> normal operation with two endpoints (spec, chapter 5.3) - uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it - - // recv handling - CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs - recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs - recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic - recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver - recv_ntb_t *recv_glue_ntb; //!< buffer for the running transfer driver -> glue logic - uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram - - // xmit handling - CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs - xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs - xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB - xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB - xmit_ntb_t *xmit_glue_ntb; //!< buffer for the running transfer glue logic -> driver - uint16_t xmit_sequence; //!< NTB sequence counter - uint16_t xmit_glue_ntb_datagram_ndx; //!< index into \a xmit_glue_ntb_datagram - - // notification handling - enum { - NOTIFICATION_SPEED, - NOTIFICATION_CONNECTED, - NOTIFICATION_DONE - } notification_xmit_state; //!< state of notification transmission - bool notification_xmit_is_running; //!< notification is currently transmitted + // general + uint8_t ep_in; // endpoint for outgoing datagrams (naming is a little bit confusing) + uint8_t ep_out; // endpoint for incoming datagrams (naming is a little bit confusing) + uint8_t ep_notif; // endpoint for notifications + uint8_t itf_num; // interface number + uint8_t itf_data_alt; // ==0 -> no endpoints, i.e. no network traffic, ==1 -> normal operation with two endpoints (spec, chapter 5.3) + uint8_t rhport; // storage of \a rhport because some callbacks are done without it + + // recv handling + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; // actual recv NTBs + recv_ntb_t *recv_free_ntb[RECV_NTB_N]; // free list of recv NTBs + recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; // NTBs waiting for transmission to glue logic + recv_ntb_t *recv_tinyusb_ntb; // buffer for the running transfer TinyUSB -> driver + recv_ntb_t *recv_glue_ntb; // buffer for the running transfer driver -> glue logic + uint16_t recv_glue_ntb_datagram_ndx; // index into \a recv_glue_ntb_datagram + + // xmit handling + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; // actual xmit NTBs + xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; // free list of xmit NTBs + xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; // NTBs waiting for transmission to TinyUSB + xmit_ntb_t *xmit_tinyusb_ntb; // buffer for the running transfer driver -> TinyUSB + xmit_ntb_t *xmit_glue_ntb; // buffer for the running transfer glue logic -> driver + uint16_t xmit_sequence; // NTB sequence counter + uint16_t xmit_glue_ntb_datagram_ndx; // index into \a xmit_glue_ntb_datagram + + // notification handling + enum { + NOTIFICATION_SPEED, + NOTIFICATION_CONNECTED, + NOTIFICATION_DONE + } notification_xmit_state; // state of notification transmission + bool notification_xmit_is_running; // notification is currently transmitted } ncm_interface_t; - CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; - /** * This is the NTB parameter structure * @@ -115,18 +121,18 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; * We are lucky, that byte order is correct */ 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, - .wNdbOutPayloadRemainder = 0, - .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01,// 16-bit NTB supported + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, + .wNdbInDivisor = 1, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 1, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, }; // Some confusing remarks about wNtbOutMaxDatagrams... @@ -135,7 +141,6 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par // ==6 -> SystemView runs fine, iperf also // >6 -> iperf starts to show errors // -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? -// switch \a TU_LOG2 on to see interesting values for this. // // iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done // sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 @@ -146,151 +151,128 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par // everything about notifications // tu_static struct ncm_notify_t 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, - }, + .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_t 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 = 12000000, - .uplink = 12000000, + .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 = TUD_OPT_HIGH_SPEED ? 480000000 : 12000000, + .uplink = TUD_OPT_HIGH_SPEED ? 480000000 : 12000000, }; - - -static void notification_xmit(uint8_t rhport, bool force_next) /** * Transmit next notification to the host (if appropriate). * Notifications are transferred to the host once during connection setup. */ -{ - TU_LOG3("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); - - if ( !force_next && ncm_interface.notification_xmit_is_running) { - return; - } - - if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { - TU_LOG3(" NOTIFICATION_SPEED\n"); - 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.notification_xmit_state = NOTIFICATION_CONNECTED; - ncm_interface.notification_xmit_is_running = true; - } - else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { - TU_LOG3(" NOTIFICATION_CONNECTED\n"); - 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.notification_xmit_state = NOTIFICATION_DONE; - ncm_interface.notification_xmit_is_running = true; - } - else { - TU_LOG3(" NOTIFICATION_FINISHED\n"); - } -} // notification_xmit - +static void notification_xmit(uint8_t rhport, bool force_next) { + TU_LOG_DRV("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); + + if (!force_next && ncm_interface.notification_xmit_is_running) { + return; + } + + if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { + TU_LOG_DRV(" NOTIFICATION_SPEED\n"); + 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.notification_xmit_state = NOTIFICATION_CONNECTED; + ncm_interface.notification_xmit_is_running = true; + } else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { + TU_LOG_DRV(" NOTIFICATION_CONNECTED\n"); + 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.notification_xmit_state = NOTIFICATION_DONE; + ncm_interface.notification_xmit_is_running = true; + } else { + TU_LOG_DRV(" NOTIFICATION_FINISHED\n"); + } +} // notification_xmit //----------------------------------------------------------------------------- // // everything about packet transmission (driver -> TinyUSB) // - -static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) /** * Put NTB into the transmitter free list. */ -{ - TU_LOG3("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); +static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) { + TU_LOG_DRV("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); - if (free_ntb == NULL) { - // can happen due to ZLPs - return; - } + if (free_ntb == NULL) { // can happen due to ZLPs + return; + } - for (int i = 0; i < XMIT_NTB_N; ++i) { - if (ncm_interface.xmit_free_ntb[i] == NULL) { - ncm_interface.xmit_free_ntb[i] = free_ntb; - return; - } + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] == NULL) { + ncm_interface.xmit_free_ntb[i] = free_ntb; + return; } - TU_LOG1("(EE) xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen -} // xmit_put_ntb_into_free_list - - + } + TU_LOG_DRV("(EE) xmit_put_ntb_into_free_list - no entry in free list\n");// this should not happen +} // xmit_put_ntb_into_free_list -static xmit_ntb_t *xmit_get_free_ntb(void) /** * Get an NTB from the free list */ -{ - TU_LOG3("xmit_get_free_ntb()\n"); - - for (int i = 0; i < XMIT_NTB_N; ++i) { - if (ncm_interface.xmit_free_ntb[i] != NULL) { - xmit_ntb_t *free = ncm_interface.xmit_free_ntb[i]; - ncm_interface.xmit_free_ntb[i] = NULL; - return free; - } - } - return NULL; -} // xmit_get_free_ntb - +static xmit_ntb_t *xmit_get_free_ntb(void) { + TU_LOG_DRV("xmit_get_free_ntb()\n"); + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] != NULL) { + xmit_ntb_t *free = ncm_interface.xmit_free_ntb[i]; + ncm_interface.xmit_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // xmit_get_free_ntb -static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) /** * Put a filled NTB into the ready list */ -{ - TU_LOG2("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); +static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) { + TU_LOG_DRV("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); - for (int i = 0; i < XMIT_NTB_N; ++i) { - if (ncm_interface.xmit_ready_ntb[i] == NULL) { - ncm_interface.xmit_ready_ntb[i] = ready_ntb; - return; - } + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_ready_ntb[i] == NULL) { + ncm_interface.xmit_ready_ntb[i] = ready_ntb; + return; } - TU_LOG1("(EE) xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen -} // xmit_put_ntb_into_ready_list + } + TU_LOG_DRV("(EE) xmit_put_ntb_into_ready_list: ready list full\n");// this should not happen +} // xmit_put_ntb_into_ready_list - - -static xmit_ntb_t *xmit_get_next_ready_ntb(void) /** * Get the next NTB from the ready list (and remove it from the list). * If the ready list is empty, return NULL. */ -{ - xmit_ntb_t *r = NULL; - - r = ncm_interface.xmit_ready_ntb[0]; - memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); - ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; +static xmit_ntb_t *xmit_get_next_ready_ntb(void) { + xmit_ntb_t *r = NULL; - TU_LOG3("recv_get_next_ready_ntb: %p\n", r); - return r; -} // xmit_get_next_ready_ntb + r = ncm_interface.xmit_ready_ntb[0]; + memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); + ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; + TU_LOG_DRV("recv_get_next_ready_ntb: %p\n", r); + return r; +} // xmit_get_next_ready_ntb - -static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) /** * Transmit a ZLP if required * @@ -302,252 +284,221 @@ static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) * \pre * This must be called from netd_xfer_cb() so that ep_in is ready */ -{ - TU_LOG3("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); - - if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { - return false; - } +static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) { + TU_LOG_DRV("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); - TU_ASSERT(ncm_interface.itf_data_alt == 1, false); - TU_ASSERT( !usbd_edpt_busy(rhport, ncm_interface.ep_in), false); - - TU_LOG2("xmit_insert_required_zlp! (%u)\n", (unsigned)xferred_bytes); + if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { + return false; + } - // start transmission of the ZLP - usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); + TU_ASSERT(ncm_interface.itf_data_alt == 1, false); + TU_ASSERT(!usbd_edpt_busy(rhport, ncm_interface.ep_in), false); - return true; -} // xmit_insert_required_zlp + TU_LOG_DRV("xmit_insert_required_zlp! (%u)\n", (unsigned) xferred_bytes); + // start transmission of the ZLP + usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); + return true; +} // xmit_insert_required_zlp -static void xmit_start_if_possible(uint8_t rhport) /** * Start transmission if it there is a waiting packet and if can be done from interface side. */ -{ - TU_LOG3("xmit_start_if_possible()\n"); - - if (ncm_interface.xmit_tinyusb_ntb != NULL) { - TU_LOG3(" !xmit_start_if_possible 1\n"); - return; - } - if (ncm_interface.itf_data_alt != 1) { - TU_LOG1("(EE) !xmit_start_if_possible 2\n"); - return; - } - if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { - TU_LOG2(" !xmit_start_if_possible 3\n"); - return; - } +static void xmit_start_if_possible(uint8_t rhport) { + TU_LOG_DRV("xmit_start_if_possible()\n"); + + if (ncm_interface.xmit_tinyusb_ntb != NULL) { + TU_LOG_DRV(" !xmit_start_if_possible 1\n"); + return; + } + if (ncm_interface.itf_data_alt != 1) { + TU_LOG_DRV("(EE) !xmit_start_if_possible 2\n"); + return; + } + if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { + TU_LOG_DRV(" !xmit_start_if_possible 3\n"); + return; + } + + ncm_interface.xmit_tinyusb_ntb = xmit_get_next_ready_ntb(); + if (ncm_interface.xmit_tinyusb_ntb == NULL) { + if (ncm_interface.xmit_glue_ntb == NULL || ncm_interface.xmit_glue_ntb_datagram_ndx == 0) { + // -> really nothing is waiting + return; + } + ncm_interface.xmit_tinyusb_ntb = ncm_interface.xmit_glue_ntb; + ncm_interface.xmit_glue_ntb = NULL; + } + + #if CFG_TUD_NCM_LOG_LEVEL >= 3 + { + uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; + TU_LOG_BUF(3, ncm_interface.xmit_tinyusb_ntb->data[i], len); + } + #endif + + if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { + TU_LOG_DRV(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); + } + + // Kick off an endpoint transfer + usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); +} // xmit_start_if_possible - ncm_interface.xmit_tinyusb_ntb = xmit_get_next_ready_ntb(); - if (ncm_interface.xmit_tinyusb_ntb == NULL) { - if (ncm_interface.xmit_glue_ntb == NULL || ncm_interface.xmit_glue_ntb_datagram_ndx == 0) { - // -> really nothing is waiting - return; - } - ncm_interface.xmit_tinyusb_ntb = ncm_interface.xmit_glue_ntb; - ncm_interface.xmit_glue_ntb = NULL; - } - -#if CFG_TUSB_DEBUG >= 3 - { - uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; - TU_LOG3(" %d\n", len); - for (int i = 0; i < len; ++i) { - TU_LOG3(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); - } - TU_LOG3("\n"); - } -#endif - - if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { - TU_LOG3(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); - } - - // Kick off an endpoint transfer - usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); -} // xmit_start_if_possible - - - -static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size) /** * check if a new datagram fits into the current NTB */ -{ - TU_LOG3("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); - - if (ncm_interface.xmit_glue_ntb == NULL) { - return false; - } - if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB) { - return false; - } - if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - return false; - } - return true; -} // xmit_requested_datagram_fits_into_current_ntb - +static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size) { + TU_LOG_DRV("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); + if (ncm_interface.xmit_glue_ntb == NULL) { + return false; + } + if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB) { + return false; + } + if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + return false; + } + return true; +} // xmit_requested_datagram_fits_into_current_ntb -static bool xmit_setup_next_glue_ntb(void) /** * Setup an NTB for the glue logic */ -{ - TU_LOG3("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); +static bool xmit_setup_next_glue_ntb(void) { + TU_LOG_DRV("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); - if (ncm_interface.xmit_glue_ntb != NULL) { - // put NTB into waiting list (the new datagram did not fit in) - xmit_put_ntb_into_ready_list(ncm_interface.xmit_glue_ntb); - } + if (ncm_interface.xmit_glue_ntb != NULL) { + // put NTB into waiting list (the new datagram did not fit in) + xmit_put_ntb_into_ready_list(ncm_interface.xmit_glue_ntb); + } - ncm_interface.xmit_glue_ntb = xmit_get_free_ntb(); // get next buffer (if any) - if (ncm_interface.xmit_glue_ntb == NULL) { - TU_LOG3(" xmit_setup_next_glue_ntb - nothing free\n"); // should happen rarely - return false; - } - - ncm_interface.xmit_glue_ntb_datagram_ndx = 0; + ncm_interface.xmit_glue_ntb = xmit_get_free_ntb();// get next buffer (if any) + if (ncm_interface.xmit_glue_ntb == NULL) { + TU_LOG_DRV(" xmit_setup_next_glue_ntb - nothing free\n");// should happen rarely + return false; + } - xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + ncm_interface.xmit_glue_ntb_datagram_ndx = 0; - // Fill in NTB header - ntb->nth.dwSignature = NTH16_SIGNATURE; - ntb->nth.wHeaderLength = sizeof(ntb->nth); - ntb->nth.wSequence = ncm_interface.xmit_sequence++; - ntb->nth.wBlockLength = sizeof(ntb->nth) + sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); - ntb->nth.wNdpIndex = sizeof(ntb->nth); + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; - // Fill in NDP16 header and terminator - ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; - ntb->ndp.wLength = sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); - ntb->ndp.wNextNdpIndex = 0; + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(ntb->nth); + ntb->nth.wSequence = ncm_interface.xmit_sequence++; + ntb->nth.wBlockLength = sizeof(ntb->nth) + sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->nth.wNdpIndex = sizeof(ntb->nth); - memset(ntb->ndp_datagram, 0, sizeof(ntb->ndp_datagram)); - return true; -} // xmit_setup_next_glue_ntb + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->ndp.wNextNdpIndex = 0; + memset(ntb->ndp_datagram, 0, sizeof(ntb->ndp_datagram)); + return true; +} // xmit_setup_next_glue_ntb //----------------------------------------------------------------------------- // // all the recv_*() stuff (TinyUSB -> driver -> glue logic) // - -static recv_ntb_t *recv_get_free_ntb(void) /** * Return pointer to an available receive buffer or NULL. * Returned buffer (if any) has the size \a CFG_TUD_NCM_OUT_NTB_MAX_SIZE. */ -{ - TU_LOG3("recv_get_free_ntb()\n"); - - for (int i = 0; i < RECV_NTB_N; ++i) { - if (ncm_interface.recv_free_ntb[i] != NULL) { - recv_ntb_t *free = ncm_interface.recv_free_ntb[i]; - ncm_interface.recv_free_ntb[i] = NULL; - return free; - } - } - return NULL; -} // recv_get_free_ntb - +static recv_ntb_t *recv_get_free_ntb(void) { + TU_LOG_DRV("recv_get_free_ntb()\n"); + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] != NULL) { + recv_ntb_t *free = ncm_interface.recv_free_ntb[i]; + ncm_interface.recv_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // recv_get_free_ntb -static recv_ntb_t *recv_get_next_ready_ntb(void) /** * Get the next NTB from the ready list (and remove it from the list). * If the ready list is empty, return NULL. */ -{ - recv_ntb_t *r = NULL; +static recv_ntb_t *recv_get_next_ready_ntb(void) { + recv_ntb_t *r = NULL; - r = ncm_interface.recv_ready_ntb[0]; - memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); - ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; + r = ncm_interface.recv_ready_ntb[0]; + memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); + ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; - TU_LOG3("recv_get_next_ready_ntb: %p\n", r); - return r; -} // recv_get_next_ready_ntb + TU_LOG_DRV("recv_get_next_ready_ntb: %p\n", r); + return r; +} // recv_get_next_ready_ntb - - -static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) /** * Put NTB into the receiver free list. */ -{ - TU_LOG3("recv_put_ntb_into_free_list(%p)\n", free_ntb); +static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) { + TU_LOG_DRV("recv_put_ntb_into_free_list(%p)\n", free_ntb); - for (int i = 0; i < RECV_NTB_N; ++i) { - if (ncm_interface.recv_free_ntb[i] == NULL) { - ncm_interface.recv_free_ntb[i] = free_ntb; - return; - } + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] == NULL) { + ncm_interface.recv_free_ntb[i] = free_ntb; + return; } - TU_LOG1("(EE) recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen -} // recv_put_ntb_into_free_list + } + TU_LOG_DRV("(EE) recv_put_ntb_into_free_list - no entry in free list\n");// this should not happen +} // recv_put_ntb_into_free_list - - -static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) /** * \a ready_ntb holds a validated NTB, * put this buffer into the waiting list. */ -{ - TU_LOG3("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); +static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) { + TU_LOG_DRV("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); - for (int i = 0; i < RECV_NTB_N; ++i) { - if (ncm_interface.recv_ready_ntb[i] == NULL) { - ncm_interface.recv_ready_ntb[i] = ready_ntb; - return; - } + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_ready_ntb[i] == NULL) { + ncm_interface.recv_ready_ntb[i] = ready_ntb; + return; } - TU_LOG1("(EE) recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen -} // recv_put_ntb_into_ready_list - - + } + TU_LOG_DRV("(EE) recv_put_ntb_into_ready_list: ready list full\n");// this should not happen +} // recv_put_ntb_into_ready_list -static void recv_try_to_start_new_reception(uint8_t rhport) /** * If possible, start a new reception TinyUSB -> driver. */ -{ - TU_LOG3("recv_try_to_start_new_reception(%d)\n", rhport); - - if (ncm_interface.itf_data_alt != 1) { - return; - } - if (ncm_interface.recv_tinyusb_ntb != NULL) { - return; - } - if (usbd_edpt_busy(rhport, ncm_interface.ep_out)) { - return; - } - - ncm_interface.recv_tinyusb_ntb = recv_get_free_ntb(); - if (ncm_interface.recv_tinyusb_ntb == NULL) { - return; - } - - // initiate transfer - TU_LOG3(" start reception\n"); - bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); - if ( !r) { - recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); - ncm_interface.recv_tinyusb_ntb = NULL; - } -} // recv_try_to_start_new_reception - - +static void recv_try_to_start_new_reception(uint8_t rhport) { + TU_LOG_DRV("recv_try_to_start_new_reception(%d)\n", rhport); + + if (ncm_interface.itf_data_alt != 1) { + return; + } + if (ncm_interface.recv_tinyusb_ntb != NULL) { + return; + } + if (usbd_edpt_busy(rhport, ncm_interface.ep_out)) { + return; + } + + ncm_interface.recv_tinyusb_ntb = recv_get_free_ntb(); + if (ncm_interface.recv_tinyusb_ntb == NULL) { + return; + } + + // initiate transfer + TU_LOG_DRV(" start reception\n"); + bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + if (!r) { + recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); + ncm_interface.recv_tinyusb_ntb = NULL; + } +} // recv_try_to_start_new_reception -static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) /** * Validate incoming datagram. * \return true if valid @@ -555,287 +506,243 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) * \note * \a ndp16->wNextNdpIndex != 0 is not supported */ -{ - const nth16_t *nth16 = &(ntb->nth); - - TU_LOG3("recv_validate_datagram(%p, %d)\n", ntb, (int)len); - - // - // check header - // - if (nth16->wHeaderLength != sizeof(nth16_t)) - { - TU_LOG1("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); - return false; - } - if (nth16->dwSignature != NTH16_SIGNATURE) { - TU_LOG1("(EE) ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); - return false; - } - if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - TU_LOG1("(EE) ill min len: %d\n", len); - return false; - } - if (nth16->wBlockLength > len) { - TU_LOG1("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); - return false; - } - if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - TU_LOG1("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); - return false; - } - if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t))) { - TU_LOG1("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); - return false; - } +static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { + const nth16_t *nth16 = &(ntb->nth); - // - // check (first) NDP(16) - // - const ndp16_t *ndp16 = (const ndp16_t *)(ntb->data + nth16->wNdpIndex); + TU_LOG_DRV("recv_validate_datagram(%p, %d)\n", ntb, (int) len); - if (ndp16->wLength < sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - TU_LOG1("(EE) ill ndp16 length: %d\n", ndp16->wLength); - return false; - } - if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { - TU_LOG1("(EE) ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); - return false; - } - if (ndp16->wNextNdpIndex != 0) { - TU_LOG1("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); - return false; - } + // check header + if (nth16->wHeaderLength != sizeof(nth16_t)) { + TU_LOG_DRV("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); + return false; + } + if (nth16->dwSignature != NTH16_SIGNATURE) { + TU_LOG_DRV("(EE) ill signature: 0x%08x\n", (unsigned) nth16->dwSignature); + return false; + } + if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { + TU_LOG_DRV("(EE) ill min len: %d\n", len); + return false; + } + if (nth16->wBlockLength > len) { + TU_LOG_DRV("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); + return false; + } + if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + TU_LOG_DRV("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + return false; + } + if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t))) { + TU_LOG_DRV("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + return false; + } - const ndp16_datagram_t *ndp16_datagram = (const ndp16_datagram_t *)(ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); - int ndx = 0; - uint16_t max_ndx = (uint16_t)((ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t)); + // check (first) NDP(16) + const ndp16_t *ndp16 = (const ndp16_t *) (ntb->data + nth16->wNdpIndex); - if (max_ndx > 2) { - // number of datagrams in NTB > 1 - TU_LOG2("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); - } - if (ndp16_datagram[max_ndx-1].wDatagramIndex != 0 || ndp16_datagram[max_ndx-1].wDatagramLength != 0) { - TU_LOG2(" max_ndx != 0\n"); - return false; - } - while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { - TU_LOG3(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); - if (ndp16_datagram[ndx].wDatagramIndex > len) { - TU_LOG1("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); - return false; - } - if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { - TU_LOG1("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); - return false; - } - ++ndx; - } + if (ndp16->wLength < sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { + TU_LOG_DRV("(EE) ill ndp16 length: %d\n", ndp16->wLength); + return false; + } + if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { + TU_LOG_DRV("(EE) ill signature: 0x%08x\n", (unsigned) ndp16->dwSignature); + return false; + } + if (ndp16->wNextNdpIndex != 0) { + TU_LOG_DRV("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + return false; + } -#if CFG_TUSB_DEBUG >= 3 - for (uint32_t i = 0; i < len; ++i) { - TU_LOG3(" %02x", ntb->data[i]); - } - TU_LOG3("\n"); -#endif + const ndp16_datagram_t *ndp16_datagram = (const ndp16_datagram_t *) (ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); + int ndx = 0; + uint16_t max_ndx = (uint16_t) ((ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t)); - // -> ntb contains a valid packet structure - // ok... I did not check for garbage within the datagram indices... - return true; -} // recv_validate_datagram + if (max_ndx > 2) { // number of datagrams in NTB > 1 + TU_LOG_DRV("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); + } + if (ndp16_datagram[max_ndx - 1].wDatagramIndex != 0 || ndp16_datagram[max_ndx - 1].wDatagramLength != 0) { + TU_LOG_DRV(" max_ndx != 0\n"); + return false; + } + while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { + TU_LOG_DRV(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); + if (ndp16_datagram[ndx].wDatagramIndex > len) { + TU_LOG_DRV("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + return false; + } + if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { + TU_LOG_DRV("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + return false; + } + ++ndx; + } + #if CFG_TUD_NCM_LOG_LEVEL >= 3 + TU_LOG_BUF(3, ntb->data[i], len); + #endif + // -> ntb contains a valid packet structure + // ok... I did not check for garbage within the datagram indices... + return true; +} // recv_validate_datagram -static void recv_transfer_datagram_to_glue_logic(void) /** * Transfer the next (pending) datagram to the glue logic and return receive buffer if empty. */ -{ - TU_LOG3("recv_transfer_datagram_to_glue_logic()\n"); - - if (ncm_interface.recv_glue_ntb == NULL) { - ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); - TU_LOG3(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); - ncm_interface.recv_glue_ntb_datagram_ndx = 0; - } - - if (ncm_interface.recv_glue_ntb != NULL) { - const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *)(ncm_interface.recv_glue_ntb->data - + ncm_interface.recv_glue_ntb->nth.wNdpIndex - + sizeof(ndp16_t)); - - if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { - TU_LOG1("(EE) SOMETHING WENT WRONG 1\n"); - } - else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { - TU_LOG1("(EE) SOMETHING WENT WRONG 2\n"); - } - else { - uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; - uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; - - TU_LOG3(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); - if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { - // - // send datagram successfully to glue logic - // - TU_LOG3(" OK\n"); - datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; - datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; - - if (datagramIndex != 0 && datagramLength != 0) { - // -> next datagram - ++ncm_interface.recv_glue_ntb_datagram_ndx; - } - else { - // end of datagrams reached - recv_put_ntb_into_free_list(ncm_interface.recv_glue_ntb); - ncm_interface.recv_glue_ntb = NULL; - } - } +static void recv_transfer_datagram_to_glue_logic(void) { + TU_LOG_DRV("recv_transfer_datagram_to_glue_logic()\n"); + + if (ncm_interface.recv_glue_ntb == NULL) { + ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); + TU_LOG_DRV(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb_datagram_ndx = 0; + } + + if (ncm_interface.recv_glue_ntb != NULL) { + const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *) (ncm_interface.recv_glue_ntb->data + ncm_interface.recv_glue_ntb->nth.wNdpIndex + sizeof(ndp16_t)); + + if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { + TU_LOG_DRV("(EE) SOMETHING WENT WRONG 1\n"); + } else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { + TU_LOG_DRV("(EE) SOMETHING WENT WRONG 2\n"); + } else { + uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; + uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; + + TU_LOG_DRV(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); + if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { + // send datagram successfully to glue logic + TU_LOG_DRV(" OK\n"); + datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; + datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; + + if (datagramIndex != 0 && datagramLength != 0) { + // -> next datagram + ++ncm_interface.recv_glue_ntb_datagram_ndx; + } else { + // end of datagrams reached + recv_put_ntb_into_free_list(ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb = NULL; } + } } -} // recv_transfer_datagram_to_glue_logic - + } +} // recv_transfer_datagram_to_glue_logic //----------------------------------------------------------------------------- // // all the tud_network_*() stuff (glue logic -> driver) // - -bool tud_network_can_xmit(uint16_t size) /** * Check if the glue logic is allowed to call tud_network_xmit(). * This function also fetches a next buffer if required, so that tud_network_xmit() is ready for copy * and transmission operation. */ -{ - TU_LOG3("tud_network_can_xmit(%d)\n", size); - - TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)), false); - - if (xmit_requested_datagram_fits_into_current_ntb(size) || xmit_setup_next_glue_ntb()) { - // -> everything is fine - return true; - } - xmit_start_if_possible(ncm_interface.rhport); - TU_LOG2("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) - return false; -} // tud_network_can_xmit +bool tud_network_can_xmit(uint16_t size) { + TU_LOG_DRV("tud_network_can_xmit(%d)\n", size); + TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)), false); + if (xmit_requested_datagram_fits_into_current_ntb(size) || xmit_setup_next_glue_ntb()) { + // -> everything is fine + return true; + } + xmit_start_if_possible(ncm_interface.rhport); + TU_LOG_DRV("(II) tud_network_can_xmit: request blocked\n");// could happen if all xmit buffers are full (but should happen rarely) + return false; +} // tud_network_can_xmit -void tud_network_xmit(void *ref, uint16_t arg) /** * Put a datagram into a waiting NTB. * If currently no transmission is started, then initiate transmission. */ -{ - TU_LOG3("tud_network_xmit(%p, %d)\n", ref, arg); - - if (ncm_interface.xmit_glue_ntb == NULL) { - TU_LOG1("(EE) tud_network_xmit: no buffer\n"); // must not happen (really) - return; - } - - xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; +void tud_network_xmit(void *ref, uint16_t arg) { + TU_LOG_DRV("tud_network_xmit(%p, %d)\n", ref, arg); - // copy new datagram to the end of the current NTB - uint16_t size = tud_network_xmit_cb(ntb->data + ntb->nth.wBlockLength, ref, arg); + if (ncm_interface.xmit_glue_ntb == NULL) { + TU_LOG_DRV("(EE) tud_network_xmit: no buffer\n");// must not happen (really) + return; + } - // correct NTB internals - ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramIndex = ntb->nth.wBlockLength; - ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; - ncm_interface.xmit_glue_ntb_datagram_ndx += 1; + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; - ntb->nth.wBlockLength += (uint16_t)(size + XMIT_ALIGN_OFFSET(size)); + // copy new datagram to the end of the current NTB + uint16_t size = tud_network_xmit_cb(ntb->data + ntb->nth.wBlockLength, ref, arg); - if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - TU_LOG1("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) - return; - } + // correct NTB internals + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramIndex = ntb->nth.wBlockLength; + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; + ncm_interface.xmit_glue_ntb_datagram_ndx += 1; - xmit_start_if_possible(ncm_interface.rhport); -} // tud_network_xmit + ntb->nth.wBlockLength += (uint16_t) (size + XMIT_ALIGN_OFFSET(size)); + if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + TU_LOG_DRV("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) + return; + } + xmit_start_if_possible(ncm_interface.rhport); +} // tud_network_xmit -void tud_network_recv_renew(void) /** * Keep the receive logic busy and transfer pending packets to the glue logic. */ -{ - TU_LOG3("tud_network_recv_renew()\n"); +void tud_network_recv_renew(void) { + TU_LOG_DRV("tud_network_recv_renew()\n"); - recv_transfer_datagram_to_glue_logic(); - recv_try_to_start_new_reception(ncm_interface.rhport); -} // tud_network_recv_renew + recv_transfer_datagram_to_glue_logic(); + recv_try_to_start_new_reception(ncm_interface.rhport); +} // tud_network_recv_renew - - -void tud_network_recv_renew_r(uint8_t rhport) /** * Same as tud_network_recv_renew() but knows \a rhport */ -{ - TU_LOG3("tud_network_recv_renew_r(%d)\n", rhport); - - ncm_interface.rhport = rhport; - tud_network_recv_renew(); -} // tud_network_recv_renew +void tud_network_recv_renew_r(uint8_t rhport) { + TU_LOG_DRV("tud_network_recv_renew_r(%d)\n", rhport); + ncm_interface.rhport = rhport; + tud_network_recv_renew(); +} // tud_network_recv_renew //----------------------------------------------------------------------------- // // all the netd_*() stuff (interface TinyUSB -> driver) // -void netd_init(void) /** * Initialize the driver data structures. * Might be called several times. */ -{ - TU_LOG3("netd_init()\n"); +void netd_init(void) { + TU_LOG_DRV("netd_init()\n"); - memset( &ncm_interface, 0, sizeof(ncm_interface)); - - for (int i = 0; i < XMIT_NTB_N; ++i) { - ncm_interface.xmit_free_ntb[i] = ncm_interface.xmit_ntb + i; - } - for (int i = 0; i < RECV_NTB_N; ++i) { - ncm_interface.recv_free_ntb[i] = ncm_interface.recv_ntb + i; - } -} // netd_init + memset(&ncm_interface, 0, sizeof(ncm_interface)); + for (int i = 0; i < XMIT_NTB_N; ++i) { + ncm_interface.xmit_free_ntb[i] = ncm_interface.xmit_ntb + i; + } + for (int i = 0; i < RECV_NTB_N; ++i) { + ncm_interface.recv_free_ntb[i] = ncm_interface.recv_ntb + i; + } +} // netd_init - -bool netd_deinit(void) /** * Deinit driver */ -{ - return true; +bool netd_deinit(void) { + return true; } - - -void netd_reset(uint8_t rhport) /** * Resets the port. * In this driver this is the same as netd_init() */ -{ - (void)rhport; - - TU_LOG3("netd_reset(%d)\n", rhport); +void netd_reset(uint8_t rhport) { + (void) rhport; - netd_init(); -} // netd_reset + netd_init(); +} // netd_reset - - -uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) /** * Open the USB interface. * - parse the USB descriptor \a TUD_CDC_NCM_DESCRIPTOR for itfnum and endpoints @@ -850,174 +757,137 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 * - \a ep_notif, \a ep_in and \a ep_out are set * - USB interface is open */ -{ - TU_LOG3("netd_open(%d,%p,%d)\n", rhport, itf_desc, max_len); - - TU_ASSERT(ncm_interface.ep_notif == 0, 0); // assure that the interface is only opened once +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + TU_ASSERT(ncm_interface.ep_notif == 0, 0);// assure that the interface is only opened once - ncm_interface.itf_num = itf_desc->bInterfaceNumber; // management interface + ncm_interface.itf_num = itf_desc->bInterfaceNumber;// management interface - // - // skip the two first entries and the following TUSB_DESC_CS_INTERFACE entries - // - uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const *p_desc = tu_desc_next(itf_desc); - while (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && drv_len <= max_len) { - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } - - // - // get notification endpoint - // - TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); - 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; + // skip the two first entries and the following TUSB_DESC_CS_INTERFACE entries + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const *p_desc = tu_desc_next(itf_desc); + while (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && drv_len <= max_len) { drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); + } - // - // skip the following TUSB_DESC_INTERFACE entries (which must be TUSB_CLASS_CDC_DATA) - // - while (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && drv_len <= max_len) { - tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const*)p_desc; - TU_ASSERT(data_itf_desc->bInterfaceClass == TUSB_CLASS_CDC_DATA, 0); + // get notification endpoint + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); + 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); - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } + // skip the following TUSB_DESC_INTERFACE entries (which must be TUSB_CLASS_CDC_DATA) + while (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && drv_len <= max_len) { + tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const *) p_desc; + TU_ASSERT(data_itf_desc->bInterfaceClass == TUSB_CLASS_CDC_DATA, 0); - // - // a TUSB_DESC_ENDPOINT (actually two) must follow, open these endpoints - // - TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 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; -} // netd_open + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + // a TUSB_DESC_ENDPOINT (actually two) must follow, open these endpoints + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 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; +} // netd_open -bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) /** * Handle TinyUSB requests to process transfer events. */ -{ - (void)result; - - TU_LOG3("netd_xfer_cb(%d,%d,%d,%u)\n", rhport, ep_addr, result, (unsigned)xferred_bytes); - - if (ep_addr == ncm_interface.ep_out) { - // - // new NTB received - // - make the NTB valid - // - if ready transfer datagrams to the glue logic for further processing - // - if there is a free receive buffer, initiate reception - // - TU_LOG3(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); - if ( !recv_validate_datagram( ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { - // verification failed: ignore NTB and return it to free - TU_LOG1("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); - } - else { - // packet ok -> put it into ready list - recv_put_ntb_into_ready_list(ncm_interface.recv_tinyusb_ntb); - } - ncm_interface.recv_tinyusb_ntb = NULL; - tud_network_recv_renew_r(rhport); - } - else if (ep_addr == ncm_interface.ep_in) { - // - // transmission of an NTB finished - // - free the transmitted NTB buffer - // - insert ZLPs when necessary - // - if there is another transmit NTB waiting, try to start transmission - // - TU_LOG3(" EP_IN %d %u\n", ncm_interface.itf_data_alt, (unsigned)xferred_bytes); - xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); - ncm_interface.xmit_tinyusb_ntb = NULL; - if ( !xmit_insert_required_zlp(rhport, xferred_bytes)) { - xmit_start_if_possible(rhport); - } - } - else if (ep_addr == ncm_interface.ep_notif) { - // - // next transfer on notification channel - // - TU_LOG3(" EP_NOTIF\n"); - notification_xmit(rhport, true); - } - - return true; -} // netd_xfer_cb - - +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) result; + + if (ep_addr == ncm_interface.ep_out) { + // new NTB received + // - make the NTB valid + // - if ready transfer datagrams to the glue logic for further processing + // - if there is a free receive buffer, initiate reception + if (!recv_validate_datagram(ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { + // verification failed: ignore NTB and return it to free + TU_LOG_DRV("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + } else { + // packet ok -> put it into ready list + recv_put_ntb_into_ready_list(ncm_interface.recv_tinyusb_ntb); + } + ncm_interface.recv_tinyusb_ntb = NULL; + tud_network_recv_renew_r(rhport); + } else if (ep_addr == ncm_interface.ep_in) { + // transmission of an NTB finished + // - free the transmitted NTB buffer + // - insert ZLPs when necessary + // - if there is another transmit NTB waiting, try to start transmission + xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); + ncm_interface.xmit_tinyusb_ntb = NULL; + if (!xmit_insert_required_zlp(rhport, xferred_bytes)) { + xmit_start_if_possible(rhport); + } + } else if (ep_addr == ncm_interface.ep_notif) { + // next transfer on notification channel + notification_xmit(rhport, true); + } + + return true; +} // netd_xfer_cb -bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) /** * Respond to TinyUSB control requests. * At startup transmission of notification packets are done here. */ -{ - TU_LOG3("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, 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; + } - if (stage != CONTROL_STAGE_SETUP) { - return true; - } + switch (request->bmRequestType_bit.type) { + case TUSB_REQ_TYPE_STANDARD: - switch (request->bmRequestType_bit.type) { - case TUSB_REQ_TYPE_STANDARD: - TU_LOG3(" TUSB_REQ_TYPE_STANDARD: %d\n", request->bRequest); - - switch (request->bRequest) { - case TUSB_REQ_GET_INTERFACE: { - TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); - - TU_LOG3(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); - tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); - } - break; - - case TUSB_REQ_SET_INTERFACE: { - TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); - - ncm_interface.itf_data_alt = (uint8_t)request->wValue; - TU_LOG3(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); - - if (ncm_interface.itf_data_alt == 1) { - tud_network_recv_renew_r(rhport); - notification_xmit(rhport, 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, false); - - TU_LOG3(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - - if (request->bRequest == NCM_GET_NTB_PARAMETERS) { - // transfer NTB parameters to host. - // TODO can one assume, that tud_control_xfer() succeeds? - TU_LOG3(" NCM_GET_NTB_PARAMETERS\n"); - tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); - } - break; - - // unsupported request - default: - return false ; - } + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); - return true; -} // netd_control_xfer_cb + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + } break; -#endif // ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + case TUSB_REQ_SET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); + + ncm_interface.itf_data_alt = (uint8_t) request->wValue; + + if (ncm_interface.itf_data_alt == 1) { + tud_network_recv_renew_r(rhport); + notification_xmit(rhport, 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, false); + switch (request->bRequest) { + case NCM_GET_NTB_PARAMETERS: { + // transfer NTB parameters to host. + tud_control_xfer(rhport, request, (void *) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } break; + + // unsupported request + default: + return false; + } + break; + // unsupported request + default: + return false; + } + + return true; +} // netd_control_xfer_cb + +#endif // ( CFG_TUD_ENABLED && CFG_TUD_NCM ) -- cgit v1.3.1 From d01b2cfc0e25e6d64f8d7a2d764c2620e0d9d71f Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 7 May 2024 20:17:48 +1000 Subject: Add option to make CDC TX buffer persistent. --- src/class/cdc/cdc_device.c | 2 ++ src/class/cdc/cdc_device.h | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'src/class') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 2e0a0c30d..f36725eba 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -295,7 +295,9 @@ void cdcd_reset(uint8_t rhport) tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); tu_fifo_clear(&p_cdc->rx_ff); + #if !CFG_TUD_CDC_PERSISTENT_TX_BUFF tu_fifo_clear(&p_cdc->tx_ff); + #endif tu_fifo_set_overwritable(&p_cdc->tx_ff, true); } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 20e908451..db709b3bc 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -41,6 +41,12 @@ #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif +// By default the TX fifo buffer is cleared on connect / bus reset. +// Enable this to persist any data in the fifo instead. +#ifndef CFG_TUD_CDC_PERSISTENT_TX_BUFF + #define CFG_TUD_CDC_PERSISTENT_TX_BUFF (0) +#endif + #ifdef __cplusplus extern "C" { #endif -- cgit v1.3.1 From 2b9e53772e73c2bfd07bbbf4d6d2f0b33bcd22fb Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 16:28:25 +0200 Subject: Take updated change from cdc_device. --- src/class/vendor/vendor_device.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index e87ce3997..56ef098c7 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -36,6 +36,8 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + typedef struct { uint8_t itf_num; @@ -273,7 +275,6 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) rhport; (void) result; uint8_t itf = 0; @@ -300,7 +301,18 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint { if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); // Send complete, try to send more if possible - tud_vendor_n_write_flush(itf); + if ( 0 == tud_vendor_n_write_flush(itf) ) + { + // If there is no data left, a ZLP should be sent if + // xferred_bytes is multiple of EP Packet size and not zero + if ( !tu_fifo_count(&p_itf->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) + { + if ( usbd_edpt_claim(rhport, p_itf->ep_in) ) + { + usbd_edpt_xfer(rhport, p_itf->ep_in, NULL, 0); + } + } + } } return true; -- cgit v1.3.1 From 015b57b6ef5cd24db8665c62e8fe209bce3e2b7e Mon Sep 17 00:00:00 2001 From: John Toniutti Date: Thu, 9 May 2024 17:05:14 +0200 Subject: Add missing key codes Source: https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf from page 57 to page 59 --- src/class/hid/hid.h | 389 +++++++++++++++++++++++++++++----------------------- 1 file changed, 218 insertions(+), 171 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index e949f1f83..03ef24f78 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -366,177 +366,224 @@ typedef enum //--------------------------------------------------------------------+ // HID KEYCODE //--------------------------------------------------------------------+ -#define HID_KEY_NONE 0x00 -#define HID_KEY_A 0x04 -#define HID_KEY_B 0x05 -#define HID_KEY_C 0x06 -#define HID_KEY_D 0x07 -#define HID_KEY_E 0x08 -#define HID_KEY_F 0x09 -#define HID_KEY_G 0x0A -#define HID_KEY_H 0x0B -#define HID_KEY_I 0x0C -#define HID_KEY_J 0x0D -#define HID_KEY_K 0x0E -#define HID_KEY_L 0x0F -#define HID_KEY_M 0x10 -#define HID_KEY_N 0x11 -#define HID_KEY_O 0x12 -#define HID_KEY_P 0x13 -#define HID_KEY_Q 0x14 -#define HID_KEY_R 0x15 -#define HID_KEY_S 0x16 -#define HID_KEY_T 0x17 -#define HID_KEY_U 0x18 -#define HID_KEY_V 0x19 -#define HID_KEY_W 0x1A -#define HID_KEY_X 0x1B -#define HID_KEY_Y 0x1C -#define HID_KEY_Z 0x1D -#define HID_KEY_1 0x1E -#define HID_KEY_2 0x1F -#define HID_KEY_3 0x20 -#define HID_KEY_4 0x21 -#define HID_KEY_5 0x22 -#define HID_KEY_6 0x23 -#define HID_KEY_7 0x24 -#define HID_KEY_8 0x25 -#define HID_KEY_9 0x26 -#define HID_KEY_0 0x27 -#define HID_KEY_ENTER 0x28 -#define HID_KEY_ESCAPE 0x29 -#define HID_KEY_BACKSPACE 0x2A -#define HID_KEY_TAB 0x2B -#define HID_KEY_SPACE 0x2C -#define HID_KEY_MINUS 0x2D -#define HID_KEY_EQUAL 0x2E -#define HID_KEY_BRACKET_LEFT 0x2F -#define HID_KEY_BRACKET_RIGHT 0x30 -#define HID_KEY_BACKSLASH 0x31 -#define HID_KEY_EUROPE_1 0x32 -#define HID_KEY_SEMICOLON 0x33 -#define HID_KEY_APOSTROPHE 0x34 -#define HID_KEY_GRAVE 0x35 -#define HID_KEY_COMMA 0x36 -#define HID_KEY_PERIOD 0x37 -#define HID_KEY_SLASH 0x38 -#define HID_KEY_CAPS_LOCK 0x39 -#define HID_KEY_F1 0x3A -#define HID_KEY_F2 0x3B -#define HID_KEY_F3 0x3C -#define HID_KEY_F4 0x3D -#define HID_KEY_F5 0x3E -#define HID_KEY_F6 0x3F -#define HID_KEY_F7 0x40 -#define HID_KEY_F8 0x41 -#define HID_KEY_F9 0x42 -#define HID_KEY_F10 0x43 -#define HID_KEY_F11 0x44 -#define HID_KEY_F12 0x45 -#define HID_KEY_PRINT_SCREEN 0x46 -#define HID_KEY_SCROLL_LOCK 0x47 -#define HID_KEY_PAUSE 0x48 -#define HID_KEY_INSERT 0x49 -#define HID_KEY_HOME 0x4A -#define HID_KEY_PAGE_UP 0x4B -#define HID_KEY_DELETE 0x4C -#define HID_KEY_END 0x4D -#define HID_KEY_PAGE_DOWN 0x4E -#define HID_KEY_ARROW_RIGHT 0x4F -#define HID_KEY_ARROW_LEFT 0x50 -#define HID_KEY_ARROW_DOWN 0x51 -#define HID_KEY_ARROW_UP 0x52 -#define HID_KEY_NUM_LOCK 0x53 -#define HID_KEY_KEYPAD_DIVIDE 0x54 -#define HID_KEY_KEYPAD_MULTIPLY 0x55 -#define HID_KEY_KEYPAD_SUBTRACT 0x56 -#define HID_KEY_KEYPAD_ADD 0x57 -#define HID_KEY_KEYPAD_ENTER 0x58 -#define HID_KEY_KEYPAD_1 0x59 -#define HID_KEY_KEYPAD_2 0x5A -#define HID_KEY_KEYPAD_3 0x5B -#define HID_KEY_KEYPAD_4 0x5C -#define HID_KEY_KEYPAD_5 0x5D -#define HID_KEY_KEYPAD_6 0x5E -#define HID_KEY_KEYPAD_7 0x5F -#define HID_KEY_KEYPAD_8 0x60 -#define HID_KEY_KEYPAD_9 0x61 -#define HID_KEY_KEYPAD_0 0x62 -#define HID_KEY_KEYPAD_DECIMAL 0x63 -#define HID_KEY_EUROPE_2 0x64 -#define HID_KEY_APPLICATION 0x65 -#define HID_KEY_POWER 0x66 -#define HID_KEY_KEYPAD_EQUAL 0x67 -#define HID_KEY_F13 0x68 -#define HID_KEY_F14 0x69 -#define HID_KEY_F15 0x6A -#define HID_KEY_F16 0x6B -#define HID_KEY_F17 0x6C -#define HID_KEY_F18 0x6D -#define HID_KEY_F19 0x6E -#define HID_KEY_F20 0x6F -#define HID_KEY_F21 0x70 -#define HID_KEY_F22 0x71 -#define HID_KEY_F23 0x72 -#define HID_KEY_F24 0x73 -#define HID_KEY_EXECUTE 0x74 -#define HID_KEY_HELP 0x75 -#define HID_KEY_MENU 0x76 -#define HID_KEY_SELECT 0x77 -#define HID_KEY_STOP 0x78 -#define HID_KEY_AGAIN 0x79 -#define HID_KEY_UNDO 0x7A -#define HID_KEY_CUT 0x7B -#define HID_KEY_COPY 0x7C -#define HID_KEY_PASTE 0x7D -#define HID_KEY_FIND 0x7E -#define HID_KEY_MUTE 0x7F -#define HID_KEY_VOLUME_UP 0x80 -#define HID_KEY_VOLUME_DOWN 0x81 -#define HID_KEY_LOCKING_CAPS_LOCK 0x82 -#define HID_KEY_LOCKING_NUM_LOCK 0x83 -#define HID_KEY_LOCKING_SCROLL_LOCK 0x84 -#define HID_KEY_KEYPAD_COMMA 0x85 -#define HID_KEY_KEYPAD_EQUAL_SIGN 0x86 -#define HID_KEY_KANJI1 0x87 -#define HID_KEY_KANJI2 0x88 -#define HID_KEY_KANJI3 0x89 -#define HID_KEY_KANJI4 0x8A -#define HID_KEY_KANJI5 0x8B -#define HID_KEY_KANJI6 0x8C -#define HID_KEY_KANJI7 0x8D -#define HID_KEY_KANJI8 0x8E -#define HID_KEY_KANJI9 0x8F -#define HID_KEY_LANG1 0x90 -#define HID_KEY_LANG2 0x91 -#define HID_KEY_LANG3 0x92 -#define HID_KEY_LANG4 0x93 -#define HID_KEY_LANG5 0x94 -#define HID_KEY_LANG6 0x95 -#define HID_KEY_LANG7 0x96 -#define HID_KEY_LANG8 0x97 -#define HID_KEY_LANG9 0x98 -#define HID_KEY_ALTERNATE_ERASE 0x99 -#define HID_KEY_SYSREQ_ATTENTION 0x9A -#define HID_KEY_CANCEL 0x9B -#define HID_KEY_CLEAR 0x9C -#define HID_KEY_PRIOR 0x9D -#define HID_KEY_RETURN 0x9E -#define HID_KEY_SEPARATOR 0x9F -#define HID_KEY_OUT 0xA0 -#define HID_KEY_OPER 0xA1 -#define HID_KEY_CLEAR_AGAIN 0xA2 -#define HID_KEY_CRSEL_PROPS 0xA3 -#define HID_KEY_EXSEL 0xA4 -// RESERVED 0xA5-DF -#define HID_KEY_CONTROL_LEFT 0xE0 -#define HID_KEY_SHIFT_LEFT 0xE1 -#define HID_KEY_ALT_LEFT 0xE2 -#define HID_KEY_GUI_LEFT 0xE3 -#define HID_KEY_CONTROL_RIGHT 0xE4 -#define HID_KEY_SHIFT_RIGHT 0xE5 -#define HID_KEY_ALT_RIGHT 0xE6 -#define HID_KEY_GUI_RIGHT 0xE7 +#define HID_KEY_NONE 0x00 +#define HID_KEY_A 0x04 +#define HID_KEY_B 0x05 +#define HID_KEY_C 0x06 +#define HID_KEY_D 0x07 +#define HID_KEY_E 0x08 +#define HID_KEY_F 0x09 +#define HID_KEY_G 0x0A +#define HID_KEY_H 0x0B +#define HID_KEY_I 0x0C +#define HID_KEY_J 0x0D +#define HID_KEY_K 0x0E +#define HID_KEY_L 0x0F +#define HID_KEY_M 0x10 +#define HID_KEY_N 0x11 +#define HID_KEY_O 0x12 +#define HID_KEY_P 0x13 +#define HID_KEY_Q 0x14 +#define HID_KEY_R 0x15 +#define HID_KEY_S 0x16 +#define HID_KEY_T 0x17 +#define HID_KEY_U 0x18 +#define HID_KEY_V 0x19 +#define HID_KEY_W 0x1A +#define HID_KEY_X 0x1B +#define HID_KEY_Y 0x1C +#define HID_KEY_Z 0x1D +#define HID_KEY_1 0x1E +#define HID_KEY_2 0x1F +#define HID_KEY_3 0x20 +#define HID_KEY_4 0x21 +#define HID_KEY_5 0x22 +#define HID_KEY_6 0x23 +#define HID_KEY_7 0x24 +#define HID_KEY_8 0x25 +#define HID_KEY_9 0x26 +#define HID_KEY_0 0x27 +#define HID_KEY_ENTER 0x28 +#define HID_KEY_ESCAPE 0x29 +#define HID_KEY_BACKSPACE 0x2A +#define HID_KEY_TAB 0x2B +#define HID_KEY_SPACE 0x2C +#define HID_KEY_MINUS 0x2D +#define HID_KEY_EQUAL 0x2E +#define HID_KEY_BRACKET_LEFT 0x2F +#define HID_KEY_BRACKET_RIGHT 0x30 +#define HID_KEY_BACKSLASH 0x31 +#define HID_KEY_EUROPE_1 0x32 +#define HID_KEY_SEMICOLON 0x33 +#define HID_KEY_APOSTROPHE 0x34 +#define HID_KEY_GRAVE 0x35 +#define HID_KEY_COMMA 0x36 +#define HID_KEY_PERIOD 0x37 +#define HID_KEY_SLASH 0x38 +#define HID_KEY_CAPS_LOCK 0x39 +#define HID_KEY_F1 0x3A +#define HID_KEY_F2 0x3B +#define HID_KEY_F3 0x3C +#define HID_KEY_F4 0x3D +#define HID_KEY_F5 0x3E +#define HID_KEY_F6 0x3F +#define HID_KEY_F7 0x40 +#define HID_KEY_F8 0x41 +#define HID_KEY_F9 0x42 +#define HID_KEY_F10 0x43 +#define HID_KEY_F11 0x44 +#define HID_KEY_F12 0x45 +#define HID_KEY_PRINT_SCREEN 0x46 +#define HID_KEY_SCROLL_LOCK 0x47 +#define HID_KEY_PAUSE 0x48 +#define HID_KEY_INSERT 0x49 +#define HID_KEY_HOME 0x4A +#define HID_KEY_PAGE_UP 0x4B +#define HID_KEY_DELETE 0x4C +#define HID_KEY_END 0x4D +#define HID_KEY_PAGE_DOWN 0x4E +#define HID_KEY_ARROW_RIGHT 0x4F +#define HID_KEY_ARROW_LEFT 0x50 +#define HID_KEY_ARROW_DOWN 0x51 +#define HID_KEY_ARROW_UP 0x52 +#define HID_KEY_NUM_LOCK 0x53 +#define HID_KEY_KEYPAD_DIVIDE 0x54 +#define HID_KEY_KEYPAD_MULTIPLY 0x55 +#define HID_KEY_KEYPAD_SUBTRACT 0x56 +#define HID_KEY_KEYPAD_ADD 0x57 +#define HID_KEY_KEYPAD_ENTER 0x58 +#define HID_KEY_KEYPAD_1 0x59 +#define HID_KEY_KEYPAD_2 0x5A +#define HID_KEY_KEYPAD_3 0x5B +#define HID_KEY_KEYPAD_4 0x5C +#define HID_KEY_KEYPAD_5 0x5D +#define HID_KEY_KEYPAD_6 0x5E +#define HID_KEY_KEYPAD_7 0x5F +#define HID_KEY_KEYPAD_8 0x60 +#define HID_KEY_KEYPAD_9 0x61 +#define HID_KEY_KEYPAD_0 0x62 +#define HID_KEY_KEYPAD_DECIMAL 0x63 +#define HID_KEY_EUROPE_2 0x64 +#define HID_KEY_APPLICATION 0x65 +#define HID_KEY_POWER 0x66 +#define HID_KEY_KEYPAD_EQUAL 0x67 +#define HID_KEY_F13 0x68 +#define HID_KEY_F14 0x69 +#define HID_KEY_F15 0x6A +#define HID_KEY_F16 0x6B +#define HID_KEY_F17 0x6C +#define HID_KEY_F18 0x6D +#define HID_KEY_F19 0x6E +#define HID_KEY_F20 0x6F +#define HID_KEY_F21 0x70 +#define HID_KEY_F22 0x71 +#define HID_KEY_F23 0x72 +#define HID_KEY_F24 0x73 +#define HID_KEY_EXECUTE 0x74 +#define HID_KEY_HELP 0x75 +#define HID_KEY_MENU 0x76 +#define HID_KEY_SELECT 0x77 +#define HID_KEY_STOP 0x78 +#define HID_KEY_AGAIN 0x79 +#define HID_KEY_UNDO 0x7A +#define HID_KEY_CUT 0x7B +#define HID_KEY_COPY 0x7C +#define HID_KEY_PASTE 0x7D +#define HID_KEY_FIND 0x7E +#define HID_KEY_MUTE 0x7F +#define HID_KEY_VOLUME_UP 0x80 +#define HID_KEY_VOLUME_DOWN 0x81 +#define HID_KEY_LOCKING_CAPS_LOCK 0x82 +#define HID_KEY_LOCKING_NUM_LOCK 0x83 +#define HID_KEY_LOCKING_SCROLL_LOCK 0x84 +#define HID_KEY_KEYPAD_COMMA 0x85 +#define HID_KEY_KEYPAD_EQUAL_SIGN 0x86 +#define HID_KEY_KANJI1 0x87 +#define HID_KEY_KANJI2 0x88 +#define HID_KEY_KANJI3 0x89 +#define HID_KEY_KANJI4 0x8A +#define HID_KEY_KANJI5 0x8B +#define HID_KEY_KANJI6 0x8C +#define HID_KEY_KANJI7 0x8D +#define HID_KEY_KANJI8 0x8E +#define HID_KEY_KANJI9 0x8F +#define HID_KEY_LANG1 0x90 +#define HID_KEY_LANG2 0x91 +#define HID_KEY_LANG3 0x92 +#define HID_KEY_LANG4 0x93 +#define HID_KEY_LANG5 0x94 +#define HID_KEY_LANG6 0x95 +#define HID_KEY_LANG7 0x96 +#define HID_KEY_LANG8 0x97 +#define HID_KEY_LANG9 0x98 +#define HID_KEY_ALTERNATE_ERASE 0x99 +#define HID_KEY_SYSREQ_ATTENTION 0x9A +#define HID_KEY_CANCEL 0x9B +#define HID_KEY_CLEAR 0x9C +#define HID_KEY_PRIOR 0x9D +#define HID_KEY_RETURN 0x9E +#define HID_KEY_SEPARATOR 0x9F +#define HID_KEY_OUT 0xA0 +#define HID_KEY_OPER 0xA1 +#define HID_KEY_CLEAR_AGAIN 0xA2 +#define HID_KEY_CRSEL_PROPS 0xA3 +#define HID_KEY_EXSEL 0xA4 +// RESERVED 0xA5-AF +#define HID_KEY_KEYPAD_00 0xB0 +#define HID_KEY_KEYPAD_000 0xB1 +#define HID_KEY_THOUSANDS_SEPARATOR 0xB2 +#define HID_KEY_DECIMAL_SEPARATOR 0xB3 +#define HID_KEY_CURRENCY_UNIT 0xB4 +#define HID_KEY_CURRENCY_SUBUNIT 0xB5 +#define HID_KEY_KEYPAD_LEFT_PARENTHESIS 0xB6 +#define HID_KEY_KEYPAD_RIGHT_PARENTHESIS 0xB7 +#define HID_KEY_KEYPAD_LEFT_BRACE 0xB8 +#define HID_KEY_KEYPAD_RIGHT_BRACE 0xB9 +#define HID_KEY_KEYPAD_TAB 0xBA +#define HID_KEY_KEYPAD_BACKSPACE 0xBB +#define HID_KEY_KEYPAD_A 0xBC +#define HID_KEY_KEYPAD_B 0xBD +#define HID_KEY_KEYPAD_C 0xBE +#define HID_KEY_KEYPAD_D 0xBF +#define HID_KEY_KEYPAD_E 0xC0 +#define HID_KEY_KEYPAD_F 0xC1 +#define HID_KEY_KEYPAD_XOR 0xC2 +#define HID_KEY_KEYPAD_CARET 0xC3 +#define HID_KEY_KEYPAD_PERCENT 0xC4 +#define HID_KEY_KEYPAD_LESS_THAN 0xC5 +#define HID_KEY_KEYPAD_GREATER_THAN 0xC6 +#define HID_KEY_KEYPAD_AMPERSAND 0xC7 +#define HID_KEY_KEYPAD_DOUBLE_AMPERSAND 0xC8 +#define HID_KEY_KEYPAD_VERTICAL_BAR 0xC9 +#define HID_KEY_KEYPAD_DOUBLE_VERTICAL_BAR 0xCA +#define HID_KEY_KEYPAD_COLON 0xCB +#define HID_KEY_KEYPAD_HASH 0xCC +#define HID_KEY_KEYPAD_SPACE 0xCD +#define HID_KEY_KEYPAD_AT 0xCE +#define HID_KEY_KEYPAD_EXCLAMATION 0xCF +#define HID_KEY_KEYPAD_MEMORY_STORE 0xD0 +#define HID_KEY_KEYPAD_MEMORY_RECALL 0xD1 +#define HID_KEY_KEYPAD_MEMORY_CLEAR 0xD2 +#define HID_KEY_KEYPAD_MEMORY_ADD 0xD3 +#define HID_KEY_KEYPAD_MEMORY_SUBTRACT 0xD4 +#define HID_KEY_KEYPAD_MEMORY_MULTIPLY 0xD5 +#define HID_KEY_KEYPAD_MEMORY_DIVIDE 0xD6 +#define HID_KEY_KEYPAD_PLUS_MINUS 0xD7 +#define HID_KEY_KEYPAD_CLEAR 0xD8 +#define HID_KEY_KEYPAD_CLEAR_ENTRY 0xD9 +#define HID_KEY_KEYPAD_BINARY 0xDA +#define HID_KEY_KEYPAD_OCTAL 0xDB +#define HID_KEY_KEYPAD_DECIMAL 0xDC +#define HID_KEY_KEYPAD_HEXADECIMAL 0xDD +// RESERVED 0xDE-DF +#define HID_KEY_CONTROL_LEFT 0xE0 +#define HID_KEY_SHIFT_LEFT 0xE1 +#define HID_KEY_ALT_LEFT 0xE2 +#define HID_KEY_GUI_LEFT 0xE3 +#define HID_KEY_CONTROL_RIGHT 0xE4 +#define HID_KEY_SHIFT_RIGHT 0xE5 +#define HID_KEY_ALT_RIGHT 0xE6 +#define HID_KEY_GUI_RIGHT 0xE7 //--------------------------------------------------------------------+ -- cgit v1.3.1 From f09fa22bbce6139810db785940c56c5048794f31 Mon Sep 17 00:00:00 2001 From: John Toniutti Date: Thu, 9 May 2024 18:45:20 +0200 Subject: Fix redefinition --- src/class/hid/hid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 03ef24f78..2fe922136 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -573,7 +573,7 @@ typedef enum #define HID_KEY_KEYPAD_CLEAR_ENTRY 0xD9 #define HID_KEY_KEYPAD_BINARY 0xDA #define HID_KEY_KEYPAD_OCTAL 0xDB -#define HID_KEY_KEYPAD_DECIMAL 0xDC +#define HID_KEY_KEYPAD_DECIMAL_2 0xDC #define HID_KEY_KEYPAD_HEXADECIMAL 0xDD // RESERVED 0xDE-DF #define HID_KEY_CONTROL_LEFT 0xE0 -- cgit v1.3.1 From 376b43906a901a878a07aca1cd364e32b839e656 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 21:55:28 +0200 Subject: Convert to bit-field since it's more reliable. --- src/class/audio/audio_device.c | 4 ++-- src/device/usbd.c | 22 ++++++++++------------ src/device/usbd_pvt.h | 11 ++++++++++- 3 files changed, 22 insertions(+), 15 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9ba38a20c..46db96ea9 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1835,7 +1835,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->feedback.frame_shift = desc_ep->bInterval -1; // Enable SOF interrupt if callback is implemented - if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); + if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, SOF_CONSUMER_AUDIO, true); } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1909,7 +1909,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * break; } } - if (disable) usbd_sof_enable(rhport, false); + if (disable) usbd_sof_enable(rhport, SOF_CONSUMER_AUDIO, false); #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL diff --git a/src/device/usbd.c b/src/device/usbd.c index 89b819b8e..3bd99ec40 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -76,13 +76,11 @@ typedef struct { uint8_t remote_wakeup_en : 1; // enable/disable by host uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute uint8_t self_powered : 1; // configuration descriptor's attribute - - uint8_t sof_cb_en : 1; // SOF user callback enable }; volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; volatile uint8_t setup_count; - uint8_t sof_ref_cnt; + volatile uint8_t sof_consumer; uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each @@ -392,10 +390,7 @@ bool tud_connect(void) { bool tud_sof_cb_enable(bool en) { - if(_usbd_dev.sof_cb_en != en) { - _usbd_dev.sof_cb_en = en; - usbd_sof_enable(_usbd_rhport, en); - } + usbd_sof_enable(_usbd_rhport, SOF_CONSUMER_USER, en); return true; } @@ -1384,18 +1379,21 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { return; } -void usbd_sof_enable(uint8_t rhport, bool en) { +void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en) { rhport = _usbd_rhport; + uint8_t consumer_old = _usbd_dev.sof_consumer; // Keep track how many class instances need the SOF interrupt if (en) { - _usbd_dev.sof_ref_cnt++; + _usbd_dev.sof_consumer = tu_bit_set(_usbd_dev.sof_consumer, consumer); } else { - _usbd_dev.sof_ref_cnt--; + _usbd_dev.sof_consumer = tu_bit_clear(_usbd_dev.sof_consumer, consumer); } - // Only disable SOF interrupts if all drivers switched off SOF calls and if the SOF callback isn't used - dcd_sof_enable(rhport, _usbd_dev.sof_ref_cnt ? true : false); + // Test logically unequal + if(!!_usbd_dev.sof_consumer != !!consumer_old) { + dcd_sof_enable(rhport, _usbd_dev.sof_consumer); + } } bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 7eb504246..335d46cd8 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -35,6 +35,15 @@ #define TU_LOG_USBD(...) TU_LOG(CFG_TUD_LOG_LEVEL, __VA_ARGS__) +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +typedef enum { + SOF_CONSUMER_USER = 0, + SOF_CONSUMER_AUDIO, +} sof_consumer_t; + //--------------------------------------------------------------------+ // Class Driver API //--------------------------------------------------------------------+ @@ -108,7 +117,7 @@ bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) { } // Enable SOF interrupt -void usbd_sof_enable(uint8_t rhport, bool en); +void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en); /*------------------------------------------------------------------*/ /* Helper -- cgit v1.3.1 From 3e2ea7750681b27238043c7158ff5508f01914a3 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 18:55:43 +0700 Subject: More ci tweak (#2636) * change concurrency group to ${{ github.workflow }}-${{ github.ref }} * use argparse for build.py hil_test.py, remove the need to install click * move ci win/mac to build_cmake.yml * rename build_family.yml to build_util.yml * build_util.yml support esp32 * integrate build-espressif into build.yml * build.py support make with --board option * add get_deps action * update hil test to reuse action --- .github/actions/get_deps/action.yml | 29 +++++++ .github/actions/prepare_build/action.yml | 30 ------- .github/actions/setup_toolchain/action.yml | 18 ++++- .github/workflows/build_cmake.yml | 46 +++++++++-- .github/workflows/build_esp.yml | 109 ------------------------- .github/workflows/build_family.yml | 64 --------------- .github/workflows/build_iar.yml | 2 +- .github/workflows/build_renesas.yml | 3 +- .github/workflows/build_util.yml | 59 ++++++++++++++ .github/workflows/build_win_mac.yml | 56 ------------- .github/workflows/ci_set_matrix.py | 2 +- .github/workflows/hil_test.yml | 121 ++++++++++++++++++++-------- .github/workflows/pre-commit.yml | 3 +- examples/device/net_lwip_webserver/skip.txt | 4 +- examples/device/video_capture_2ch/skip.txt | 2 + examples/host/cdc_msc_hid_freertos/only.txt | 1 - hw/bsp/lpc17/family.mk | 2 +- hw/bsp/lpc40/family.mk | 2 + src/class/net/ncm_device.c | 16 ++-- test/hil/hil_test.py | 19 +++-- test/hil/pi4.json | 10 +++ test/hil/pi4_esp32.json | 14 ---- tools/build.py | 46 +++++++---- tools/build_esp32.py | 106 ------------------------ tools/get_deps.py | 11 ++- 25 files changed, 314 insertions(+), 461 deletions(-) create mode 100644 .github/actions/get_deps/action.yml delete mode 100644 .github/actions/prepare_build/action.yml delete mode 100644 .github/workflows/build_esp.yml delete mode 100644 .github/workflows/build_family.yml create mode 100644 .github/workflows/build_util.yml delete mode 100644 .github/workflows/build_win_mac.yml delete mode 100644 test/hil/pi4_esp32.json delete mode 100644 tools/build_esp32.py (limited to 'src/class') diff --git a/.github/actions/get_deps/action.yml b/.github/actions/get_deps/action.yml new file mode 100644 index 000000000..38b44a70e --- /dev/null +++ b/.github/actions/get_deps/action.yml @@ -0,0 +1,29 @@ +name: Get dependencies + +inputs: + arg: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Checkout pico-sdk for rp2040 + if: contains(inputs.arg, 'rp2040') || contains(inputs.arg, 'raspberry_pi_pico') + uses: actions/checkout@v4 + with: + repository: raspberrypi/pico-sdk + ref: develop + path: pico-sdk + + - name: Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt install -y ninja-build + shell: bash + + - name: Get Dependencies + run: | + python3 tools/get_deps.py ${{ inputs.arg }} + echo "PICO_SDK_PATH=${{ github.workspace }}/pico-sdk" >> $GITHUB_ENV + shell: bash diff --git a/.github/actions/prepare_build/action.yml b/.github/actions/prepare_build/action.yml deleted file mode 100644 index 5f2c544c1..000000000 --- a/.github/actions/prepare_build/action.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Prepare to build - -inputs: - family: - required: true - type: string - -runs: - using: "composite" - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Checkout pico-sdk for rp2040 - if: contains(inputs.family, 'rp2040') - uses: actions/checkout@v4 - with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk - - - name: Get Dependencies - run: | - sudo apt install -y ninja-build - pip install click - python3 tools/get_deps.py ${{ inputs.family }} - echo >> $GITHUB_ENV "PICO_SDK_PATH=$GITHUB_WORKSPACE/pico-sdk" - shell: bash diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index b59ece116..e6c79e7dd 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -8,6 +8,11 @@ inputs: required: false type: string +outputs: + build_option: + description: 'Build option for the toolchain e.g --toolchain clang' + value: ${{ steps.set-toolchain-option.outputs.build_option }} + runs: using: "composite" steps: @@ -19,7 +24,7 @@ runs: - name: Pull ESP-IDF docker if: inputs.toolchain == 'esp-idf' - run: docker pull espressif/idf:latest + run: docker pull espressif/idf:${{ inputs.toolchain_url }} shell: bash - name: Download Toolchain @@ -29,3 +34,14 @@ runs: uses: ./.github/actions/setup_toolchain/download with: toolchain_url: ${{ inputs.toolchain_url }} + + - name: Set toolchain option + id: set-toolchain-option + run: | + BUILD_OPTION="" + if [[ "${{ inputs.toolchain }}" == *"clang"* ]]; then + BUILD_OPTION="--toolchain clang" + fi + echo "build_option=$BUILD_OPTION" + echo "build_option=$BUILD_OPTION" >> $GITHUB_OUTPUT + shell: bash diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index b62a0e9bd..4723cf8d9 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -12,6 +12,7 @@ on: - 'tools/build.py' - '.github/actions/**' - '.github/workflows/build_cmake.yml' + - '.github/workflows/build_util.yml' - '.github/workflows/ci_set_matrix.py' pull_request: branches: [ master ] @@ -24,9 +25,10 @@ on: - 'tools/build.py' - '.github/actions/**' - '.github/workflows/build_cmake.yml' + - '.github/workflows/build_util.yml' - '.github/workflows/ci_set_matrix.py' concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -55,7 +57,7 @@ jobs: # --------------------------------------- cmake: needs: set-matrix - uses: ./.github/workflows/build_family.yml + uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: @@ -69,14 +71,14 @@ jobs: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} - build-family: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} # --------------------------------------- # Build Make # --------------------------------------- make: needs: set-matrix - uses: ./.github/workflows/build_family.yml + uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: @@ -90,4 +92,38 @@ jobs: build-system: 'make' toolchain: ${{ matrix.toolchain }} toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} - build-family: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + + # --------------------------------------- + # Build Make on Windows/MacOS + # --------------------------------------- + make-os: + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + os: [windows-latest, macos-latest] + with: + os: ${{ matrix.os }} + build-system: 'make' + toolchain: 'arm-gcc' + build-args: '["-bstm32f411disco"]' + + # --------------------------------------- + # Build Espressif + # --------------------------------------- + espressif: + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + board: + # ESP32-S2 + - 'espressif_kaluga_1' + # ESP32-S3 skip since devkitm is also compiled in hil-test workflow + #- 'espressif_s3_devkitm' + with: + build-system: 'cmake' + toolchain: 'esp-idf' + toolchain_url: 'v5.1.1' + build-args: '["-b${{ matrix.board }}"]' diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml deleted file mode 100644 index 66fa8548e..000000000 --- a/.github/workflows/build_esp.yml +++ /dev/null @@ -1,109 +0,0 @@ -name: Build ESP - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'test/hil/**' - - '.github/workflows/build_esp.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'test/hil/**' - - '.github/workflows/build_esp.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-esp: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - board: - # ESP32-S2 - - 'espressif_kaluga_1' - # ESP32-S3 - - 'espressif_s3_devkitm' - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Setup Toolchain - uses: ./.github/actions/setup_toolchain - with: - toolchain: 'esp-idf' - - - name: Build - run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build.py -b ${{ matrix.board }} - - - name: Upload Artifacts for Hardware Testing - if: matrix.board == 'espressif_s3_devkitm' && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.board }} - path: | - cmake-build/cmake-build-${{ matrix.board }}/*/*/bootloader/bootloader.bin - cmake-build/cmake-build-${{ matrix.board }}/*/*/*.bin - cmake-build/cmake-build-${{ matrix.board }}/*/*/partition_table/partition-table.bin - cmake-build/cmake-build-${{ matrix.board }}/*/*/config.env - cmake-build/cmake-build-${{ matrix.board }}/*/*/flash_args - - # --------------------------------------- - # Hardware in the loop (HIL) - # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json - # --------------------------------------- - hil-test: - # run only with hathach's commit due to limited resource on RPI4 - if: github.repository_owner == 'hathach' - needs: build-esp - runs-on: [self-hosted, esp32s3, hardware-in-the-loop] - strategy: - fail-fast: false - matrix: - board: - - 'espressif_s3_devkitm' - steps: - - name: Clean workspace - run: | - echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}" - mkdir -p "${{ github.workspace }}" - - # USB bus on rpi4 is not stable, reset it before testing - - name: Reset USB bus - run: | - lsusb - lsusb -t - # reset VIA Labs 2.0 hub - sudo usbreset 001/002 - - - name: Checkout test/hil - uses: actions/checkout@v4 - with: - sparse-checkout: test/hil - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - name: ${{ matrix.board }} - path: cmake-build/cmake-build-${{ matrix.board }} - - - name: Test on actual hardware - run: | - python3 test/hil/hil_test.py --board ${{ matrix.board }} pi4_esp32.json diff --git a/.github/workflows/build_family.yml b/.github/workflows/build_family.yml deleted file mode 100644 index 2e89267a3..000000000 --- a/.github/workflows/build_family.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Build family - -on: - workflow_call: - inputs: - build-system: - required: true - type: string - toolchain: - required: true - type: string - toolchain_url: - required: true - type: string - build-family: - required: true - type: string - -jobs: - family: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: ${{ fromJSON(inputs.build-family) }} - steps: - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Setup Toolchain - uses: ./.github/actions/setup_toolchain - with: - toolchain: ${{ inputs.toolchain }} - toolchain_url: ${{ inputs.toolchain_url }} - - - name: Checkout pico-sdk for rp2040 - if: contains(matrix.family, 'rp2040') - uses: actions/checkout@v4 - with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk - - - name: Get Dependencies - run: | - sudo apt install -y ninja-build - pip install click - python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: | - OPTION="" - if [[ "${{ inputs.toolchain }}" == *"clang"* ]]; then - OPTION="--toolchain clang" - fi - echo "OPTION=$OPTION" - python tools/build.py -s ${{ inputs.build-system }} $OPTION ${{ matrix.family }} - env: - PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index c4a7f96b7..34dbda192 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -23,7 +23,7 @@ on: - '.github/workflows/build_iar.yml' concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 8c83bdbbf..1be49344f 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -21,7 +21,7 @@ on: - '.github/workflows/build_renesas.yml' concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -65,7 +65,6 @@ jobs: - name: Get Dependencies run: | - pip install click python3 tools/get_deps.py ${{ matrix.family }} - name: Build diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml new file mode 100644 index 000000000..f8ad1900c --- /dev/null +++ b/.github/workflows/build_util.yml @@ -0,0 +1,59 @@ +name: Reusable build util + +on: + workflow_call: + inputs: + build-system: + required: true + type: string + toolchain: + required: true + type: string + toolchain_url: + required: false + type: string + build-args: + required: true + type: string + os: + required: false + type: string + default: 'ubuntu-latest' + +jobs: + family: + runs-on: ${{ inputs.os }} + strategy: + fail-fast: false + matrix: + arg: ${{ fromJSON(inputs.build-args) }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Setup Toolchain + id: setup-toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: ${{ inputs.toolchain }} + toolchain_url: ${{ inputs.toolchain_url }} + + - name: Get Dependencies + uses: ./.github/actions/get_deps + with: + arg: ${{ matrix.arg }} + + - name: Build + if: inputs.toolchain != 'esp-idf' + run: | + python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ matrix.arg }} + + - name: Build using ESP-IDF docker + if: inputs.toolchain == 'esp-idf' + run: | + docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_url }} python3 tools/build.py ${{ matrix.arg }} diff --git a/.github/workflows/build_win_mac.yml b/.github/workflows/build_win_mac.yml deleted file mode 100644 index 35328aa32..000000000 --- a/.github/workflows/build_win_mac.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Build Windows/MacOS - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_win_mac.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_win_mac.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - # --------------------------------------- - # Build ARM family - # --------------------------------------- - build-arm: - strategy: - fail-fast: false - matrix: - os: [windows-latest, macos-latest] - runs-on: ${{ matrix.os }} - - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '10.3-2021.10' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Get Dependencies - run: | - pip install click - python3 tools/get_deps.py stm32f4 - - - name: Build - run: python3 tools/build.py -s make stm32f2 diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 2a17be6a1..ea758d917 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -16,7 +16,7 @@ family_list = { "ch32v307 fomu gd32vf103": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], - "lpc11 lpc13 lpc15": ["arm-gcc"], + "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], "lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], "mcx": ["arm-gcc"], diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 024ab969d..796ff32dc 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -24,15 +24,18 @@ on: - '.github/actions/**' - '.github/workflows/hil_test.yml' concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: + # --------------------------------------- + # Build Non Espressif + # --------------------------------------- build: if: github.repository_owner == 'hathach' runs-on: ubuntu-latest outputs: - BOARD_LIST: ${{ steps.parse_hil_json.outputs.BOARD_LIST }} + BOARDS_LIST: ${{ steps.parse_hil_json.outputs.BOARDS_LIST }} steps: - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -42,38 +45,29 @@ jobs: with: python-version: '3.x' - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '12.3.Rel1' - - name: Parse HIL json id: parse_hil_json run: | sudo apt install -y jq - BOARD_LIST=$(jq -r '.boards[] | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') - echo "BOARD_LIST=$BOARD_LIST" - echo >> $GITHUB_ENV "BOARD_LIST=$BOARD_LIST" - echo >> $GITHUB_OUTPUT "BOARD_LIST=$BOARD_LIST" - - name: Checkout pico-sdk for rp2040 - uses: actions/checkout@v4 + # Non-Espresif boards + BOARDS_LIST=$(jq -r '.boards[] | select(.flasher != "esptool") | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') + echo "BOARDS_LIST=$BOARDS_LIST" + echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV + echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT + + - name: Setup ARM Toolchain + uses: ./.github/actions/setup_toolchain with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk + toolchain: 'arm-gcc' - name: Get Dependencies - run: | - pip install click - sudo apt install -y ninja-build - python3 tools/get_deps.py $BOARD_LIST + uses: ./.github/actions/get_deps + with: + arg: ${{ env.BOARDS_LIST }} - name: Build - run: | - python tools/build.py $BOARD_LIST - env: - PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk + run: python tools/build.py $BOARDS_LIST - name: Upload Artifacts for Hardware Testing uses: actions/upload-artifact@v4 @@ -83,16 +77,71 @@ jobs: cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin + # --------------------------------------- + # Build Espressif + # --------------------------------------- + build-esp: + runs-on: ubuntu-latest + outputs: + BOARDS_LIST: ${{ steps.parse_hil_json.outputs.BOARDS_LIST }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Parse HIL json + id: parse_hil_json + run: | + sudo apt install -y jq + # Espressif boards + BOARDS_LIST=$(jq -r '.boards[] | select(.flasher == "esptool") | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') + echo "BOARDS_LIST=$BOARDS_LIST" + echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV + echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT + + - name: Setup ESP-IDF + if: env.BOARDS_LIST != '' + uses: ./.github/actions/setup_toolchain + with: + toolchain: 'esp-idf' + toolchain_url: 'v5.1.1' + + - name: Get Dependencies + uses: ./.github/actions/get_deps + with: + arg: ${{ env.BOARDS_LIST }} + + - name: Build Espressif + if: env.BOARDS_LIST != '' + run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build.py $BOARDS_LIST + + - name: Upload Artifacts for Hardware Testing + uses: actions/upload-artifact@v4 + with: + name: hil_pi4_esp + path: | + cmake-build/cmake-build-*/*/*/*.bin + cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin + cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin + cmake-build/cmake-build-*/*/*/config.env + cmake-build/cmake-build-*/*/*/flash_args + # --------------------------------------- # Hardware in the loop (HIL) - # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json + # Current self-hosted instance is running on an RPI4. For attached hardware checkout test/hil/pi4.json # --------------------------------------- hil-pi4: if: github.repository_owner == 'hathach' - needs: build - runs-on: [self-hosted, rp2040, nrf52840, hardware-in-the-loop] + needs: + - build + - build-esp + runs-on: [self-hosted, rp2040, nrf52840, esp32s3, hardware-in-the-loop] env: - BOARD_LIST: ${{ needs.build.outputs.BOARD_LIST }} + BOARDS_LIST: "${{ needs.build.outputs.BOARDS_LIST }} ${{ needs.build-esp.outputs.BOARDS_LIST }}" steps: - name: Clean workspace run: | @@ -103,8 +152,7 @@ jobs: # USB bus on rpi4 is not stable, reset it before testing - name: Reset USB bus run: | - lsusb - lsusb -t + # lsusb -t # reset VIA Labs 2.0 hub sudo usbreset 001/002 @@ -119,7 +167,16 @@ jobs: name: hil_pi4 path: cmake-build + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: hil_pi4_esp + path: cmake-build + - name: Test on actual hardware run: | - echo "BOARD_LIST=$BOARD_LIST" - python3 test/hil/hil_test.py $BOARD_LIST pi4.json + echo "BOARDS_LIST=$BOARDS_LIST" + echo "::group::{cmake-build contents}" + tree cmake-build + echo "::endgroup::" + python3 test/hil/hil_test.py $BOARDS_LIST pi4.json diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 6b3151702..d1ffe6ca1 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -7,7 +7,7 @@ on: branches: [ master ] concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -38,7 +38,6 @@ jobs: - name: Build Fuzzer run: | - pip install click export CC=clang export CXX=clang++ fuzz_harness=$(ls -d test/fuzz/device/*/) diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index bb3ff7885..43cdab71a 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -9,6 +9,8 @@ mcu:STM32F0 mcu:KINETIS_KL family:broadcom_64bit family:broadcom_32bit +family:espressif board:curiosity_nano board:frdm_kl25z -family:espressif +# lpc55 has weird error 'ncm_interface' causes a section type conflict with 'ntb_parameters' +family:lpc55 diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 15c176a2a..86697899b 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -12,3 +12,5 @@ board:lpcxpresso11u68 board:stm32f303disco board:stm32l412nucleo board:ek_tm4c123gxl +board:uno_r4 +board:ra4m1_ek diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt index 81d993ffa..1e0e60075 100644 --- a/examples/host/cdc_msc_hid_freertos/only.txt +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -8,5 +8,4 @@ mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MSP432E4 mcu:RX65X -mcu:RAXXX mcu:MAX3421 diff --git a/hw/bsp/lpc17/family.mk b/hw/bsp/lpc17/family.mk index 84ed95648..d719a47b7 100644 --- a/hw/bsp/lpc17/family.mk +++ b/hw/bsp/lpc17/family.mk @@ -22,8 +22,8 @@ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ - src/portable/ohci/ohci.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ + src/portable/ohci/ohci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ $(MCU_DIR)/src/clock_17xx_40xx.c \ diff --git a/hw/bsp/lpc40/family.mk b/hw/bsp/lpc40/family.mk index 79d868f35..ef9fe57b2 100644 --- a/hw/bsp/lpc40/family.mk +++ b/hw/bsp/lpc40/family.mk @@ -20,6 +20,8 @@ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs # All source paths should be relative to the top level. SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ + src/portable/ohci/ohci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ $(MCU_DIR)/src/clock_17xx_40xx.c \ diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 4b237e4cf..64aba011a 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -112,7 +112,7 @@ typedef struct { bool notification_xmit_is_running; // notification is currently transmitted } ncm_interface_t; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; +CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN tu_static ncm_interface_t ncm_interface; /** * This is the NTB parameter structure @@ -120,7 +120,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; * \attention * We are lucky, that byte order is correct */ -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { +CFG_TUD_MEM_SECTION CFG_TUD_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, @@ -285,7 +285,7 @@ static xmit_ntb_t *xmit_get_next_ready_ntb(void) { * This must be called from netd_xfer_cb() so that ep_in is ready */ static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) { - TU_LOG_DRV("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); + TU_LOG_DRV("xmit_insert_required_zlp(%d,%ld)\n", rhport, xferred_bytes); if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { return false; @@ -521,11 +521,11 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { return false; } if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { - TU_LOG_DRV("(EE) ill min len: %d\n", len); + TU_LOG_DRV("(EE) ill min len: %lu\n", len); return false; } if (nth16->wBlockLength > len) { - TU_LOG_DRV("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); + TU_LOG_DRV("(EE) ill block length: %d > %lu\n", nth16->wBlockLength, len); return false; } if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { @@ -533,7 +533,7 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { return false; } if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t))) { - TU_LOG_DRV("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + TU_LOG_DRV("(EE) ill position of first ndp: %d (%lu)\n", nth16->wNdpIndex, len); return false; } @@ -567,11 +567,11 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { TU_LOG_DRV(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); if (ndp16_datagram[ndx].wDatagramIndex > len) { - TU_LOG_DRV("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + TU_LOG_DRV("(EE) ill start of datagram[%d]: %d (%lu)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); return false; } if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { - TU_LOG_DRV("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + TU_LOG_DRV("(EE) ill end of datagram[%d]: %d (%lu)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); return false; } ++ndx; diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index dffb81765..c2699cc6f 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -25,10 +25,10 @@ # ACTION=="add", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", MODE="0666", PROGRAM="/bin/sh -c 'echo $$ID_SERIAL_SHORT | rev | cut -c -8 | rev'", SYMLINK+="ttyUSB_%c.%s{bInterfaceNumber}" # ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", ENV{ID_FS_USAGE}=="filesystem", MODE="0666", PROGRAM="/bin/sh -c 'echo $$ID_SERIAL_SHORT | rev | cut -c -8 | rev'", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media/blkUSB_%c.%s{bInterfaceNumber}" +import argparse import os import sys import time -import click import serial import subprocess import json @@ -318,13 +318,18 @@ def test_hid_composite_freertos(id): # ------------------------------------------------------------- # Main # ------------------------------------------------------------- -@click.command() -@click.argument('config_file') -@click.option('-b', '--board', multiple=True, default=None, help='Boards to test, all if not specified') -def main(config_file, board): +def main(): """ Hardware test on specified boards """ + parser = argparse.ArgumentParser() + parser.add_argument('config_file', help='Configuration JSON file') + parser.add_argument('-b', '--board', action='append', default=[], help='Boards to test, all if not specified') + args = parser.parse_args() + + config_file = args.config_file + boards = args.board + config_file = os.path.join(os.path.dirname(__file__), config_file) with open(config_file) as f: config = json.load(f) @@ -334,10 +339,10 @@ def main(config_file, board): 'cdc_dual_ports', 'cdc_msc', 'dfu', 'dfu_runtime', 'hid_boot_interface', ] - if len(board) == 0: + if len(boards) == 0: config_boards = config['boards'] else: - config_boards = [e for e in config['boards'] if e['name'] in board] + config_boards = [e for e in config['boards'] if e['name'] in boards] for item in config_boards: name = item['name'] diff --git a/test/hil/pi4.json b/test/hil/pi4.json index 04329bb64..bdb8a5fa5 100644 --- a/test/hil/pi4.json +++ b/test/hil/pi4.json @@ -22,6 +22,16 @@ "flasher_product": "ItsyBitsy M4 Express", "flasher_reset_pin": "2", "flasher_args": "--offset 0x4000" + }, + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "tests": [ + "cdc_msc_freertos", "hid_composite_freertos" + ], + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 1500000" } ] } diff --git a/test/hil/pi4_esp32.json b/test/hil/pi4_esp32.json deleted file mode 100644 index c95dd2d4e..000000000 --- a/test/hil/pi4_esp32.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "boards": [ - { - "name": "espressif_s3_devkitm", - "uid": "84F703C084E4", - "tests": [ - "cdc_msc_freertos", "hid_composite_freertos" - ], - "flasher": "esptool", - "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 1500000" - } - ] -} diff --git a/tools/build.py b/tools/build.py index 884cd56f4..967f7c95e 100644 --- a/tools/build.py +++ b/tools/build.py @@ -1,8 +1,8 @@ +import argparse import os import sys import time import subprocess -import click from pathlib import Path from multiprocessing import Pool @@ -125,13 +125,20 @@ def build_family(family, toolchain, build_system): return ret -@click.command() -@click.argument('families', nargs=-1, required=False) -@click.option('-b', '--board', multiple=True, default=None, help='Boards to build') -@click.option('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') -@click.option('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') -def main(families, board, toolchain, build_system): - if len(families) == 0 and len(board) == 0: +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('families', nargs='*', default=[], help='Families to build') + parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build') + parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') + parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') + args = parser.parse_args() + + families = args.families + boards = args.board + toolchain = args.toolchain + build_system = args.build_system + + if len(families) == 0 and len(boards) == 0: print("Please specify families or board to build") return 1 @@ -159,12 +166,23 @@ def main(families, board, toolchain, build_system): total_result[2] += fret[2] # build board (only cmake) - if board is not None: - for b in board: - r = build_board_cmake(b, toolchain) - total_result[0] += r[0] - total_result[1] += r[1] - total_result[2] += r[2] + if boards is not None: + for b in boards: + if build_system == 'cmake': + r = build_board_cmake(b, toolchain) + total_result[0] += r[0] + total_result[1] += r[1] + total_result[2] += r[2] + elif build_system == 'make': + all_examples = get_examples(find_family(b)) + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda e, bb=b, o=f"TOOLCHAIN={toolchain}": [e, bb, o], all_examples))) + r = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + rsum = list(map(sum, list(zip(*r)))) + total_result[0] += rsum[0] + total_result[1] += rsum[1] + total_result[2] += rsum[2] total_time = time.monotonic() - total_time print(build_separator) diff --git a/tools/build_esp32.py b/tools/build_esp32.py deleted file mode 100644 index 951467c23..000000000 --- a/tools/build_esp32.py +++ /dev/null @@ -1,106 +0,0 @@ -import os -import glob -import sys -import subprocess -import time - -import build_utils - -SUCCEEDED = "\033[32msucceeded\033[0m" -FAILED = "\033[31mfailed\033[0m" -SKIPPED = "\033[33mskipped\033[0m" - -success_count = 0 -fail_count = 0 -skip_count = 0 -exit_status = 0 - -total_time = time.monotonic() - -build_format = '| {:30} | {:30} | {:18} | {:7} | {:6} | {:6} |' -build_separator = '-' * 107 - -def filter_with_input(mylist): - if len(sys.argv) > 1: - input_args = list(set(mylist).intersection(sys.argv)) - if len(input_args) > 0: - mylist[:] = input_args - - -# Build all examples if not specified -all_examples = [entry.replace('examples/', '') for entry in glob.glob("examples/*/*_freertos")] -filter_with_input(all_examples) -all_examples.append('device/board_test') -all_examples.sort() - -# Build all boards if not specified -all_boards = [] -for entry in os.scandir("hw/bsp/espressif/boards"): - if entry.is_dir(): - all_boards.append(entry.name) -filter_with_input(all_boards) -all_boards.sort() - -def build_board(example, board): - global success_count, fail_count, skip_count, exit_status - start_time = time.monotonic() - - # Check if board is skipped - build_dir = f"cmake-build/cmake-build-{board}/{example}" - - # Generate and build - r = subprocess.run(f"cmake examples/{example} -B {build_dir} -G \"Ninja\" -DBOARD={board} -DMAX3421_HOST=1", - shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - if r.returncode == 0: - r = subprocess.run(f"cmake --build {build_dir}", shell=True, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - build_duration = time.monotonic() - start_time - flash_size = "-" - sram_size = "-" - - if r.returncode == 0: - success = SUCCEEDED - success_count += 1 - #(flash_size, sram_size) = build_size(example, board) - else: - exit_status = r.returncode - success = FAILED - fail_count += 1 - - title = build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size) - if os.getenv('CI'): - # always print build output if in CI - print(f"::group::{title}") - print(r.stdout.decode("utf-8")) - print(f"::endgroup::") - else: - # print build output if failed - print(title) - if r.returncode != 0: - print(r.stdout.decode("utf-8")) - - -def build_size(example, board): - #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) - elf_file = 'examples/device/{}/_build/{}/*.elf'.format(example, board) - size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - size_list = size_output.split('\n')[1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) - - -print(build_separator) -print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) -print(build_separator) - -for example in all_examples: - for board in all_boards: - build_board(example, board) - -total_time = time.monotonic() - total_time -print(build_separator) -print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) -print(build_separator) - -sys.exit(exit_status) diff --git a/tools/get_deps.py b/tools/get_deps.py index 2359b4bd0..20cbe64c7 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -245,11 +245,10 @@ def main(): args = parser.parse_args() families = args.families - board = args.board + boards = args.board - if len(families) == 0 and len(board) == 0: - print("Please specify family or board to fetch") - return + if len(families) == 0 and len(boards) == 0: + print("Warning: family and board are not specified, only fetching mandatory dependencies.") status = 0 deps = list(deps_mandatory.keys()) @@ -258,8 +257,8 @@ def main(): deps += deps_optional.keys() else: families = list(families) - if board is not None: - for b in board: + if boards is not None: + for b in boards: f = find_family(b) if f is not None: families.append(f) -- cgit v1.3.1 From 969b06d77c8a37510c9bed8dde377ff7bf462a30 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 12:51:50 +0700 Subject: minor update --- src/class/hid/hid.h | 4 ++-- src/class/net/ncm_device.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 2fe922136..c2b5a8a48 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -762,7 +762,7 @@ enum { HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, HID_USAGE_PAGE_MEDICAL = 0x40, HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59, - HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 + HID_USAGE_PAGE_MONITOR = 0x80, // 0x80 - 0x83 HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, HID_USAGE_PAGE_SCALE = 0x8d, @@ -770,7 +770,7 @@ enum { HID_USAGE_PAGE_CAMERA = 0x90, HID_USAGE_PAGE_ARCADE = 0x91, HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page - HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; /// HID Usage Table - Table 6: Generic Desktop Page diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 64aba011a..44a6a0de9 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,6 +1,8 @@ /* * The MIT License (MIT) * + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2024 Hardy Griech * -- cgit v1.3.1 From 2be72a97b8fd4d08ca20a9b8815f2042c4ef7520 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 17:55:36 +0700 Subject: minor update --- hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk | 2 -- hw/bsp/ch32v10x/family.c | 2 +- src/class/net/ncm_device.c | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk index 7d7462312..70e65333c 100644 --- a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk @@ -1,5 +1,3 @@ -MCU_VARIANT = D6 - CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY LDFLAGS += \ diff --git a/hw/bsp/ch32v10x/family.c b/hw/bsp/ch32v10x/family.c index c41b207e0..15f754e11 100644 --- a/hw/bsp/ch32v10x/family.c +++ b/hw/bsp/ch32v10x/family.c @@ -24,7 +24,7 @@ void USBHD_IRQHandler(void) { } __attribute__((interrupt)) __attribute__((used)) -void USBHDWakeUp_IRQHandler(void) { +void USBWakeUp_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 44a6a0de9..90d747185 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,10 +1,10 @@ /* * The MIT License (MIT) * - * Copyright (c) 2020 Jacob Berg Potter - * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2024 Hardy Griech + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal -- cgit v1.3.1 From 8f699023f3ff2434efa4433ddc92a9c01756d1f1 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Fri, 28 Jun 2024 10:55:43 +0200 Subject: audio_device.c: fix strict-overflow warning with gcc >= 12 Fix the following error ~/libs/tinyusb/src/class/audio/audio_device.c:1493:23: error: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Werror=strict-overflow] 1493 | while (p_desc < p_desc_end) | ~~~~~~~^~~~~~~~~~~~ compilation terminated due to -Wfatal-errors. --- src/class/audio/audio_device.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 46db96ea9..65cac2fd5 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1490,7 +1490,8 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin #endif uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { @@ -1740,7 +1741,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN; // p_desc starts at required interface with alternate setting zero - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // Find correct interface if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == alt) @@ -1750,7 +1752,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints; - while (foundEPs < nEps && p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (foundEPs < nEps && (p_desc_end - p_desc > 0)) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { @@ -2394,7 +2397,8 @@ static bool audiod_get_AS_interface_index(uint8_t itf, audiod_function_t * audio p_desc += ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength; uint8_t tmp = 0; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // We assume the number of alternate settings is increasing thus we return the index of alternate setting zero! if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0) @@ -2447,7 +2451,8 @@ static bool audiod_verify_entity_exists(uint8_t itf, uint8_t entityID, uint8_t * uint8_t const *p_desc_end = ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength + p_desc; p_desc = tu_desc_next(p_desc); // Get past CS AC descriptor - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (p_desc[3] == entityID) // Entity IDs are always at offset 3 { @@ -2471,8 +2476,8 @@ static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id) // Get pointer at beginning and end uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = _audiod_fct[i].p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; - - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const *)_audiod_fct[i].p_desc)->bInterfaceNumber == itf) { @@ -2500,7 +2505,8 @@ static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id) uint8_t const *p_desc = tu_desc_next(_audiod_fct[i].p_desc); p_desc += ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT && ((tusb_desc_endpoint_t const * )p_desc)->bEndpointAddress == ep) { @@ -2531,8 +2537,8 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #endif p_desc = tu_desc_next(p_desc); // Exclude standard AS interface descriptor of current alternate interface descriptor - - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // Abort if follow up descriptor is a new standard interface descriptor - indicates the last AS descriptor was already finished if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) break; -- cgit v1.3.1 From 8f9a57636c9ae6b51e272274ea79f01a7a2631c1 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Fri, 28 Jun 2024 19:57:59 +0200 Subject: audio.h: fix error ISO C restricts enumerator values to range of 'int' fix error ~/dsp/libs/tinyusb/src/class/audio/audio.h:643:53: error: ISO C restricts enumerator values to range of 'int' before C23 [-Werror=pedantic] 643 | AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, // TODO | ^~~~~~~~~~ compilation terminated due to -Wfatal-errors. Closes: https://github.com/hathach/tinyusb/issues/2690 --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index d6f3e22e2..49ccbe863 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = (int)(1U << 31U), } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, + AUDIO_CHANNEL_CONFIG_RAW_DATA = (int)(1U << 31U), } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From bd562e418080d4d9e4213d38a123b93f30250c48 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 5 Jul 2024 15:15:00 +0700 Subject: Revert "audio.h: fix error ISO C restricts enumerator values to range of 'int'" --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 49ccbe863..d6f3e22e2 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = (int)(1U << 31U), + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = (int)(1U << 31U), + AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From ca12a579020184c0e3f6d66d8081d5bb927cb4b2 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Jul 2024 15:19:16 +0700 Subject: add u for unsigned --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index d6f3e22e2..2f97c0f23 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000u, } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, + AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000u, } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From 1f590c36287e26b6d189bf41f9b7704e957bf8af Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jul 2024 16:53:21 +0700 Subject: - add tud_cdc_configure_fifo() to replace CFG_TUD_CDC_PERSISTENT_TX_BUFF - new line, and code format --- src/class/cdc/cdc_device.c | 237 ++++++++++++++++++--------------------------- src/class/cdc/cdc_device.h | 195 ++++++++++++++----------------------- 2 files changed, 168 insertions(+), 264 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index f36725eba..681a1b852 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -45,8 +45,7 @@ //--------------------------------------------------------------------+ #define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_notif; uint8_t ep_in; @@ -56,7 +55,7 @@ typedef struct uint8_t line_state; /*------------- From this point, data is not cleared by bus reset -------------*/ - char wanted_char; + char wanted_char; TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // FIFO @@ -72,18 +71,17 @@ typedef struct // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE]; - -}cdcd_interface_t; +} cdcd_interface_t; #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char) //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUD_MEM_SECTION tu_static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc) -{ +static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { uint8_t const rhport = 0; uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); @@ -99,14 +97,11 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) // fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&p_cdc->rx_ff); - if ( available >= sizeof(p_cdc->epout_buf) ) - { + if ( available >= sizeof(p_cdc->epout_buf) ) { return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf)); - }else - { + }else { // Release endpoint since we don't make any transfer usbd_edpt_release(rhport, p_cdc->ep_out); - return false; } } @@ -114,51 +109,49 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -bool tud_cdc_n_connected(uint8_t itf) -{ + +bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg) { + TU_VERIFY(cfg); + _cdcd_fifo_cfg = (*cfg); + return true; +} + +bool tud_cdc_n_connected(uint8_t itf) { // DTR (bit 0) active is considered as connected return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); } -uint8_t tud_cdc_n_get_line_state (uint8_t itf) -{ +uint8_t tud_cdc_n_get_line_state(uint8_t itf) { return _cdcd_itf[itf].line_state; } -void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding) -{ +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding) { (*coding) = _cdcd_itf[itf].line_coding; } -void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted) -{ +void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { _cdcd_itf[itf].wanted_char = wanted; } - //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ -uint32_t tud_cdc_n_available(uint8_t itf) -{ +uint32_t tud_cdc_n_available(uint8_t itf) { return tu_fifo_count(&_cdcd_itf[itf].rx_ff); } -uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) -{ +uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); _prep_out_transaction(p_cdc); return num_read; } -bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) -{ +bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { return tu_fifo_peek(&_cdcd_itf[itf].rx_ff, chr); } -void tud_cdc_n_read_flush (uint8_t itf) -{ +void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); _prep_out_transaction(p_cdc); @@ -167,16 +160,15 @@ void tud_cdc_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ -uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) -{ +uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); // flush if queue more than packet size - if ( tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE - #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size - #endif + if (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE + #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE + || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size + #endif ) { tud_cdc_n_write_flush(itf); } @@ -184,30 +176,27 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) return ret; } -uint32_t tud_cdc_n_write_flush (uint8_t itf) -{ +uint32_t tud_cdc_n_write_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; // Skip if usb is not ready yet - TU_VERIFY( tud_ready(), 0 ); + TU_VERIFY(tud_ready(), 0); // No data to send - if ( !tu_fifo_count(&p_cdc->tx_ff) ) return 0; + if (!tu_fifo_count(&p_cdc->tx_ff)) return 0; uint8_t const rhport = 0; // Claim the endpoint - TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); + TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_in), 0); // Pull data from FIFO uint16_t const count = tu_fifo_read_n(&p_cdc->tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf)); - if ( count ) - { - TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); + if (count) { + TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected usbd_edpt_release(rhport, p_cdc->ep_in); @@ -215,33 +204,30 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf) } } -uint32_t tud_cdc_n_write_available (uint8_t itf) -{ +uint32_t tud_cdc_n_write_available(uint8_t itf) { return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff); } -bool tud_cdc_n_write_clear (uint8_t itf) -{ +bool tud_cdc_n_write_clear(uint8_t itf) { return tu_fifo_clear(&_cdcd_itf[itf].tx_ff); } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void cdcd_init(void) -{ +void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); + tu_memclr(&_cdcd_fifo_cfg, sizeof(_cdcd_fifo_cfg)); - for(uint8_t i=0; iwanted_char = (char) -1; // default line coding is : stop bit = 1, parity = none, data bits = 8 - p_cdc->line_coding.bit_rate = 115200; + p_cdc->line_coding.bit_rate = 115200; p_cdc->line_coding.stop_bits = 0; - p_cdc->line_coding.parity = 0; + p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; // Config RX fifo @@ -285,35 +271,28 @@ bool cdcd_deinit(void) { return true; } -void cdcd_reset(uint8_t rhport) -{ +void cdcd_reset(uint8_t rhport) { (void) rhport; - for(uint8_t i=0; irx_ff); - #if !CFG_TUD_CDC_PERSISTENT_TX_BUFF - tu_fifo_clear(&p_cdc->tx_ff); - #endif + if (!_cdcd_fifo_cfg.rx_persistent) tu_fifo_clear(&p_cdc->rx_ff); + if (!_cdcd_fifo_cfg.tx_persistent) tu_fifo_clear(&p_cdc->tx_ff); tu_fifo_set_overwritable(&p_cdc->tx_ff, true); } } -uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -{ +uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { // Only support ACM subclass TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); // Find available interface - cdcd_interface_t * p_cdc = NULL; - for(uint8_t cdc_id=0; cdc_iditf_num = itf_desc->bInterfaceNumber; uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const * p_desc = tu_desc_next( itf_desc ); + 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 ) - { + 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); + p_desc = tu_desc_next(p_desc); } - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { // notification endpoint - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc; - TU_ASSERT( usbd_edpt_open(rhport, desc_ep), 0 ); + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); } //------------- Data Interface (if any) -------------// - if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) - { + if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && + (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const*) p_desc)->bInterfaceClass)) { // next to endpoint descriptor drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); // Open endpoint pair - TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0 ); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0); - drv_len += 2*sizeof(tusb_desc_endpoint_t); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); } // Prepare for incoming data @@ -368,8 +344,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ +bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { // Handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); @@ -377,42 +352,33 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t cdcd_interface_t* p_cdc = _cdcd_itf; // Identify which interface to use - for ( ; ; itf++, p_cdc++) - { + for (;; itf++, p_cdc++) { if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false; - if ( p_cdc->itf_num == request->wIndex ) break; + if (p_cdc->itf_num == request->wIndex) break; } - switch ( request->bRequest ) - { + switch (request->bRequest) { case CDC_REQUEST_SET_LINE_CODING: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Set Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); + } else if (stage == CONTROL_STAGE_ACK) { + if (tud_cdc_line_coding_cb) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); } - else if ( stage == CONTROL_STAGE_ACK) - { - if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); - } - break; + break; case CDC_REQUEST_GET_LINE_CODING: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Get Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } - break; + break; case CDC_REQUEST_SET_CONTROL_LINE_STATE: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); - } - else if (stage == CONTROL_STAGE_ACK) - { + } else if (stage == CONTROL_STAGE_ACK) { // CDC PSTN v1.2 section 6.3.12 // Bit 0: Indicates if DTE is present or not. // This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready) @@ -429,61 +395,54 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); // Invoke callback - if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts); + if (tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, dtr, rts); } - break; + break; + case CDC_REQUEST_SEND_BREAK: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); - } - else if (stage == CONTROL_STAGE_ACK) - { + } else if (stage == CONTROL_STAGE_ACK) { TU_LOG_DRV(" Send Break\r\n"); - if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue); + if (tud_cdc_send_break_cb) tud_cdc_send_break_cb(itf, request->wValue); } - break; + break; - default: return false; // stall unsupported request + default: + return false; // stall unsupported request } return true; } -bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; uint8_t itf; cdcd_interface_t* p_cdc; // Identify which interface to use - for (itf = 0; itf < CFG_TUD_CDC; itf++) - { + for (itf = 0; itf < CFG_TUD_CDC; itf++) { p_cdc = &_cdcd_itf[itf]; - if ( ( ep_addr == p_cdc->ep_out ) || ( ep_addr == p_cdc->ep_in ) ) break; + if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in)) break; } TU_ASSERT(itf < CFG_TUD_CDC); // Received new data - if ( ep_addr == p_cdc->ep_out ) - { + if (ep_addr == p_cdc->ep_out) { tu_fifo_write_n(&p_cdc->rx_ff, p_cdc->epout_buf, (uint16_t) xferred_bytes); // Check for wanted char and invoke callback if needed - if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) ) - { - for ( uint32_t i = 0; i < xferred_bytes; i++ ) - { - if ( (p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff) ) - { + if (tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1)) { + for (uint32_t i = 0; i < xferred_bytes; i++) { + if ((p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } } // invoke receive callback (if there is still data) - if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf); + if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction _prep_out_transaction(p_cdc); @@ -492,19 +451,15 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Data sent to host, we continue to fetch from tx fifo to send. // Note: This will cause incorrect baudrate set in line coding. // Though maybe the baudrate is not really important !!! - if ( ep_addr == p_cdc->ep_in ) - { + if (ep_addr == p_cdc->ep_in) { // invoke transmit callback to possibly refill tx fifo - if ( tud_cdc_tx_complete_cb ) tud_cdc_tx_complete_cb(itf); + if (tud_cdc_tx_complete_cb) tud_cdc_tx_complete_cb(itf); - if ( 0 == tud_cdc_n_write_flush(itf) ) - { + if (0 == tud_cdc_n_write_flush(itf)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP Packet size and not zero - if ( !tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) - { - if ( usbd_edpt_claim(rhport, p_cdc->ep_in) ) - { + if (!tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { + if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0); } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index db709b3bc..5c2d07c5b 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_CDC_DEVICE_H_ -#define _TUSB_CDC_DEVICE_H_ +#ifndef TUSB_CDC_DEVICE_H_ +#define TUSB_CDC_DEVICE_H_ #include "cdc.h" @@ -41,213 +41,162 @@ #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif -// By default the TX fifo buffer is cleared on connect / bus reset. -// Enable this to persist any data in the fifo instead. -#ifndef CFG_TUD_CDC_PERSISTENT_TX_BUFF - #define CFG_TUD_CDC_PERSISTENT_TX_BUFF (0) -#endif - #ifdef __cplusplus extern "C" { #endif -/** \addtogroup CDC_Serial Serial - * @{ - * \defgroup CDC_Serial_Device Device - * @{ */ +//--------------------------------------------------------------------+ +// Driver Configuration +//--------------------------------------------------------------------+ + +typedef struct TU_ATTR_PACKED { + uint8_t rx_persistent : 1; // keep rx fifo on bus reset or disconnect + uint8_t tx_persistent : 1; // keep tx fifo on bus reset or disconnect +} tud_cdc_configure_fifo_t; + +// Configure CDC FIFOs behavior +bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); //--------------------------------------------------------------------+ -// Application API (Multiple Ports) -// CFG_TUD_CDC > 1 +// Application API (Multiple Ports) i.e CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ // Check if terminal is connected to this port -bool tud_cdc_n_connected (uint8_t itf); +bool tud_cdc_n_connected(uint8_t itf); // Get current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) -uint8_t tud_cdc_n_get_line_state (uint8_t itf); +uint8_t tud_cdc_n_get_line_state(uint8_t itf); // Get current line encoding: bit rate, stop bits parity etc .. -void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding); +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding); // Set special character that will trigger tud_cdc_rx_wanted_cb() callback on receiving -void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted); +void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted); // Get the number of bytes available for reading -uint32_t tud_cdc_n_available (uint8_t itf); +uint32_t tud_cdc_n_available(uint8_t itf); // Read received bytes -uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize); +uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize); // Read a byte, return -1 if there is none -static inline -int32_t tud_cdc_n_read_char (uint8_t itf); +TU_ATTR_ALWAYS_INLINE static inline int32_t tud_cdc_n_read_char(uint8_t itf) { + uint8_t ch; + return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; +} // Clear the received FIFO -void tud_cdc_n_read_flush (uint8_t itf); +void tud_cdc_n_read_flush(uint8_t itf); // Get a byte from FIFO without removing it -bool tud_cdc_n_peek (uint8_t itf, uint8_t* ui8); +bool tud_cdc_n_peek(uint8_t itf, uint8_t* ui8); // Write bytes to TX FIFO, data may remain in the FIFO for a while -uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); +uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize); // Write a byte -static inline -uint32_t tud_cdc_n_write_char (uint8_t itf, char ch); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) { + return tud_cdc_n_write(itf, &ch, 1); +} // Write a null-terminated string -static inline -uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_n_write_str(uint8_t itf, char const* str) { + return tud_cdc_n_write(itf, str, strlen(str)); +} // Force sending data if possible, return number of forced bytes -uint32_t tud_cdc_n_write_flush (uint8_t itf); +uint32_t tud_cdc_n_write_flush(uint8_t itf); // Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation. -uint32_t tud_cdc_n_write_available (uint8_t itf); +uint32_t tud_cdc_n_write_available(uint8_t itf); // Clear the transmit FIFO -bool tud_cdc_n_write_clear (uint8_t itf); +bool tud_cdc_n_write_clear(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ -static inline bool tud_cdc_connected (void); -static inline uint8_t tud_cdc_get_line_state (void); -static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding); -static inline void tud_cdc_set_wanted_char (char wanted); - -static inline uint32_t tud_cdc_available (void); -static inline int32_t tud_cdc_read_char (void); -static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize); -static inline void tud_cdc_read_flush (void); -static inline bool tud_cdc_peek (uint8_t* ui8); - -static inline uint32_t tud_cdc_write_char (char ch); -static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize); -static inline uint32_t tud_cdc_write_str (char const* str); -static inline uint32_t tud_cdc_write_flush (void); -static inline uint32_t tud_cdc_write_available (void); -static inline bool tud_cdc_write_clear (void); - -//--------------------------------------------------------------------+ -// Application Callback API (weak is optional) -//--------------------------------------------------------------------+ - -// Invoked when received new data -TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); - -// Invoked when received `wanted_char` -TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); - -// Invoked when a TX is complete and therefore space becomes available in TX buffer -TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf); - -// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE -TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); - -// Invoked when line coding is change via SET_LINE_CODING -TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); - -// Invoked when received send break -TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); - -//--------------------------------------------------------------------+ -// Inline Functions -//--------------------------------------------------------------------+ -static inline int32_t tud_cdc_n_read_char (uint8_t itf) -{ - uint8_t ch; - return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; -} - -static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) -{ - return tud_cdc_n_write(itf, &ch, 1); -} - -static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str) -{ - return tud_cdc_n_write(itf, str, strlen(str)); -} - -static inline bool tud_cdc_connected (void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_connected(void) { return tud_cdc_n_connected(0); } -static inline uint8_t tud_cdc_get_line_state (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_cdc_get_line_state(void) { return tud_cdc_n_get_line_state(0); } -static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_get_line_coding(cdc_line_coding_t* coding) { tud_cdc_n_get_line_coding(0, coding); } -static inline void tud_cdc_set_wanted_char (char wanted) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_set_wanted_char(char wanted) { tud_cdc_n_set_wanted_char(0, wanted); } -static inline uint32_t tud_cdc_available (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_available(void) { return tud_cdc_n_available(0); } -static inline int32_t tud_cdc_read_char (void) -{ +TU_ATTR_ALWAYS_INLINE static inline int32_t tud_cdc_read_char(void) { return tud_cdc_n_read_char(0); } -static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_read(void* buffer, uint32_t bufsize) { return tud_cdc_n_read(0, buffer, bufsize); } -static inline void tud_cdc_read_flush (void) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_read_flush(void) { tud_cdc_n_read_flush(0); } -static inline bool tud_cdc_peek (uint8_t* ui8) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_peek(uint8_t* ui8) { return tud_cdc_n_peek(0, ui8); } -static inline uint32_t tud_cdc_write_char (char ch) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_char(char ch) { return tud_cdc_n_write_char(0, ch); } -static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write(void const* buffer, uint32_t bufsize) { return tud_cdc_n_write(0, buffer, bufsize); } -static inline uint32_t tud_cdc_write_str (char const* str) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_str(char const* str) { return tud_cdc_n_write_str(0, str); } -static inline uint32_t tud_cdc_write_flush (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_flush(void) { return tud_cdc_n_write_flush(0); } -static inline uint32_t tud_cdc_write_available(void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_available(void) { return tud_cdc_n_write_available(0); } -static inline bool tud_cdc_write_clear(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_write_clear(void) { return tud_cdc_n_write_clear(0); } -/** @} */ -/** @} */ +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received new data +TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); + +// Invoked when received `wanted_char` +TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); + +// Invoked when a TX is complete and therefore space becomes available in TX buffer +TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf); + +// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE +TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); + +// Invoked when line coding is change via SET_LINE_CODING +TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); + +// Invoked when received send break +TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API -- cgit v1.3.1 From 0ecf15bc61b2684e53250437d295d6c43682a724 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 14:35:23 +0700 Subject: follow up to #2253 - rename tud_hid_report_fail_cb() to tud_hid_report_failed_cb() and change its signature - use default implementation for hid callbacks to be compatible with keil compiler - code format --- src/class/cdc/cdc_device.h | 2 +- src/class/hid/hid_device.c | 268 +++++++++++++++++++++++---------------------- src/class/hid/hid_device.h | 106 +++++++----------- 3 files changed, 180 insertions(+), 196 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 5c2d07c5b..34670517a 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -58,7 +58,7 @@ typedef struct TU_ATTR_PACKED { bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); //--------------------------------------------------------------------+ -// Application API (Multiple Ports) i.e CFG_TUD_CDC > 1 +// Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ // Check if terminal is connected to this port diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index ada01582e..7168ab3d5 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -61,28 +61,53 @@ typedef struct { CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; /*------------- Helpers -------------*/ -static inline uint8_t get_index_by_itfnum(uint8_t itf_num) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t get_index_by_itfnum(uint8_t itf_num) { for (uint8_t i = 0; i < CFG_TUD_HID; i++) { - if (itf_num == _hidd_itf[i].itf_num) + if (itf_num == _hidd_itf[i].itf_num) { return i; + } } - return 0xFF; } +//--------------------------------------------------------------------+ +// Weak stubs: invoked if no strong implementation is available +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) { + (void) instance; + (void) protocol; +} + +TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate) { + (void) instance; + (void) idle_rate; + return true; +} + +TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { + (void) instance; + (void) report; + (void) len; +} + +// Invoked when a transfer wasn't successful +TU_ATTR_WEAK void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, uint8_t const* report, uint16_t xferred_bytes) { + (void) instance; + (void) report_type; + (void) report; + (void) xferred_bytes; +} + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -bool tud_hid_n_ready(uint8_t instance) -{ +bool tud_hid_n_ready(uint8_t instance) { uint8_t const rhport = 0; uint8_t const ep_in = _hidd_itf[instance].ep_in; return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) -{ +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) { uint8_t const rhport = 0; hidd_interface_t *p_hid = &_hidd_itf[instance]; @@ -101,14 +126,16 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, u return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); } -uint8_t tud_hid_n_interface_protocol(uint8_t instance) { return _hidd_itf[instance].itf_protocol; } +uint8_t tud_hid_n_interface_protocol(uint8_t instance) { + return _hidd_itf[instance].itf_protocol; +} -uint8_t tud_hid_n_get_protocol(uint8_t instance) { return _hidd_itf[instance].protocol_mode; } +uint8_t tud_hid_n_get_protocol(uint8_t instance) { + return _hidd_itf[instance].protocol_mode; +} -bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) -{ +bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { hid_keyboard_report_t report; - report.modifier = modifier; report.reserved = 0; @@ -121,8 +148,8 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) -{ +bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, + uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { hid_mouse_report_t report = { .buttons = buttons, .x = x, @@ -134,8 +161,8 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) -{ +bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, + uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { hid_abs_mouse_report_t report = { .buttons = buttons, .x = x, @@ -146,8 +173,8 @@ bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t but return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) -{ +bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, + int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { hid_gamepad_report_t report = { .x = x, .y = y, @@ -165,28 +192,25 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int //--------------------------------------------------------------------+ // USBD-CLASS API //--------------------------------------------------------------------+ -void hidd_init(void) -{ +void hidd_init(void) { hidd_reset(0); } -bool hidd_deinit(void) -{ +bool hidd_deinit(void) { return true; } -void hidd_reset(uint8_t rhport) -{ +void hidd_reset(uint8_t rhport) { (void)rhport; tu_memclr(_hidd_itf, sizeof(_hidd_itf)); } -uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ +uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints - uint16_t const drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface @@ -211,8 +235,9 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16 p_desc = tu_desc_next(p_desc); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in), 0); - if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) + if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) { p_hid->itf_protocol = desc_itf->bInterfaceProtocol; + } p_hid->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode p_hid->itf_num = desc_itf->bInterfaceNumber; @@ -234,8 +259,7 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) -{ +bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); uint8_t const hid_itf = get_index_by_itfnum((uint8_t)request->wIndex); @@ -262,90 +286,82 @@ bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { //------------- Class Specific Request -------------// switch (request->bRequest) { - case HID_REQ_CONTROL_GET_REPORT: - if (stage == CONTROL_STAGE_SETUP) { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - - uint8_t *report_buf = p_hid->ctrl_buf; - uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - uint16_t xferlen = 0; - - // If host request a specific Report ID, add ID to as 1 byte of response - if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { - *report_buf++ = report_id; - req_len--; - - xferlen++; + case HID_REQ_CONTROL_GET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t* report_buf = p_hid->ctrl_buf; + uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + uint16_t xferlen = 0; + + // If host request a specific Report ID, add ID to as 1 byte of response + if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { + *report_buf++ = report_id; + req_len--; + xferlen++; + } + + xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); + TU_ASSERT(xferlen > 0); + + tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); } - - xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, req_len); - TU_ASSERT(xferlen > 0); - - tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); - } - break; - - case HID_REQ_CONTROL_SET_REPORT: - if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); - tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); - } else if (stage == CONTROL_STAGE_ACK) { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - - uint8_t const *report_buf = p_hid->ctrl_buf; - uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - // If host request a specific Report ID, extract report ID in buffer before invoking callback - if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { - report_buf++; - report_len--; + break; + + case HID_REQ_CONTROL_SET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); + } else if (stage == CONTROL_STAGE_ACK) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t const* report_buf = p_hid->ctrl_buf; + uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + + // If host request a specific Report ID, extract report ID in buffer before invoking callback + if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { + report_buf++; + report_len--; + } + + tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); } + break; - tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, report_len); - } - break; - - case HID_REQ_CONTROL_SET_IDLE: - if (stage == CONTROL_STAGE_SETUP) { - p_hid->idle_rate = tu_u16_high(request->wValue); - if (tud_hid_set_idle_cb) { - // stall request if callback return false - TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); + case HID_REQ_CONTROL_SET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + p_hid->idle_rate = tu_u16_high(request->wValue); + TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); // stall if false + tud_control_status(rhport, request); } + break; - tud_control_status(rhport, request); - } - break; - - case HID_REQ_CONTROL_GET_IDLE: - if (stage == CONTROL_STAGE_SETUP) { - // TODO idle rate of report - tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); - } - break; + case HID_REQ_CONTROL_GET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + // TODO idle rate of report + tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); + } + break; - case HID_REQ_CONTROL_GET_PROTOCOL: - if (stage == CONTROL_STAGE_SETUP) { - tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); - } - break; + case HID_REQ_CONTROL_GET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); + } + break; - case HID_REQ_CONTROL_SET_PROTOCOL: - if (stage == CONTROL_STAGE_SETUP) { - tud_control_status(rhport, request); - } else if (stage == CONTROL_STAGE_ACK) { - p_hid->protocol_mode = (uint8_t)request->wValue; - if (tud_hid_set_protocol_cb) { + case HID_REQ_CONTROL_SET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_status(rhport, request); + } else if (stage == CONTROL_STAGE_ACK) { + p_hid->protocol_mode = (uint8_t) request->wValue; tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); } - } - break; + break; - default: - return false; // stall unsupported request + default: + return false; // stall unsupported request } } else { return false; // stall unsupported request @@ -354,45 +370,35 @@ bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t return true; } -bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void)result; - +bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { uint8_t instance = 0; hidd_interface_t *p_hid = _hidd_itf; // Identify which interface to use for (instance = 0; instance < CFG_TUD_HID; instance++) { p_hid = &_hidd_itf[instance]; - if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) + if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) { break; + } } TU_ASSERT(instance < CFG_TUD_HID); - // Check if there was a problem - if (XFER_RESULT_SUCCESS != result) { // Inform application about the issue - if (tud_hid_report_fail_cb) { - tud_hid_report_fail_cb(instance, ep_addr, (uint16_t)xferred_bytes); + if (ep_addr == p_hid->ep_in) { + // Input report + if (XFER_RESULT_SUCCESS == result) { + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); + } else { + tud_hid_report_failed_cb(instance, HID_REPORT_TYPE_INPUT, p_hid->epin_buf, (uint16_t) xferred_bytes); } - - // Allow a new transfer to be received if issue happened on an OUT endpoint - if (ep_addr == p_hid->ep_out) { - // Prepare the OUT endpoint to be able to receive a new transfer - TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); + } else { + // Output report + if (XFER_RESULT_SUCCESS == result) { + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); + } else { + tud_hid_report_failed_cb(instance, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t) xferred_bytes); } - return true; - } - - // Sent report successfully - if (ep_addr == p_hid->ep_in) { - if (tud_hid_report_complete_cb) { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t)xferred_bytes); - } - } - // Received report successfully - else if (ep_addr == p_hid->ep_out) { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); + // prepare for new transfer TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index fcbf161c4..89c28e061 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_HID_DEVICE_H_ -#define _TUSB_HID_DEVICE_H_ +#ifndef TUSB_HID_DEVICE_H_ +#define TUSB_HID_DEVICE_H_ #include "hid.h" @@ -48,8 +48,7 @@ #endif //--------------------------------------------------------------------+ -// Application API (Multiple Instances) -// CFG_TUD_HID > 1 +// Application API (Multiple Instances) i.e. CFG_TUD_HID > 1 //--------------------------------------------------------------------+ // Check if the interface is ready to use @@ -76,12 +75,6 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons // use template layout report as defined by hid_abs_mouse_report_t bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal); - -static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) -{ - return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); -} - // Gamepad: convenient helper to send gamepad report if application // use template layout report TUD_HID_REPORT_DESC_GAMEPAD bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); @@ -89,16 +82,40 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ -static inline bool tud_hid_ready(void); -static inline uint8_t tud_hid_interface_protocol(void); -static inline uint8_t tud_hid_get_protocol(void); -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len); -static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); -static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); -static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_ready(void) { + return tud_hid_n_ready(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_hid_interface_protocol(void) { + return tud_hid_n_interface_protocol(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_hid_get_protocol(void) { + return tud_hid_n_get_protocol(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) { + return tud_hid_n_report(0, report_id, report, len); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { + return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { + return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { + return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { + return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons); +} //--------------------------------------------------------------------+ -// Callbacks (Weak is optional) +// Application Callbacks //--------------------------------------------------------------------+ // Invoked when received GET HID REPORT DESCRIPTOR request @@ -111,63 +128,25 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance); uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen); // Invoked when received SET_REPORT control request or -// received data on OUT endpoint ( Report ID = 0, Type = 0 ) +// received data on OUT endpoint (Report ID = 0, Type = OUTPUT) void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize); // Invoked when received SET_PROTOCOL request // protocol is either HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) -TU_ATTR_WEAK void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol); +void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol); // Invoked when received SET_IDLE request. return false will stall the request -// - Idle Rate = 0 : only send report if there is changes, i.e skip duplication +// - Idle Rate = 0 : only send report if there is changes, i.e. skip duplication // - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms). -TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); +bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); // Invoked when a transfer wasn't successful -TU_ATTR_WEAK void tud_hid_report_fail_cb(uint8_t instance, uint8_t ep_addr, uint16_t len); - -//--------------------------------------------------------------------+ -// Inline Functions -//--------------------------------------------------------------------+ -static inline bool tud_hid_ready(void) -{ - return tud_hid_n_ready(0); -} - -static inline uint8_t tud_hid_interface_protocol(void) -{ - return tud_hid_n_interface_protocol(0); -} - -static inline uint8_t tud_hid_get_protocol(void) -{ - return tud_hid_n_get_protocol(0); -} - -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) -{ - return tud_hid_n_report(0, report_id, report, len); -} - -static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) -{ - return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); -} - -static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) -{ - return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); -} - -static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) -{ - return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons); -} +void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, uint8_t const* report, uint16_t xferred_bytes); /* --------------------------------------------------------------------+ * HID Report Descriptor Template @@ -645,9 +624,8 @@ uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); - #ifdef __cplusplus } #endif -#endif /* _TUSB_HID_DEVICE_H_ */ +#endif -- cgit v1.3.1 From 0004faca83f3fa3128fa69b6f97ac711f30d2d20 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 19:29:21 +0700 Subject: minor update hid device --- src/class/hid/hid_device.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 7168ab3d5..00f6fc474 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -46,16 +46,16 @@ typedef struct { uint8_t itf_protocol; // Boot mouse or keyboard uint16_t report_desc_len; - CFG_TUSB_MEM_ALIGN uint8_t protocol_mode; // Boot (0) or Report protocol (1) - CFG_TUSB_MEM_ALIGN uint8_t idle_rate; // up to application to handle idle rate - - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; + uint8_t protocol_mode; // Boot (0) or Report protocol (1) + uint8_t idle_rate; // up to application to handle idle rate // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration tusb_hid_descriptor_hid_t const *hid_descriptor; + + uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; } hidd_interface_t; CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; -- cgit v1.3.1 From 31a979a6cccc2d4dc0a86474643710ae3b7f34fe Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 17 Jul 2024 21:08:55 -0500 Subject: fix some clang compiler warnings --- examples/host/cdc_msc_hid/src/hid_app.c | 1 + examples/host/hid_controller/src/hid_app.c | 1 + src/class/hid/hid_host.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index f0d42a08f..6bb3a2072 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -235,6 +235,7 @@ static void process_mouse_report(hid_mouse_report_t const * report) static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { (void) dev_addr; + (void) len; uint8_t const rpt_count = hid_info[instance].report_count; tuh_hid_report_info_t* rpt_info_arr = hid_info[instance].report_info; diff --git a/examples/host/hid_controller/src/hid_app.c b/examples/host/hid_controller/src/hid_app.c index bff830ca2..6ffe0b6d4 100644 --- a/examples/host/hid_controller/src/hid_app.c +++ b/examples/host/hid_controller/src/hid_app.c @@ -253,6 +253,7 @@ bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2) void process_sony_ds4(uint8_t const* report, uint16_t len) { + (void)len; const char* dpad_str[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "none" }; // previous report used to compare for changes diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 115a8a4df..7639a8fc6 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -657,7 +657,9 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t const data8 = desc_report[0]; TU_LOG(3, "tag = %d, type = %d, size = %d, data = ", tag, type, size); - for (uint32_t i = 0; i < size; i++) TU_LOG(3, "%02X ", desc_report[i]); + for (uint32_t i = 0; i < size; i++) { + TU_LOG(3, "%02X ", desc_report[i]); + } TU_LOG(3, "\r\n"); switch (type) { -- cgit v1.3.1 From ffe1d0664b6abe942c14ca540833e1e86a797184 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 18 Jul 2024 20:02:57 +0200 Subject: UAC2: Fix memclr on driver reset. --- src/class/audio/audio_device.c | 94 ++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 44 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 65cac2fd5..ed380424f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -304,19 +304,6 @@ typedef struct uint16_t desc_length; // Length of audio function descriptor - // Buffer for control requests - uint8_t * ctrl_buf; - uint8_t ctrl_buf_sz; - - // Current active alternate settings - uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP! - - // EP Transfer buffers and FIFOs -#if CFG_TUD_AUDIO_ENABLE_EP_OUT -#if !CFG_TUD_AUDIO_ENABLE_DECODING - tu_fifo_t ep_out_ff; -#endif - #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP struct { CFG_TUSB_MEM_ALIGN uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). @@ -346,17 +333,6 @@ typedef struct } feedback; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT - -#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING - tu_fifo_t ep_in_ff; -#endif - - // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; -#endif - // Decoding parameters - parameters are set when alternate AS interface is set by host // Coding is currently only supported for EP. Software coding corresponding to AS interfaces without EPs are not supported currently. #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING @@ -365,8 +341,7 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING audio_data_format_type_I_t format_type_I_rx; - uint8_t n_bytes_per_sampe_rx; - uint8_t n_channels_per_ff_rx; + uint8_t n_bytes_per_sample_rx; uint8_t n_ff_used_rx; #endif #endif @@ -382,26 +357,57 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL) audio_format_type_t format_type_tx; uint8_t n_channels_tx; - uint8_t n_bytes_per_sampe_tx; + uint8_t n_bytes_per_sample_tx; #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING audio_data_format_type_I_t format_type_I_tx; - uint8_t n_channels_per_ff_tx; uint8_t n_ff_used_tx; #endif #endif + // Buffer for control requests + uint8_t * ctrl_buf; + uint8_t ctrl_buf_sz; + + // Current active alternate settings + uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP! + + // EP Transfer buffers and FIFOs +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +#if !CFG_TUD_AUDIO_ENABLE_DECODING + tu_fifo_t ep_out_ff; +#endif + + +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + tu_fifo_t ep_in_ff; +#endif + + // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; +#endif + + // Support FIFOs for software encoding and decoding #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING tu_fifo_t * rx_supp_ff; uint8_t n_rx_supp_ff; uint16_t rx_supp_ff_sz_max; +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + uint8_t n_channels_per_ff_rx; +#endif #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING tu_fifo_t * tx_supp_ff; uint8_t n_tx_supp_ff; uint16_t tx_supp_ff_sz_max; +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + uint8_t n_channels_per_ff_tx; +#endif #endif // Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR the support FIFOs are used @@ -707,16 +713,16 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u if (info.len_lin != 0) { info.len_lin = tu_min16(nBytesPerFFToRead, info.len_lin); - src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; + src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sample_rx]; dst_end = info.ptr_lin + info.len_lin; - src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_lin, dst_end, src, n_ff_used); + src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sample_rx, info.ptr_lin, dst_end, src, n_ff_used); // Handle wrapped part of FIFO info.len_wrap = tu_min16(nBytesPerFFToRead - info.len_lin, info.len_wrap); if (info.len_wrap != 0) { dst_end = info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_wrap, dst_end, src, n_ff_used); + audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sample_rx, info.ptr_wrap, dst_end, src, n_ff_used); } tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); } @@ -1024,7 +1030,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi // Limit to maximum sample number - THIS IS A POSSIBLE ERROR SOURCE IF TOO MANY SAMPLE WOULD NEED TO BE SENT BUT CAN NOT! nBytesPerFFToSend = tu_min16(nBytesPerFFToSend, audio->ep_in_sz / n_ff_used); // Round to full number of samples (flooring) - uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx; + uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx; nBytesPerFFToSend = (nBytesPerFFToSend / nSlotSize) * nSlotSize; #endif @@ -1036,7 +1042,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) { - dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx]; + dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sample_tx]; tu_fifo_get_read_info(&audio->tx_supp_ff[cnt_ff], &info); @@ -1044,7 +1050,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi { info.len_lin = tu_min16(nBytesPerFFToSend, info.len_lin); // Limit up to desired length src_end = (uint8_t *)info.ptr_lin + info.len_lin; - dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_lin, src_end, dst, n_ff_used); + dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sample_tx, info.ptr_lin, src_end, dst, n_ff_used); // Limit up to desired length info.len_wrap = tu_min16(nBytesPerFFToSend - info.len_lin, info.len_wrap); @@ -1053,7 +1059,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi if (info.len_wrap != 0) { src_end = (uint8_t *)info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_wrap, src_end, dst, n_ff_used); + audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sample_tx, info.ptr_wrap, src_end, dst, n_ff_used); } tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); @@ -1782,8 +1788,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap #if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING - const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)) - * (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)); + const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx)) + * (audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx)); for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) { tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); @@ -1813,7 +1819,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING - const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sampe_rx) * audio->n_bytes_per_sampe_rx; + const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sample_rx) * audio->n_bytes_per_sample_rx; for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) { tu_fifo_config(&audio->rx_supp_ff[cnt], audio->rx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); @@ -2587,14 +2593,14 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_EP_IN if (as_itf == audio->ep_in_as_intf_num) { - audio->n_bytes_per_sampe_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; + audio->n_bytes_per_sample_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING if (as_itf == audio->ep_out_as_intf_num) { - audio->n_bytes_per_sampe_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; + audio->n_bytes_per_sample_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; } #endif } @@ -2613,7 +2619,7 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t* audio) { TU_VERIFY(audio->format_type_tx == AUDIO_FORMAT_TYPE_I); TU_VERIFY(audio->n_channels_tx); - TU_VERIFY(audio->n_bytes_per_sampe_tx); + TU_VERIFY(audio->n_bytes_per_sample_tx); TU_VERIFY(audio->interval_tx); TU_VERIFY(audio->sample_rate_tx); @@ -2622,9 +2628,9 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t* audio) const uint16_t sample_normimal = (uint16_t)(audio->sample_rate_tx * interval / ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); const uint16_t sample_reminder = (uint16_t)(audio->sample_rate_tx * interval % ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); - const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); - const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); - const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); + const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx); + const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sample_tx); + const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx); // Endpoint size must larger than packet size TU_ASSERT(packet_sz_tx_max <= audio->ep_in_sz); -- cgit v1.3.1 From 60b3d14d1979b4a281f999e3a1861b44477f57b1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 14:05:58 +0200 Subject: Check tud ready check for OUT xfer. --- src/class/cdc/cdc_device.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 681a1b852..792aedf26 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,8 +81,13 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { +static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) +{ uint8_t const rhport = 0; + + // Skip if usb is not ready yet + TU_VERIFY(tud_ready() || itf_open); + uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); // Prepare for incoming data but only allow what we can store in the ring buffer. @@ -143,7 +148,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); return num_read; } @@ -154,7 +159,7 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); } //--------------------------------------------------------------------+ @@ -336,7 +341,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 } // Prepare for incoming data - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, true); return drv_len; } @@ -445,7 +450,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); } // Data sent to host, we continue to fetch from tx fifo to send. -- cgit v1.3.1 From be18af823591389a12e246f65784646f93443882 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 17:10:53 +0700 Subject: revert changes to usbds configuration_reset() (deal with it in separated PR) --- src/class/cdc/cdc_device.c | 3 +-- src/device/usbd.c | 12 ++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 792aedf26..570c825ab 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,8 +81,7 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) -{ +static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) { uint8_t const rhport = 0; // Skip if usb is not ready yet diff --git a/src/device/usbd.c b/src/device/usbd.c index 2735e35fd..4105a71a4 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -495,19 +495,15 @@ bool tud_deinit(uint8_t rhport) { } static void configuration_reset(uint8_t rhport) { - // Save setup_count for restore - uint8_t setup_count = _usbd_dev.setup_count; - // Clear mounted status first to ensure tud_ready() return false before driver clean up. - tu_varclr(&_usbd_dev); - memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping - memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping - _usbd_dev.setup_count = setup_count; - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); TU_ASSERT(driver,); driver->reset(rhport); } + + tu_varclr(&_usbd_dev); + memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping + memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping } static void usbd_reset(uint8_t rhport) { -- cgit v1.3.1 From 6fb6602a097b2d2e026f150d6fde387803606f88 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 18:08:04 +0700 Subject: - add tud_cdc_n_ready() though not used - usbd now change _usbd_dev.cfg_num before calling driver's open() --- src/class/cdc/cdc_device.c | 16 ++++++++++------ src/class/cdc/cdc_device.h | 8 ++++++++ src/common/tusb_verify.h | 10 +++++----- src/device/usbd.c | 10 ++++++++-- 4 files changed, 31 insertions(+), 13 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 570c825ab..ebc408f5a 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,11 +81,11 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) { +static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { uint8_t const rhport = 0; // Skip if usb is not ready yet - TU_VERIFY(tud_ready() || itf_open); + TU_VERIFY(tud_ready() && p_cdc->ep_out); uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); @@ -120,6 +120,10 @@ bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg) { return true; } +bool tud_cdc_n_ready(uint8_t itf) { + return tud_ready() && _cdcd_itf[itf].ep_in != 0 && _cdcd_itf[itf].ep_out != 0; +} + bool tud_cdc_n_connected(uint8_t itf) { // DTR (bit 0) active is considered as connected return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); @@ -147,7 +151,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); return num_read; } @@ -158,7 +162,7 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); } //--------------------------------------------------------------------+ @@ -340,7 +344,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 } // Prepare for incoming data - _prep_out_transaction(p_cdc, true); + _prep_out_transaction(p_cdc); return drv_len; } @@ -449,7 +453,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); } // Data sent to host, we continue to fetch from tx fifo to send. diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 34670517a..3ad7c8baf 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -61,6 +61,9 @@ bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); // Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ +// Check if interface is ready +bool tud_cdc_n_ready(uint8_t itf); + // Check if terminal is connected to this port bool tud_cdc_n_connected(uint8_t itf); @@ -116,6 +119,11 @@ bool tud_cdc_n_write_clear(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_ready(void) { + return tud_cdc_n_ready(0); +} + TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_connected(void) { return tud_cdc_n_connected(0); } diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index dde0550d3..4344575b7 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -56,8 +56,8 @@ * #define TU_VERIFY(cond) if(cond) return false; * #define TU_VERIFY(cond,ret) if(cond) return ret; * - * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} - * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} + * #define TU_ASSERT(cond) if(cond) {TU_MESS_FAILED(); TU_BREAKPOINT(), return false;} + * #define TU_ASSERT(cond,ret) if(cond) {TU_MESS_FAILED(); TU_BREAKPOINT(), return ret;} *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -70,9 +70,9 @@ #if CFG_TUSB_DEBUG #include - #define _MESS_FAILED() tu_printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) + #define TU_MESS_FAILED() tu_printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) #else - #define _MESS_FAILED() do {} while (0) + #define TU_MESS_FAILED() do {} while (0) #endif // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55 @@ -119,7 +119,7 @@ *------------------------------------------------------------------*/ #define TU_ASSERT_DEFINE(_cond, _ret) \ do { \ - if ( !(_cond) ) { _MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ + if ( !(_cond) ) { TU_MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ } while(0) #define TU_ASSERT_1ARGS(_cond) TU_ASSERT_DEFINE(_cond, false) diff --git a/src/device/usbd.c b/src/device/usbd.c index 4105a71a4..4e723c8b9 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -747,17 +747,23 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.speed = speed; // restore speed } + _usbd_dev.cfg_num = cfg_num; + // Handle the new configuration and execute the corresponding callback if ( cfg_num ) { // switch to new configuration if not zero - TU_ASSERT( process_set_config(rhport, cfg_num) ); + if (!process_set_config(rhport, cfg_num)) { + TU_MESS_FAILED(); + TU_BREAKPOINT(); + _usbd_dev.cfg_num = 0; + return false; + } if ( tud_mount_cb ) tud_mount_cb(); } else { if ( tud_umount_cb ) tud_umount_cb(); } } - _usbd_dev.cfg_num = cfg_num; tud_control_status(rhport, p_request); } break; -- cgit v1.3.1