From 5cfe2930012d1dbec85e0923e0eda2d9aec867e6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 13 Oct 2021 17:31:57 +0700 Subject: update changelog and increase version for 0.12.0 --- src/tusb_option.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tusb_option.h b/src/tusb_option.h index b2ebfdf66..e49fc0119 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -28,7 +28,7 @@ #define _TUSB_OPTION_H_ #define TUSB_VERSION_MAJOR 0 -#define TUSB_VERSION_MINOR 11 +#define TUSB_VERSION_MINOR 12 #define TUSB_VERSION_REVISION 0 #define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) -- cgit v1.3.1 From 2a795d5fd0e1a18ae5fa2eeb9d47e8769efe663c Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Thu, 14 Oct 2021 23:15:35 +0900 Subject: Fix GUID of video compression formats --- src/class/video/video.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/class/video/video.h b/src/class/video/video.h index b24eb0bcc..fa2976611 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -382,10 +382,10 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c #define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN 6 /* 2.2 compression formats */ -#define TUD_VIDEO_GUID_YUY2 0x59,0x55,0x59,0x32,0x00,0x00,0x10,0x00,0x00,0x80,0x71,0x9B,0x38,0x00,0xAA,0x00 -#define TUD_VIDEO_GUID_NV12 0x4E,0x56,0x31,0x32,0x00,0x00,0x10,0x00,0x00,0x80,0x71,0x9B,0x38,0x00,0xAA,0x00 -#define TUD_VIDEO_GUID_M420 0x4D,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x00,0x80,0x71,0x9B,0x38,0x00,0xAA,0x00 -#define TUD_VIDEO_GUID_I420 0x49,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x00,0x80,0x71,0x9B,0x38,0x00,0xAA,0x00 +#define TUD_VIDEO_GUID_YUY2 0x59,0x55,0x59,0x32,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 +#define TUD_VIDEO_GUID_NV12 0x4E,0x56,0x31,0x32,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 +#define TUD_VIDEO_GUID_M420 0x4D,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 +#define TUD_VIDEO_GUID_I420 0x49,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 #define TUD_VIDEO_DESC_IAD(_firstitfs, _nitfs, _stridx) \ TUD_VIDEO_DESC_IAD_LEN, TUSB_DESC_INTERFACE_ASSOCIATION, \ -- cgit v1.3.1 From 7667299b483feb4afb783d794ea94a149cc5a5b4 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 14 Oct 2021 12:13:39 -0500 Subject: Remove compiler warning --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index f9b4d9b17..28c54c52f 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -242,7 +242,7 @@ static void _hw_endpoint_xfer_sync (struct hw_endpoint *ep) // Update hw endpoint struct with info from hardware // after a buff status interrupt - uint32_t buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); + uint32_t __unused buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); TU_LOG(3, " Sync BufCtrl: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); // always sync buffer 0 -- cgit v1.3.1 From 06d955538988c3859bf6c5428a38bd8311069ed9 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 14 Oct 2021 15:20:32 -0500 Subject: More warning cleanup - physically suppress warnings in TinyUSB headers using pragmas so they don't break -Werror compilation of external files that include them - fix compiler warnings in rp2040 port - add cmake method to rp2040 port to allow an external project to suppress warnings in TinyUSB itself --- hw/bsp/rp2040/family.cmake | 25 ++++++++++++++++++++++++- src/device/dcd.h | 7 +++++++ src/osal/osal.h | 7 +++++++ src/portable/raspberrypi/rp2040/dcd_rp2040.c | 22 +++++++++++----------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 8 ++++---- 5 files changed, 53 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 06b5e9bd6..1aa180ef8 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -77,7 +77,6 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/class/video/video_device.c ) - # Base config for host mode; wrapped by SDK's tinyusb_host add_library(tinyusb_host_base INTERFACE) target_sources(tinyusb_host_base INTERFACE @@ -153,4 +152,28 @@ if (NOT TARGET _rp2040_family_inclusion_marker) enable_language(C CXX ASM) pico_sdk_init() endfunction() + + # This method must be called from the project scope to suppress known warnings in TinyUSB source files + function(suppress_tinyusb_warnings) + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/tusb.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual") + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/device/usbd.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual -Wno-null-dereference") + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/device/usbd_control.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") + endfunction() endif() diff --git a/src/device/dcd.h b/src/device/dcd.h index d43a0dd9a..c042cc708 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -106,7 +106,14 @@ typedef struct TU_ATTR_ALIGNED(4) void dcd_init (uint8_t rhport); // Interrupt Handler +#if __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif void dcd_int_handler(uint8_t rhport); +#if __GNUC__ +#pragma GCC diagnostic pop +#endif // Enable device interrupt void dcd_int_enable (uint8_t rhport); diff --git a/src/osal/osal.h b/src/osal/osal.h index 28bdf479c..c8131d19d 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -67,6 +67,10 @@ typedef void (*osal_task_func_t)( void * ); // OSAL Porting API //--------------------------------------------------------------------+ +#if __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif //------------- Semaphore -------------// static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); @@ -84,6 +88,9 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef); static inline bool osal_queue_receive(osal_queue_t qhdl, void* data); static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); static inline bool osal_queue_empty(osal_queue_t qhdl); +#if __GNUC__ +#pragma GCC diagnostic pop +#endif #if 0 // TODO remove subtask related macros later // Sub Task diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index a710bd557..4bcc9ca54 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -70,7 +70,7 @@ static struct hw_endpoint *hw_endpoint_get_by_addr(uint8_t ep_addr) static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) { // size must be multiple of 64 - uint16_t size = tu_div_ceil(ep->wMaxPacketSize, 64) * 64u; + uint size = tu_div_ceil(ep->wMaxPacketSize, 64) * 64u; // double buffered Bulk endpoint if ( transfer_type == TUSB_XFER_BULK ) @@ -88,7 +88,7 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) pico_info(" Alloced %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); // Fill in endpoint control register with buffer offset - uint32_t const reg = EP_CTRL_ENABLE_BITS | (transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; + uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; *ep->endpoint_control = reg; } @@ -177,7 +177,7 @@ static void hw_handle_buff_status(void) uint32_t remaining_buffers = usb_hw->buf_status; pico_trace("buf_status = 0x%08x\n", remaining_buffers); uint bit = 1u; - for (uint i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) + for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) { if (remaining_buffers & bit) { @@ -365,19 +365,19 @@ void dcd_init (uint8_t rhport) dcd_connect(rhport); } -void dcd_int_enable(uint8_t rhport) +void dcd_int_enable(__unused uint8_t rhport) { assert(rhport == 0); irq_set_enabled(USBCTRL_IRQ, true); } -void dcd_int_disable(uint8_t rhport) +void dcd_int_disable(__unused uint8_t rhport) { assert(rhport == 0); irq_set_enabled(USBCTRL_IRQ, false); } -void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +void dcd_set_address (__unused uint8_t rhport, __unused uint8_t dev_addr) { assert(rhport == 0); @@ -386,7 +386,7 @@ void dcd_set_address (uint8_t rhport, uint8_t dev_addr) hw_endpoint_xfer(0x80, NULL, 0); } -void dcd_remote_wakeup(uint8_t rhport) +void dcd_remote_wakeup(__unused uint8_t rhport) { pico_info("dcd_remote_wakeup %d\n", rhport); assert(rhport == 0); @@ -394,14 +394,14 @@ void dcd_remote_wakeup(uint8_t rhport) } // disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) +void dcd_disconnect(__unused uint8_t rhport) { (void) rhport; usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } // connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) +void dcd_connect(__unused uint8_t rhport) { (void) rhport; usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; @@ -423,7 +423,7 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re } } -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +bool dcd_edpt_open (__unused uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { assert(rhport == 0); hw_endpoint_init(desc_edpt->bEndpointAddress, desc_edpt->wMaxPacketSize.size, desc_edpt->bmAttributes.xfer); @@ -438,7 +438,7 @@ void dcd_edpt_close_all (uint8_t rhport) reset_non_control_endpoints(); } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +bool dcd_edpt_xfer(__unused uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { assert(rhport == 0); hw_endpoint_xfer(ep_addr, buffer, total_bytes); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 28c54c52f..c9e2f6b26 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -38,7 +38,7 @@ const char *ep_dir_string[] = { "in", }; -static inline void _hw_endpoint_lock_update(struct hw_endpoint *ep, int delta) { +static inline void _hw_endpoint_lock_update(__unused struct hw_endpoint * ep, __unused int delta) { // todo add critsec as necessary to prevent issues between worker and IRQ... // note that this is perhaps as simple as disabling IRQs because it would make // sense to have worker and IRQ on same core, however I think using critsec is about equivalent. @@ -107,7 +107,7 @@ void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_m static uint32_t prepare_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) { uint16_t const buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize); - ep->remaining_len -= buflen; + ep->remaining_len = (uint16_t)(ep->remaining_len - buflen); uint32_t buf_ctrl = buflen | USB_BUF_CTRL_AVAIL; @@ -214,7 +214,7 @@ static uint16_t sync_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) // sent some data can increase the length we have sent assert(!(buf_ctrl & USB_BUF_CTRL_FULL)); - ep->xferred_len += xferred_bytes; + ep->xferred_len = (uint16_t)(ep->xferred_len + xferred_bytes); }else { // If we have received some data, so can increase the length @@ -222,7 +222,7 @@ static uint16_t sync_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) assert(buf_ctrl & USB_BUF_CTRL_FULL); memcpy(ep->user_buf, ep->hw_data_buf + buf_id*64, xferred_bytes); - ep->xferred_len += xferred_bytes; + ep->xferred_len = (uint16_t)(ep->xferred_len + xferred_bytes); ep->user_buf += xferred_bytes; } -- cgit v1.3.1 From 49aa0b72a8301f21281fa6498af47ac26bcb1bea Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 15 Oct 2021 11:34:26 +0200 Subject: dcd_da146xx: Fix EPIN stall notification handling Normal TX handler for IN non-0 endpoints is called during outgoing transfer or just after it was finished. It may need to fill TX fifo with same data if TX_DONE is present but ACK_STAT is not. It may need to fill more data when called during transfer. But it may also be called when STALL was sent. In this case TX_DONE is set ACK_STAT is not, just like for packets that were sent but no ACK was received. Code was trying to send something again. There was nothing to send so empty ZLP was scheduled for stalled endpoint. This ZLP was later send to host where valid response was required. This change checks if notification was for STALL endpoint and does not try to fill TX FIFO in that case. --- src/portable/dialog/da146xx/dcd_da146xx.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index a36165343..c4b46ac08 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -632,6 +632,13 @@ static void handle_epx_tx_ev(xfer_ctl_t *xfer) return; } } + else if (regs->epc_in & USB_USB_EPC1_REG_USB_STALL_Msk) + { + // TX_DONE also indicates that STALL packet was just sent, there is + // no point to put anything into transmit FIFO. It could result in + // empty packet being scheduled. + return; + } } if (txs & USB_USB_TXS1_REG_USB_TX_URUN_Msk) { -- cgit v1.3.1 From bf4b133084585d302691e53faf868c0c37b9eaf0 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 15 Oct 2021 11:57:52 +0200 Subject: dcd_da146xx: Drop unexpected data USB3CV tool verifies MSC device by sending too short or too long packets. In case of too long packets (msc_device requested 31 bytes but incoming data had 32 bytes) extra byte(s) were left in FIFO resulting in some data mismatch later on. Now if more data is received in packet that expected extra bytes are just dropped. --- src/portable/dialog/da146xx/dcd_da146xx.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index c4b46ac08..f15203ee9 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -368,8 +368,8 @@ static void start_rx_packet(xfer_ctl_t *xfer) else { // Other endpoint is using DMA in that direction, fall back to interrupts. - // For endpoint size greater then FIFO size enable FIFO level warning interrupt - // when FIFO has less then 17 bytes free. + // For endpoint size greater than FIFO size enable FIFO level warning interrupt + // when FIFO has less than 17 bytes free. regs->rxc |= USB_USB_RXC1_REG_USB_RFWL_Msk; USB->USB_FWMSK_REG |= 1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos); } @@ -420,7 +420,7 @@ static void start_tx_packet(xfer_ctl_t *xfer) regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk; } -static void read_rx_fifo(xfer_ctl_t *xfer, uint16_t bytes_in_fifo) +static uint16_t read_rx_fifo(xfer_ctl_t *xfer, uint16_t bytes_in_fifo) { EPx_REGS *regs = XFER_REGS(xfer); uint16_t remaining = xfer->total_len - xfer->transferred - xfer->last_packet_size; @@ -433,6 +433,8 @@ static void read_rx_fifo(xfer_ctl_t *xfer, uint16_t bytes_in_fifo) for (int i = 0; i < receive_this_time; ++i) buf[i] = regs->rxd; xfer->last_packet_size += receive_this_time; + + return bytes_in_fifo - receive_this_time; } static void handle_ep0_rx(void) @@ -562,7 +564,7 @@ static void handle_epx_rx_ev(uint8_t ep) // FIFO maybe empty if DMA read it before or it's final iteration and function already read all that was to read. if (fifo_bytes > 0) { - read_rx_fifo(xfer, fifo_bytes); + fifo_bytes = read_rx_fifo(xfer, fifo_bytes); } if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_LAST)) { @@ -577,6 +579,13 @@ static void handle_epx_rx_ev(uint8_t ep) xfer->transferred += xfer->last_packet_size; if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size || xfer->iso) { + if (fifo_bytes) + { + // There are extra bytes in the FIFO just flush them + regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; + fifo_bytes = 0; + } + dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, XFER_RESULT_SUCCESS, true); } else -- cgit v1.3.1 From 7325dd633536d086491ef057a544760886190cc7 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sat, 16 Oct 2021 12:06:13 +0900 Subject: Change input terminal type to camera --- examples/device/video_capture/src/usb_descriptors.h | 9 +++++---- src/class/video/video.h | 8 ++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index 340b3f799..eeaef6bd2 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -48,7 +48,7 @@ enum { /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ - + TUD_VIDEO_DESC_INPUT_TERM_LEN\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ @@ -79,9 +79,11 @@ enum { TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_INPUT_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ UVC_CLOCK_FREQUENCY, 1), \ - TUD_VIDEO_DESC_INPUT_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, VIDEO_ETT_COMPOSITE_CONNECTOR, 0, 0), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS( 1, 0, 0, 0), \ @@ -108,5 +110,4 @@ enum { /* EP */ \ TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) - #endif diff --git a/src/class/video/video.h b/src/class/video/video.h index fa2976611..844746546 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -373,6 +373,7 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c #define TUD_VIDEO_DESC_CS_VC_LEN 12 #define TUD_VIDEO_DESC_INPUT_TERM_LEN 8 #define TUD_VIDEO_DESC_OUTPUT_TERM_LEN 9 +#define TUD_VIDEO_DESC_CAMERA_TERM_LEN 18 #define TUD_VIDEO_DESC_STD_VS_LEN 9 #define TUD_VIDEO_DESC_CS_VS_IN_LEN 13 #define TUD_VIDEO_DESC_CS_VS_OUT_LEN 9 @@ -412,6 +413,13 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c TUD_VIDEO_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, \ _tid, U16_TO_U8S_LE(_tt), _at, _srcid, _stridx +/* 3.7.2.3 */ +#define TUD_VIDEO_DESC_CAMERA_TERM(_tid, _at, _stridx, _focal_min, _focal_max, _focal, _ctls) \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_INPUT_TERMINAL, \ + _tid, U16_TO_U8S_LE(VIDEO_ITT_CAMERA), _at, _stridx, \ + U16_TO_U8S_LE(_focal_min), U16_TO_U8S_LE(_focal_max), U16_TO_U8S_LE(_focal), 3, \ + TU_U32_BYTE0(_ctls), TU_U32_BYTE1(_ctls), TU_U32_BYTE2(_ctls) + /* 3.9.1 */ #define TUD_VIDEO_DESC_STD_VS(_itfnum, _alt, _epn, _stridx) \ TUD_VIDEO_DESC_STD_VS_LEN, TUSB_DESC_INTERFACE, _itfnum, _alt, \ -- cgit v1.3.1 From 4fd0ee4eef149237aa58b24e843649b16d5ca1dc Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sat, 16 Oct 2021 15:52:46 +0900 Subject: Implement GET_DEF and GET_LEN handling on Probe/Commit entities of streaming interface --- src/class/video/video_device.c | 86 +++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 91d3b2b72..cd6459a18 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -354,21 +354,25 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm return true; } -/** Set the minimum or the maximum values to variables which need to negotiate with the host +/** Set the minimum, maximum or default values to variables which need to negotiate with the host * - * @param[in] set_max If true, the maximum values is set, otherwise the minimum value is set. + * @param[in] request GET_MAX, GET_MIN or GET_DEF * @param[in,out] param Target */ -static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *stm, bool set_max, +static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *stm, uint_fast8_t request, video_probe_and_commit_control_t *param) { uint_fast8_t const fmtnum = param->bFormatIndex; if (!fmtnum) { - if (set_max) { - tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); - param->bFormatIndex = vs->stm.bNumFormats; - } else { - param->bFormatIndex = 1; + switch (request) { + case VIDEO_REQUEST_GET_MAX: + param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; + break; + case VIDEO_REQUEST_GET_MIN: + case VIDEO_REQUEST_GET_DEF: + param->bFormatIndex = 1; + break; + default: return false; } /* Set the parameters determined by the format */ param->wKeyFrameRate = 1; @@ -391,7 +395,18 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); void const *end = _end_of_streaming_descriptor(vs); tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); - frmnum = set_max ? fmt->bNumFrameDescriptors: 1; + switch (request) { + case VIDEO_REQUEST_GET_MAX: + frmnum = fmt->bNumFrameDescriptors; + break; + case VIDEO_REQUEST_GET_MIN: + frmnum = 1; + break; + case VIDEO_REQUEST_GET_DEF: + frmnum = fmt->bDefaultFrameIndex; + break; + default: return false; + } param->bFrameIndex = frmnum; /* Set the parameters determined by the frame */ tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); @@ -406,11 +421,20 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); uint_fast32_t interval; - uint_fast8_t num_intervals = frm->bFrameIntervalType; - if (!num_intervals) { - interval = set_max ? frm->dwFrameInterval[1]: frm->dwFrameInterval[0]; - } else { - interval = set_max ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[0]; + switch (request) { + case VIDEO_REQUEST_GET_MAX: + { + uint_fast8_t num_intervals = frm->bFrameIntervalType; + interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; + } + break; + case VIDEO_REQUEST_GET_MIN: + interval = frm->dwFrameInterval[0]; + break; + case VIDEO_REQUEST_GET_DEF: + interval = frm->dwDefaultFrameInterval; + break; + default: return false; } param->dwFrameInterval = interval; uint_fast32_t interval_ms = interval / 10000; @@ -784,7 +808,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, video_probe_and_commit_control_t tmp; tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; - TU_VERIFY(_negotiate_streaming_parameters(self, false, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); + TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_MIN, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; @@ -795,14 +819,31 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); video_probe_and_commit_control_t tmp; tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; - TU_VERIFY(_negotiate_streaming_parameters(self, true, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); + TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_MAX, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_RES: return VIDEO_ERROR_UNKNOWN; - case VIDEO_REQUEST_GET_DEF: return VIDEO_ERROR_UNKNOWN; - case VIDEO_REQUEST_GET_LEN: return VIDEO_ERROR_UNKNOWN; + case VIDEO_REQUEST_GET_DEF: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); + video_probe_and_commit_control_t tmp; + tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; + TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_DEF, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); + TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_UNKNOWN; + + case VIDEO_REQUEST_GET_LEN: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); + uint16_t len = sizeof(video_probe_and_commit_control_t); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: if (stage == CONTROL_STAGE_SETUP) @@ -838,6 +879,15 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, } return VIDEO_ERROR_NONE; + case VIDEO_REQUEST_GET_LEN: + if (stage == CONTROL_STAGE_SETUP) + { + TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); + uint16_t len = sizeof(video_probe_and_commit_control_t); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); + } + return VIDEO_ERROR_NONE; + case VIDEO_REQUEST_GET_INFO: if (stage == CONTROL_STAGE_SETUP) { -- cgit v1.3.1 From b3b6b4f785de6916ce352c308108242227ce8a47 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Tue, 19 Oct 2021 21:49:00 +0900 Subject: Update _negotiate_streaming_parameters() to handle some requests --- src/class/video/video_device.c | 74 +++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index cd6459a18..3cd25628b 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -354,9 +354,9 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm return true; } -/** Set the minimum, maximum or default values to variables which need to negotiate with the host +/** Set the minimum, maximum, default values or resolutions to variables which need to negotiate with the host * - * @param[in] request GET_MAX, GET_MIN or GET_DEF + * @param[in] request GET_MAX, GET_MIN, GET_RES or GET_DEF * @param[in,out] param Target */ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *stm, uint_fast8_t request, @@ -420,27 +420,56 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - uint_fast32_t interval; + uint_fast32_t interval, interval_ms; switch (request) { case VIDEO_REQUEST_GET_MAX: { + uint_fast32_t min_interval, max_interval; uint_fast8_t num_intervals = frm->bFrameIntervalType; - interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; + max_interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; + min_interval = frm->dwFrameInterval[0]; + interval = max_interval; + interval_ms = min_interval / 10000; } break; case VIDEO_REQUEST_GET_MIN: - interval = frm->dwFrameInterval[0]; + { + uint_fast32_t min_interval, max_interval; + uint_fast8_t num_intervals = frm->bFrameIntervalType; + max_interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; + min_interval = frm->dwFrameInterval[0]; + interval = min_interval; + interval_ms = max_interval / 10000; + } break; case VIDEO_REQUEST_GET_DEF: interval = frm->dwDefaultFrameInterval; + interval_ms = interval / 10000; + break; + case VIDEO_REQUEST_GET_RES: + { + uint_fast8_t num_intervals = frm->bFrameIntervalType; + if (num_intervals) { + interval = 0; + } else { + interval = frm->dwFrameInterval[2]; + interval_ms = interval / 10000; + } + } break; default: return false; } param->dwFrameInterval = interval; - uint_fast32_t interval_ms = interval / 10000; - TU_ASSERT(interval_ms); - uint_fast32_t frame_size = param->dwMaxVideoFrameSize; - param->dwMaxPayloadTransferSize = (frame_size + interval_ms - 1) / interval_ms + 2; + if (!interval) { + param->dwMaxPayloadTransferSize = 0; + } else { + uint_fast32_t frame_size = param->dwMaxVideoFrameSize; + if (!interval_ms) { + param->dwMaxPayloadTransferSize = frame_size + 2; + } else { + param->dwMaxPayloadTransferSize = (frame_size + interval_ms - 1) / interval_ms + 2; + } + } return true; } return true; @@ -802,39 +831,18 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_MIN: - if (stage == CONTROL_STAGE_SETUP) - { - TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); - - video_probe_and_commit_control_t tmp; - tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; - TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_MIN, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); - TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); - } - return VIDEO_ERROR_NONE; - case VIDEO_REQUEST_GET_MAX: - if (stage == CONTROL_STAGE_SETUP) - { - TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); - video_probe_and_commit_control_t tmp; - tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; - TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_MAX, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); - } - return VIDEO_ERROR_NONE; - - case VIDEO_REQUEST_GET_RES: return VIDEO_ERROR_UNKNOWN; + case VIDEO_REQUEST_GET_RES: case VIDEO_REQUEST_GET_DEF: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); video_probe_and_commit_control_t tmp; tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; - TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_DEF, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); + TU_VERIFY(_negotiate_streaming_parameters(self, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } - return VIDEO_ERROR_UNKNOWN; + return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_LEN: if (stage == CONTROL_STAGE_SETUP) -- cgit v1.3.1