From fccbcfc88977ebdfb1448f6787cb052cfa949788 Mon Sep 17 00:00:00 2001 From: Greg Davill Date: Mon, 21 Mar 2022 10:01:11 +1030 Subject: Add WCH CH32V307 port Add WCH mcu submodule Add CH32V307V-R1-1v0 bsp --- src/common/tusb_mcu.h | 4 + src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h | 345 ++++++++++++++++++++++ src/portable/wch/ch32v307/usb_dc_usbhs.c | 388 +++++++++++++++++++++++++ src/tusb_option.h | 3 + 4 files changed, 740 insertions(+) create mode 100644 src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h create mode 100644 src/portable/wch/ch32v307/usb_dc_usbhs.c (limited to 'src') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 8eb4ad475..84d629eac 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -266,6 +266,10 @@ #elif TU_CHECK_MCU(OPT_MCU_F1C100S) #define TUP_DCD_ENDPOINT_MAX 4 +//------------- WCH -------------// +#elif TU_CHECK_MCU(OPT_MCU_CH32VF307) + #define TUP_DCD_ENDPOINT_MAX 8 + #endif //--------------------------------------------------------------------+ diff --git a/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h b/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h new file mode 100644 index 000000000..1b7c0e791 --- /dev/null +++ b/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h @@ -0,0 +1,345 @@ +#ifndef _USB_CH32_USBHS_REG_H +#define _USB_CH32_USBHS_REG_H + +#include + +/******************* GLOBAL ******************/ + +// USB CONTROL +#define USBHS_CONTROL_OFFSET 0x00 +#define USBHS_DMA_EN (1 << 0) +#define USBHS_ALL_CLR (1 << 1) +#define USBHS_FORCE_RST (1 << 2) +#define USBHS_INT_BUSY_EN (1 << 3) +#define USBHS_DEV_PU_EN (1 << 4) +#define USBHS_SPEED_MASK (3 << 5) +#define USBHS_FULL_SPEED (0 << 5) +#define USBHS_HIGH_SPEED (1 << 5) +#define USBHS_LOW_SPEED (2 << 5) +#define USBHS_HOST_MODE (1 << 7) + +// USB_INT_EN +#define USBHS_INT_EN_OFFSET 0x02 +#define USBHS_BUS_RST_EN (1 << 0) +#define USBHS_DETECT_EN (1 << 0) +#define USBHS_TRANSFER_EN (1 << 1) +#define USBHS_SUSPEND_EN (1 << 2) +#define USBHS_SOF_ACT_EN (1 << 3) +#define USBHS_FIFO_OV_EN (1 << 4) +#define USBHS_SETUP_ACT_EN (1 << 5) +#define USBHS_ISO_ACT_EN (1 << 6) +#define USBHS_DEV_NAK_EN (1 << 7) + +// USB DEV AD +#define USBHS_DEV_AD_OFFSET 0x03 +// USB FRAME_NO +#define USBHS_FRAME_NO_OFFSET 0x04 +// USB SUSPEND +#define USBHS_SUSPEND_OFFSET 0x06 +#define USBHS_DEV_REMOTE_WAKEUP (1 << 2) +#define USBHS_LINESTATE_MASK (2 << 4) /* Read Only */ + +// RESERVED0 + +// USB SPEED TYPE +#define USBHS_SPEED_TYPE_OFFSET 0x08 +#define USBSPEED_MASK (0x03) + +// USB_MIS_ST +#define USBHS_MIS_ST_OFFSET 0x09 +#define USBHS_SPLIT_CAN (1 << 0) +#define USBHS_ATTACH (1 << 1) +#define USBHS_SUSPEND (1 << 2) +#define USBHS_BUS_RESET (1 << 3) +#define USBHS_R_FIFO_RDY (1 << 4) +#define USBHS_SIE_FREE (1 << 5) +#define USBHS_SOF_ACT (1 << 6) +#define USBHS_SOF_PRES (1 << 7) + +// INT_FLAG +#define USBHS_INT_FLAG_OFFSET 0x0A +#define USBHS_BUS_RST_FLAG (1 << 0) +#define USBHS_DETECT_FLAG (1 << 0) +#define USBHS_TRANSFER_FLAG (1 << 1) +#define USBHS_SUSPEND_FLAG (1 << 2) +#define USBHS_HST_SOF_FLAG (1 << 3) +#define USBHS_FIFO_OV_FLAG (1 << 4) +#define USBHS_SETUP_FLAG (1 << 5) +#define USBHS_ISO_ACT_FLAG (1 << 6) + +// INT_ST +#define USBHS_INT_ST_OFFSET 0x0B +#define USBHS_DEV_UIS_IS_NAK (1 << 7) +#define USBHS_DEV_UIS_TOG_OK (1 << 6) +#define MASK_UIS_TOKEN (3 << 4) +#define MASK_UIS_ENDP (0x0F) +#define MASK_UIS_H_RES (0x0F) + +#define USBHS_TOGGLE_OK (0x40) +#define USBHS_HOST_RES (0x0f) + +//USB_RX_LEN +#define USBHS_RX_LEN_OFFSET 0x0C +/******************* DEVICE ******************/ + +//UEP_CONFIG +#define USBHS_UEP_CONFIG_OFFSET 0x10 +#define USBHS_EP0_T_EN (1 << 0) +#define USBHS_EP0_R_EN (1 << 16) + +#define USBHS_EP1_T_EN (1 << 1) +#define USBHS_EP1_R_EN (1 << 17) + +#define USBHS_EP2_T_EN (1 << 2) +#define USBHS_EP2_R_EN (1 << 18) + +#define USBHS_EP3_T_EN (1 << 3) +#define USBHS_EP3_R_EN (1 << 19) + +#define USBHS_EP4_T_EN (1 << 4) +#define USBHS_EP4_R_EN (1 << 20) + +#define USBHS_EP5_T_EN (1 << 5) +#define USBHS_EP5_R_EN (1 << 21) + +#define USBHS_EP6_T_EN (1 << 6) +#define USBHS_EP6_R_EN (1 << 22) + +#define USBHS_EP7_T_EN (1 << 7) +#define USBHS_EP7_R_EN (1 << 23) + +#define USBHS_EP8_T_EN (1 << 8) +#define USBHS_EP8_R_EN (1 << 24) + +#define USBHS_EP9_T_EN (1 << 9) +#define USBHS_EP9_R_EN (1 << 25) + +#define USBHS_EP10_T_EN (1 << 10) +#define USBHS_EP10_R_EN (1 << 26) + +#define USBHS_EP11_T_EN (1 << 11) +#define USBHS_EP11_R_EN (1 << 27) + +#define USBHS_EP12_T_EN (1 << 12) +#define USBHS_EP12_R_EN (1 << 28) + +#define USBHS_EP13_T_EN (1 << 13) +#define USBHS_EP13_R_EN (1 << 29) + +#define USBHS_EP14_T_EN (1 << 14) +#define USBHS_EP14_R_EN (1 << 30) + +#define USBHS_EP15_T_EN (1 << 15) +#define USBHS_EP15_R_EN (1 << 31) + +//UEP_TYPE +#define USBHS_UEP_TYPE_OFFSET 0x14 +#define USBHS_EP0_T_TYP (1 << 0) +#define USBHS_EP0_R_TYP (1 << 16) + +#define USBHS_EP1_T_TYP (1 << 1) +#define USBHS_EP1_R_TYP (1 << 17) + +#define USBHS_EP2_T_TYP (1 << 2) +#define USBHS_EP2_R_TYP (1 << 18) + +#define USBHS_EP3_T_TYP (1 << 3) +#define USBHS_EP3_R_TYP (1 << 19) + +#define USBHS_EP4_T_TYP (1 << 4) +#define USBHS_EP4_R_TYP (1 << 20) + +#define USBHS_EP5_T_TYP (1 << 5) +#define USBHS_EP5_R_TYP (1 << 21) + +#define USBHS_EP6_T_TYP (1 << 6) +#define USBHS_EP6_R_TYP (1 << 22) + +#define USBHS_EP7_T_TYP (1 << 7) +#define USBHS_EP7_R_TYP (1 << 23) + +#define USBHS_EP8_T_TYP (1 << 8) +#define USBHS_EP8_R_TYP (1 << 24) + +#define USBHS_EP9_T_TYP (1 << 8) +#define USBHS_EP9_R_TYP (1 << 25) + +#define USBHS_EP10_T_TYP (1 << 10) +#define USBHS_EP10_R_TYP (1 << 26) + +#define USBHS_EP11_T_TYP (1 << 11) +#define USBHS_EP11_R_TYP (1 << 27) + +#define USBHS_EP12_T_TYP (1 << 12) +#define USBHS_EP12_R_TYP (1 << 28) + +#define USBHS_EP13_T_TYP (1 << 13) +#define USBHS_EP13_R_TYP (1 << 29) + +#define USBHS_EP14_T_TYP (1 << 14) +#define USBHS_EP14_R_TYP (1 << 30) + +#define USBHS_EP15_T_TYP (1 << 15) +#define USBHS_EP15_R_TYP (1 << 31) + +/* BUF_MOD UEP1~15 */ +#define USBHS_BUF_MOD_OFFSET 0x18 +#define USBHS_EP0_BUF_MOD (1 << 0) +#define USBHS_EP0_ISO_BUF_MOD (1 << 16) + +#define USBHS_EP1_BUF_MOD (1 << 1) +#define USBHS_EP1_ISO_BUF_MOD (1 << 17) + +#define USBHS_EP2_BUF_MOD (1 << 2) +#define USBHS_EP2_ISO_BUF_MOD (1 << 18) + +#define USBHS_EP3_BUF_MOD (1 << 3) +#define USBHS_EP3_ISO_BUF_MOD (1 << 19) + +#define USBHS_EP4_BUF_MOD (1 << 4) +#define USBHS_EP4_ISO_BUF_MOD (1 << 20) + +#define USBHS_EP5_BUF_MOD (1 << 5) +#define USBHS_EP5_ISO_BUF_MOD (1 << 21) + +#define USBHS_EP6_BUF_MOD (1 << 6) +#define USBHS_EP6_ISO_BUF_MOD (1 << 22) + +#define USBHS_EP7_BUF_MOD (1 << 7) +#define USBHS_EP7_ISO_BUF_MOD (1 << 23) + +#define USBHS_EP8_BUF_MOD (1 << 8) +#define USBHS_EP8_ISO_BUF_MOD (1 << 24) + +#define USBHS_EP9_BUF_MOD (1 << 9) +#define USBHS_EP9_ISO_BUF_MOD (1 << 25) + +#define USBHS_EP10_BUF_MOD (1 << 10) +#define USBHS_EP10_ISO_BUF_MOD (1 << 26) + +#define USBHS_EP11_BUF_MOD (1 << 11) +#define USBHS_EP11_ISO_BUF_MOD (1 << 27) + +#define USBHS_EP12_BUF_MOD (1 << 12) +#define USBHS_EP12_ISO_BUF_MOD (1 << 28) + +#define USBHS_EP13_BUF_MOD (1 << 13) +#define USBHS_EP13_ISO_BUF_MOD (1 << 29) + +#define USBHS_EP14_BUF_MOD (1 << 14) +#define USBHS_EP14_ISO_BUF_MOD (1 << 30) + +#define USBHS_EP15_BUF_MOD (1 << 15) +#define USBHS_EP15_ISO_BUF_MOD (1 << 31) +//USBHS_EPn_T_EN USBHS_EPn_R_EN USBHS_EPn_BUF_MOD 锟斤拷锟斤拷锟斤拷锟斤拷UEPn_DMA为锟斤拷始锟斤拷址锟缴碉拷锟斤拷锟斤拷锟斤拷锟� +// 0 0 x 锟剿点被锟斤拷锟矫o拷未锟矫碉拷UEPn_*_DMA锟斤拷锟斤拷锟斤拷锟斤拷 +// 1 0 0 锟斤拷锟秸o拷OUT锟斤拷锟斤拷锟斤拷锟斤拷锟阶碉拷址为UEPn_RX_DMA +// 1 0 1 bUEPn_RX_TOG[0]=0,使锟矫伙拷锟斤拷锟斤拷UEPn_RX_DMA锟斤拷bUEPn_RX_TOG[0]=1,使锟矫伙拷锟斤拷锟斤拷UEPn_TX_DMA +// 0 1 0 锟斤拷锟斤拷(IN)锟斤拷锟斤拷锟斤拷锟阶碉拷址为UEPn_TX_DMA锟斤拷 +// 0 1 1 bUEPn_TX_TOG[0]=0,使锟矫伙拷锟斤拷锟斤拷UEPn_TX_DMA锟斤拷bUEPn_TX_TOG[0]=1,使锟矫伙拷锟斤拷锟斤拷UEPn_RX_DMA + +/* USB0_DMA */ +#define USBHS_UEP0_DMA_OFFSET(n) (0x1C) // endpoint 0 DMA buffer address + +/* USBX_RX_DMA */ +#define USBHS_UEPx_RX_DMA_OFFSET(n) (0x1C + 4 * (n)) // endpoint x DMA buffer address + +#define USBHS_UEPx_TX_DMA_OFFSET(n) (0x58 + 4 * (n)) // endpoint x DMA buffer address + +#define USBHS_UEPx_MAX_LEN_OFFSET(n) (0x98 + 4 * (n)) // endpoint x DMA buffer address + +#define USBHS_UEPx_T_LEN_OFFSET(n) (0xD8 + 4 * (n)) // endpoint x DMA buffer address +#define USBHS_UEPx_TX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 2) // endpoint x DMA buffer address +#define USBHS_UEPx_RX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 3) // endpoint x DMA buffer address + +// UEPn_T_LEN +#define USBHS_EP_T_LEN_MASK (0x7FF) + +//UEPn_TX_CTRL +#define USBHS_EP_T_RES_MASK (3 << 0) +#define USBHS_EP_T_RES_ACK (0 << 0) +#define USBHS_EP_T_RES_NYET (1 << 0) +#define USBHS_EP_T_RES_NAK (2 << 0) +#define USBHS_EP_T_RES_STALL (3 << 0) + +#define USBHS_EP_T_TOG_MASK (3 << 3) +#define USBHS_EP_T_TOG_0 (0 << 3) +#define USBHS_EP_T_TOG_1 (1 << 3) +#define USBHS_EP_T_TOG_2 (2 << 3) +#define USBHS_EP_T_TOG_M (3 << 3) + +#define USBHS_EP_T_AUTOTOG (1 << 5) + +//UEPn_RX_CTRL +#define USBHS_EP_R_RES_MASK (3 << 0) +#define USBHS_EP_R_RES_ACK (0 << 0) +#define USBHS_EP_R_RES_NYET (1 << 0) +#define USBHS_EP_R_RES_NAK (2 << 0) +#define USBHS_EP_R_RES_STALL (3 << 0) + +#define USBHS_EP_R_TOG_MASK (3 << 3) +#define USBHS_EP_R_TOG_0 (0 << 3) +#define USBHS_EP_R_TOG_1 (1 << 3) +#define USBHS_EP_R_TOG_2 (2 << 3) +#define USBHS_EP_R_TOG_M (3 << 3) + +#define USBHS_EP_R_AUTOTOG (1 << 5) + +#define USBHS_TOG_MATCH (1 << 6) + +/******************* HOST ******************/ +// USB HOST_CTRL +#define USBHS_SEND_BUS_RESET (1 << 0) +#define USBHS_SEND_BUS_SUSPEND (1 << 1) +#define USBHS_SEND_BUS_RESUME (1 << 2) +#define USBHS_REMOTE_WAKE (1 << 3) +#define USBHS_PHY_SUSPENDM (1 << 4) +#define USBHS_UH_SOFT_FREE (1 << 6) +#define USBHS_SEND_SOF_EN (1 << 7) + +//UH_CONFIG +#define USBHS_HOST_TX_EN (1 << 3) +#define USBHS_HOST_RX_EN (1 << 18) + +// HOST_EP_TYPE +#define USBHS_ENDP_TX_ISO (1 << 3) +#define USBHS_ENDP_RX_ISO (1 << (16 + 2)) + +// R32_UH_EP_PID +#define USBHS_HOST_MASK_TOKEN (0x0f) +#define USBHS_HOST_MASK_ENDP (0x0f << 4) + +//R8_UH_RX_CTRL +#define USBHS_EP_R_RES_MASK (3 << 0) +#define USBHS_EP_R_RES_ACK (0 << 0) +#define USBHS_EP_R_RES_NYET (1 << 0) +#define USBHS_EP_R_RES_NAK (2 << 0) +#define USBHS_EP_R_RES_STALL (3 << 0) + +#define USBHS_UH_R_RES_NO (1 << 2) +#define USBHS_UH_R_TOG_1 (1 << 3) +#define USBHS_UH_R_TOG_2 (2 << 3) +#define USBHS_UH_R_TOG_3 (3 << 3) +#define USBHS_UH_R_TOG_AUTO (1 << 5) +#define USBHS_UH_R_DATA_NO (1 << 6) +//R8_UH_TX_CTRL +#define USBHS_UH_T_RES_MASK (3 << 0) +#define USBHS_UH_T_RES_ACK (0 << 0) +#define USBHS_UH_T_RES_NYET (1 << 0) +#define USBHS_UH_T_RES_NAK (2 << 0) +#define USBHS_UH_T_RES_STALL (3 << 0) + +#define USBHS_UH_T_RES_NO (1 << 2) +#define USBHS_UH_T_TOG_1 (1 << 3) +#define USBHS_UH_T_TOG_2 (2 << 3) +#define USBHS_UH_T_TOG_3 (3 << 3) +#define USBHS_UH_T_TOG_AUTO (1 << 5) +#define USBHS_UH_T_DATA_NO (1 << 6) + +// 00: OUT, 01:SOF, 10:IN, 11:SETUP +#define PID_OUT 0 +#define PID_SOF 1 +#define PID_IN 2 +#define PID_SETUP 3 + +#endif diff --git a/src/portable/wch/ch32v307/usb_dc_usbhs.c b/src/portable/wch/ch32v307/usb_dc_usbhs.c new file mode 100644 index 000000000..32645dc5f --- /dev/null +++ b/src/portable/wch/ch32v307/usb_dc_usbhs.c @@ -0,0 +1,388 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Greg Davill + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32VF307) +#include "device/dcd.h" + +#include "usb_ch32_usbhs_reg.h" +#include "core_riscv.h" + +// Max number of bi-directional endpoints including EP0 +#define EP_MAX 16 + +typedef struct { + uint8_t *buffer; + // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API + uint16_t total_len; + uint16_t queued_len; + uint16_t max_size; + bool short_packet; +} xfer_ctl_t; + +#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] +static xfer_ctl_t xfer_status[EP_MAX][2]; + +#define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep)*2) +#define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep)*4) +#define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep)*4) +#define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep)*2) + +#define EP_TX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_TX_DMA) + (ep - 1)) +#define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) + +/* Endpoint Buffer */ +__attribute__((aligned(4))) uint8_t setup[8]; // ep0(64) +__attribute__((aligned(4))) uint8_t EP0_DatabufHD[64]; // ep0(64) + +volatile uint8_t mps_over_flag = 0; +volatile uint8_t USBHS_Dev_Endp0_Tog = 0x01; + +void dcd_init(uint8_t rhport) { + (void)rhport; + + memset(&xfer_status, 0, sizeof(xfer_status)); + + // usb_dc_low_level_init(); + + USBHSD->HOST_CTRL = 0x00; + USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; + + USBHSD->CONTROL = 0; +#if 1 + USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; +#else + USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; +#endif + + USBHSD->INT_EN = 0; + USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN; + + /* ALL endpoint enable */ + USBHSD->ENDP_CONFIG = 0xffffffff; + + USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; + USBHSD->ENDP_TYPE = 0x00; + USBHSD->BUF_MODE = 0x00; + + USBHSD->UEP0_MAX_LEN = 64; + + USBHSD->UEP0_DMA = (uint32_t)EP0_DatabufHD; + + USBHSD->UEP0_TX_LEN = 0; + USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_NAK; + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; + + for (int ep = 1; ep < EP_MAX; ep++) { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + + EP_RX_MAX_LEN(ep) = 512; + } + + USBHSD->DEV_AD = 0; + USBHSD->CONTROL |= USBHS_DEV_PU_EN; +} + +void dcd_int_enable(uint8_t rhport) { + (void)rhport; + + NVIC_EnableIRQ(USBHS_IRQn); +} + +void dcd_int_disable(uint8_t rhport) { + (void)rhport; + + NVIC_DisableIRQ(USBHS_IRQn); +} + +void dcd_edpt_close_all(uint8_t rhport) { + (void)rhport; +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void)dev_addr; + + // Response with zlp status + dcd_edpt_xfer(rhport, 0x80, NULL, 0); +} + +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { + (void)rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBHSD->DEV_AD = (uint8_t)request->wValue; + } + + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { + (void)rhport; + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + TU_ASSERT(epnum < EP_MAX); + + xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); + + if (epnum != 0) { + if (tu_edpt_dir(desc_edpt->bEndpointAddress) == TUSB_DIR_OUT) { + EP_RX_CTRL(epnum) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK; + } else { + EP_TX_LEN(epnum) = 0; + EP_TX_CTRL(epnum) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + } + } + + return true; +} + +int usbd_ep_close(const uint8_t ep) { + (void)ep; + + return 0; +} +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (epnum == 0) { + if (dir == TUSB_DIR_OUT) { + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_STALL; + } else { + USBHSD->UEP0_TX_LEN = 0; + USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_STALL; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL; + + } else { + EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (epnum == 0) { + if (dir == TUSB_DIR_OUT) { + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; + } else { + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~(USBHS_EP_R_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_ACK; + + } else { + EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_NAK; + } + } +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void)rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->short_packet = false; + + // uint16_t num_packets = (total_bytes / xfer->max_size); + uint16_t short_packet_size = total_bytes % (xfer->max_size + 1); + + // Zero-size packet is special case. + if (short_packet_size == 0 || (total_bytes == 0)) { + xfer->short_packet = true; + } + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + if (!total_bytes) { + xfer->short_packet = true; + if (epnum == 0) { + USBHSD->UEP0_TX_LEN = 0; + USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); + USBHS_Dev_Endp0_Tog ^= 1; + } else { + EP_TX_LEN(epnum) = 0; + EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; + } + } else { + if (epnum == 0) { + xfer->queued_len += short_packet_size; + memcpy(&EP0_DatabufHD[0], buffer, short_packet_size); + + USBHSD->UEP0_TX_LEN = short_packet_size; + USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); + USBHS_Dev_Endp0_Tog ^= 1; + } else { + xfer->queued_len += short_packet_size; + + EP_TX_DMA_ADDR(epnum) = (uint32_t)buffer; + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << epnum); + EP_TX_LEN(epnum) = short_packet_size; + EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; + } + } + } else { /* TUSB_DIR_OUT */ + if (epnum == 0) { + uint32_t read_count = USBHSD->RX_LEN; + read_count = TU_MIN(read_count, total_bytes); + + if ((total_bytes == 8)) { + read_count = 8; + memcpy(buffer, &EP0_DatabufHD[0], 8); + } else { + memcpy(buffer, &EP0_DatabufHD[0], read_count); + } + } else { + EP_RX_DMA_ADDR(epnum) = (uint32_t)xfer->buffer; + USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << epnum); + } + + // usbd_ep_read(ep_addr, buffer, total_bytes, &ret_bytes); + } + return true; +} + + +static void receive_packet(xfer_ctl_t *xfer, uint16_t xfer_size) { + // xfer->queued_len = xfer->total_len - remaining; + + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t to_recv_size; + + if (remaining <= xfer->max_size) { + // Avoid buffer overflow. + to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; + } else { + // Room for full packet, choose recv_size based on what the microcontroller + // claims. + to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; + } + + if (to_recv_size) { + } + + xfer->queued_len += xfer_size; + + // Per USB spec, a short OUT packet (including length 0) is always + // indicative of the end of a transfer (at least for ctl, bulk, int). + xfer->short_packet = (xfer_size < xfer->max_size); +} + +void dcd_int_handler(uint8_t rhport) { + (void)rhport; + + uint32_t end_num, rx_token; + uint8_t intflag = 0; + + intflag = USBHSD->INT_FG; + + if (intflag & USBHS_TRANSFER_FLAG) { + + end_num = (USBHSD->INT_ST) & MASK_UIS_ENDP; + rx_token = (((USBHSD->INT_ST) & MASK_UIS_TOKEN) >> 4) & 0x03; + + uint8_t endp = end_num | (rx_token == PID_IN ? TUSB_DIR_IN_MASK : 0); + + xfer_ctl_t *xfer = XFER_CTL_BASE(end_num, tu_edpt_dir(endp)); + + if (rx_token == PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + receive_packet(xfer, rx_len); + + if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { + xfer->short_packet = false; + + dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } + + if (end_num == 0) { + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + } + + } else if (rx_token == PID_IN) { + if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { + xfer->short_packet = false; + xfer->total_len = 0; + dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); + + EP_TX_CTRL(end_num) = (EP_TX_CTRL(end_num) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_NAK; + + if (end_num == 0) { + } + } else { + dcd_edpt_xfer(0, endp, xfer->buffer + xfer->queued_len, xfer->total_len - xfer->queued_len); + } + } + + USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ + } else if (intflag & USBHS_SETUP_FLAG) { + USBHS_Dev_Endp0_Tog = 1; + dcd_event_setup_received(0, EP0_DatabufHD, true); + + USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ + } else if (intflag & USBHS_DETECT_FLAG) { + USBHS_Dev_Endp0_Tog = 1; + + xfer_status[0][TUSB_DIR_OUT].max_size = 64; + xfer_status[0][TUSB_DIR_IN].max_size = 64; + + dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); + + USBHSD->DEV_AD = 0; + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + + USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ + } else if (intflag & USBHS_SUSPEND_FLAG) { + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; + dcd_event_handler(&event, true); + + USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ + } +} + +#endif \ No newline at end of file diff --git a/src/tusb_option.h b/src/tusb_option.h index bd87a953c..ffeec2241 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -149,6 +149,9 @@ // Allwinner #define OPT_MCU_F1C100S 2100 ///< Allwinner F1C100s family +// WCH +#define OPT_MCU_CH32VF307 2200 ///< WCH CH32V307 config + // Helper to check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input #define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) -- cgit v1.3.1 From a09c1648f56580bcdb59b08af255442d9240281c Mon Sep 17 00:00:00 2001 From: Greg Davill Date: Tue, 22 Mar 2022 23:31:20 +1030 Subject: Fix typo --- hw/bsp/ch32v307/family.mk | 2 +- src/common/tusb_mcu.h | 2 +- src/portable/wch/ch32v307/usb_dc_usbhs.c | 2 +- src/tusb_option.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index dfb4853d9..ef2af26e6 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -28,7 +28,7 @@ CFLAGS += \ -ffunction-sections \ -fdata-sections \ -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_CH32VF307 \ + -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ -Xlinker --gc-sections \ -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 84d629eac..9de092e34 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -267,7 +267,7 @@ #define TUP_DCD_ENDPOINT_MAX 4 //------------- WCH -------------// -#elif TU_CHECK_MCU(OPT_MCU_CH32VF307) +#elif TU_CHECK_MCU(OPT_MCU_CH32V307) #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/portable/wch/ch32v307/usb_dc_usbhs.c b/src/portable/wch/ch32v307/usb_dc_usbhs.c index 32645dc5f..3a2c9979e 100644 --- a/src/portable/wch/ch32v307/usb_dc_usbhs.c +++ b/src/portable/wch/ch32v307/usb_dc_usbhs.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32VF307) +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V307) #include "device/dcd.h" #include "usb_ch32_usbhs_reg.h" diff --git a/src/tusb_option.h b/src/tusb_option.h index ffeec2241..28bf8a60d 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -150,7 +150,7 @@ #define OPT_MCU_F1C100S 2100 ///< Allwinner F1C100s family // WCH -#define OPT_MCU_CH32VF307 2200 ///< WCH CH32V307 config +#define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 config // Helper to check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input -- cgit v1.3.1 From 325923b6c61d0a914a0c6f78e650c6b85fbd13d2 Mon Sep 17 00:00:00 2001 From: Greg Davill Date: Tue, 22 Mar 2022 23:40:54 +1030 Subject: Update comments about endpoint buffer modes --- src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h b/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h index 1b7c0e791..5a2c1fbc9 100644 --- a/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h +++ b/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h @@ -231,12 +231,12 @@ #define USBHS_EP15_BUF_MOD (1 << 15) #define USBHS_EP15_ISO_BUF_MOD (1 << 31) -//USBHS_EPn_T_EN USBHS_EPn_R_EN USBHS_EPn_BUF_MOD 锟斤拷锟斤拷锟斤拷锟斤拷UEPn_DMA为锟斤拷始锟斤拷址锟缴碉拷锟斤拷锟斤拷锟斤拷锟� -// 0 0 x 锟剿点被锟斤拷锟矫o拷未锟矫碉拷UEPn_*_DMA锟斤拷锟斤拷锟斤拷锟斤拷 -// 1 0 0 锟斤拷锟秸o拷OUT锟斤拷锟斤拷锟斤拷锟斤拷锟阶碉拷址为UEPn_RX_DMA -// 1 0 1 bUEPn_RX_TOG[0]=0,使锟矫伙拷锟斤拷锟斤拷UEPn_RX_DMA锟斤拷bUEPn_RX_TOG[0]=1,使锟矫伙拷锟斤拷锟斤拷UEPn_TX_DMA -// 0 1 0 锟斤拷锟斤拷(IN)锟斤拷锟斤拷锟斤拷锟阶碉拷址为UEPn_TX_DMA锟斤拷 -// 0 1 1 bUEPn_TX_TOG[0]=0,使锟矫伙拷锟斤拷锟斤拷UEPn_TX_DMA锟斤拷bUEPn_TX_TOG[0]=1,使锟矫伙拷锟斤拷锟斤拷UEPn_RX_DMA +//USBHS_EPn_T_EN USBHS_EPn_R_EN USBHS_EPn_BUF_MOD Description: Arrange from low to high with UEPn_DMA as the starting address +// 0 0 x The endpoint is disabled and the UEPn_*_DMA buffers are not used. +// 1 0 0 The first address of the receive (OUT) buffer is UEPn_RX_DMA +// 1 0 1 RB_UEPn_RX_TOG[0]=0, use buffer UEPn_RX_DMA RB_UEPn_RX_TOG[0]=1, use buffer UEPn_TX_DMA +// 0 1 0 The first address of the transmit (IN) buffer is UEPn_TX_DMA. +// 0 1 1 RB_UEPn_TX_TOG[0]=0, use buffer UEPn_TX_DMA RB_UEPn_TX_TOG[0]=1, use buffer UEPn_RX_DMA /* USB0_DMA */ #define USBHS_UEP0_DMA_OFFSET(n) (0x1C) // endpoint 0 DMA buffer address -- cgit v1.3.1 From cdb8a1a2a1dd863f35fd91d58c18ec83115f9326 Mon Sep 17 00:00:00 2001 From: Greg Davill Date: Wed, 23 Mar 2022 00:00:06 +1030 Subject: Clean up driver --- src/common/tusb_mcu.h | 2 +- src/portable/wch/ch32v307/usb_dc_usbhs.c | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 9de092e34..fb0cdd361 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -268,7 +268,7 @@ //------------- WCH -------------// #elif TU_CHECK_MCU(OPT_MCU_CH32V307) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 16 #endif diff --git a/src/portable/wch/ch32v307/usb_dc_usbhs.c b/src/portable/wch/ch32v307/usb_dc_usbhs.c index 3a2c9979e..e647389ee 100644 --- a/src/portable/wch/ch32v307/usb_dc_usbhs.c +++ b/src/portable/wch/ch32v307/usb_dc_usbhs.c @@ -56,10 +56,8 @@ static xfer_ctl_t xfer_status[EP_MAX][2]; #define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) /* Endpoint Buffer */ -__attribute__((aligned(4))) uint8_t setup[8]; // ep0(64) -__attribute__((aligned(4))) uint8_t EP0_DatabufHD[64]; // ep0(64) +TU_ATTR_ALIGNED(4) uint8_t EP0_DatabufHD[64]; // ep0(64) -volatile uint8_t mps_over_flag = 0; volatile uint8_t USBHS_Dev_Endp0_Tog = 0x01; void dcd_init(uint8_t rhport) { @@ -67,15 +65,15 @@ void dcd_init(uint8_t rhport) { memset(&xfer_status, 0, sizeof(xfer_status)); - // usb_dc_low_level_init(); - USBHSD->HOST_CTRL = 0x00; USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; USBHSD->CONTROL = 0; -#if 1 + +#if (BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_HIGH_SPEED) USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; #else + #error OPT_MODE_FULL_SPEED not currently supported on CH32V307 USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; #endif -- cgit v1.3.1 From 2a520fb921fceb2a8e6182bff073c4a98504127f Mon Sep 17 00:00:00 2001 From: gaoyichuan Date: Wed, 25 May 2022 09:51:58 +0800 Subject: hid: add fido hid descriptor templates --- src/class/hid/hid.h | 9 +++++++++ src/class/hid/hid_device.h | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'src') diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 44a464be1..296664f62 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -708,6 +708,7 @@ enum { HID_USAGE_PAGE_MSR = 0x8e, HID_USAGE_PAGE_CAMERA = 0x90, HID_USAGE_PAGE_ARCADE = 0x91, + HID_USAGE_PAGE_FIDO_ALLIANCE = 0xF1D0, HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; @@ -844,6 +845,14 @@ enum HID_USAGE_CONSUMER_AC_PAN = 0x0238, }; +/// HID Usage Table: FIDO Alliance Page (0xF1D0) +enum +{ + HID_USAGE_FIDO_U2F_AUTHENTICATOR_DEVICE = 0x01, + HID_USAGE_FIDO_INPUT_REPORT_DATA = 0x20, + HID_USAGE_FIDO_OUTPUT_REPORT_DATA = 0x21 +}; + /*-------------------------------------------------------------------- * ASCII to KEYCODE Conversion * Expand to array of [128][2] (shift, keycode) diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 3143b1024..d6cf27bd8 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -352,6 +352,29 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ +// FIDO U2F Authenticator Descriptor Template +#define TUD_HID_REPORT_DESC_FIDO_U2F(...) \ + HID_USAGE_PAGE_N ( HID_USAGE_PAGE_FIDO_ALLIANCE, 2 ) ,\ + HID_USAGE ( HID_USAGE_FIDO_U2F_AUTHENTICATOR_DEVICE ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */ \ + __VA_ARGS__ \ + /* Usage Data In */ \ + HID_USAGE ( HID_USAGE_FIDO_INPUT_REPORT_DATA ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX_N ( 255, 2 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_REPORT_COUNT ( 64 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* Usage Data Out */ \ + HID_USAGE ( HID_USAGE_FIDO_OUTPUT_REPORT_DATA ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX_N ( 255, 2 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_REPORT_COUNT ( 64 ) ,\ + HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + HID_COLLECTION_END \ + // HID Generic Input & Output // - 1st parameter is report size (mandatory) // - 2nd parameter is report id HID_REPORT_ID(n) (optional) -- cgit v1.3.1 From 3846d5f38c465d673442db1085c69f3602e21470 Mon Sep 17 00:00:00 2001 From: gaoyichuan Date: Sat, 15 Oct 2022 19:22:21 +0800 Subject: hid: add configurable report size for fido --- src/class/hid/hid_device.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index d6cf27bd8..a9f47d644 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -353,7 +353,9 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_COLLECTION_END \ // FIDO U2F Authenticator Descriptor Template -#define TUD_HID_REPORT_DESC_FIDO_U2F(...) \ +// - 1st parameter is report size, which is 64 bytes maximum in U2F +// - 2nd parameter is HID_REPORT_ID(n) (optional) +#define TUD_HID_REPORT_DESC_FIDO_U2F(report_size, ...) \ HID_USAGE_PAGE_N ( HID_USAGE_PAGE_FIDO_ALLIANCE, 2 ) ,\ HID_USAGE ( HID_USAGE_FIDO_U2F_AUTHENTICATOR_DEVICE ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ @@ -362,16 +364,16 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y /* Usage Data In */ \ HID_USAGE ( HID_USAGE_FIDO_INPUT_REPORT_DATA ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ - HID_LOGICAL_MAX_N ( 255, 2 ) ,\ + HID_LOGICAL_MAX_N ( 0xff, 2 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ - HID_REPORT_COUNT ( 64 ) ,\ + HID_REPORT_COUNT ( report_size ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* Usage Data Out */ \ HID_USAGE ( HID_USAGE_FIDO_OUTPUT_REPORT_DATA ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ - HID_LOGICAL_MAX_N ( 255, 2 ) ,\ + HID_LOGICAL_MAX_N ( 0xff, 2 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ - HID_REPORT_COUNT ( 64 ) ,\ + HID_REPORT_COUNT ( report_size ) ,\ HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ -- cgit v1.3.1 From d588167a39fd01e5cea718deb1917e74c6a801ab Mon Sep 17 00:00:00 2001 From: pete-pjb Date: Wed, 30 Nov 2022 11:33:24 +0000 Subject: Modify FreeRTOS integration to allow non-static allocation. --- src/osal/osal_freertos.h | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 52db336f5..a2b0573f8 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -62,12 +62,20 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ +#if configSUPPORT_STATIC_ALLOCATION == 1 typedef StaticSemaphore_t osal_semaphore_def_t; +#else +typedef SemaphoreHandle_t osal_semaphore_def_t; +#endif typedef SemaphoreHandle_t osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { +#if configSUPPORT_STATIC_ALLOCATION == 1 return xSemaphoreCreateBinaryStatic(semdef); +#else + return xSemaphoreCreateBinary(); +#endif } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) @@ -105,12 +113,21 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t c //--------------------------------------------------------------------+ // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ +#if configSUPPORT_STATIC_ALLOCATION == 1 typedef StaticSemaphore_t osal_mutex_def_t; +#else +typedef SemaphoreHandle_t osal_mutex_def_t; +#endif typedef SemaphoreHandle_t osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { +#if configSUPPORT_STATIC_ALLOCATION == 1 return xSemaphoreCreateMutexStatic(mdef); +#else + return xSemaphoreCreateMutex(); +#endif + } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) @@ -145,7 +162,11 @@ typedef QueueHandle_t osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { - return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); +#if configSUPPORT_STATIC_ALLOCATION == 1 + return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); +#else + return xQueueCreate(qdef->depth, qdef->item_sz); +#endif } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -- cgit v1.3.1 From 069215c538cc1b615f18a6af055026267d56581c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 30 Nov 2022 18:36:01 +0700 Subject: white spaces --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 587 ++++++++++++++------------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 54 ++- 2 files changed, 330 insertions(+), 311 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 10237d1f9..9e6bdad44 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -81,89 +81,90 @@ static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) TU_ATTR_ALWAYS_INLINE static inline uint8_t dev_speed(void) { - return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB; + return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB; } -static bool need_pre(uint8_t dev_addr) +TU_ATTR_ALWAYS_INLINE static inline bool need_pre(uint8_t dev_addr) { - // If this device is different to the speed of the root device - // (i.e. is a low speed device on a full speed hub) then need pre - return hcd_port_speed_get(0) != tuh_speed_get(dev_addr); + // If this device is different to the speed of the root device + // (i.e. is a low speed device on a full speed hub) then need pre + return hcd_port_speed_get(0) != tuh_speed_get(dev_addr); } static void __tusb_irq_path_func(hw_xfer_complete)(struct hw_endpoint *ep, xfer_result_t xfer_result) { - // Mark transfer as done before we tell the tinyusb stack - uint8_t dev_addr = ep->dev_addr; - uint8_t ep_addr = ep->ep_addr; - uint xferred_len = ep->xferred_len; - hw_endpoint_reset_transfer(ep); - hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); + // Mark transfer as done before we tell the tinyusb stack + uint8_t dev_addr = ep->dev_addr; + uint8_t ep_addr = ep->ep_addr; + uint xferred_len = ep->xferred_len; + hw_endpoint_reset_transfer(ep); + hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); } static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_endpoint *ep) { - usb_hw_clear->buf_status = bit; - // EP may have been stalled? - assert(ep->active); - bool done = hw_endpoint_xfer_continue(ep); - if (done) - { - hw_xfer_complete(ep, XFER_RESULT_SUCCESS); - } + usb_hw_clear->buf_status = bit; + // EP may have been stalled? + assert(ep->active); + bool done = hw_endpoint_xfer_continue(ep); + if ( done ) + { + hw_xfer_complete(ep, XFER_RESULT_SUCCESS); + } } static void __tusb_irq_path_func(hw_handle_buff_status)(void) { - uint32_t remaining_buffers = usb_hw->buf_status; - pico_trace("buf_status 0x%08x\n", remaining_buffers); + uint32_t remaining_buffers = usb_hw->buf_status; + pico_trace("buf_status 0x%08x\n", remaining_buffers); - // Check EPX first - uint bit = 0b1; - if (remaining_buffers & bit) + // Check EPX first + uint bit = 0b1; + if ( remaining_buffers & bit ) + { + remaining_buffers &= ~bit; + struct hw_endpoint * ep = &epx; + + uint32_t ep_ctrl = *ep->endpoint_control; + if ( ep_ctrl & EP_CTRL_DOUBLE_BUFFERED_BITS ) { - remaining_buffers &= ~bit; - struct hw_endpoint *ep = &epx; - - uint32_t ep_ctrl = *ep->endpoint_control; - if (ep_ctrl & EP_CTRL_DOUBLE_BUFFERED_BITS) - { - TU_LOG(3, "Double Buffered: "); - }else - { - TU_LOG(3, "Single Buffered: "); - } - TU_LOG_HEX(3, ep_ctrl); - - _handle_buff_status_bit(bit, ep); + TU_LOG(3, "Double Buffered: "); } - - // Check "interrupt" (asynchronous) endpoints for both IN and OUT - for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++) + else { - // EPX is bit 0 & 1 - // IEP1 IN is bit 2 - // IEP1 OUT is bit 3 - // IEP2 IN is bit 4 - // IEP2 OUT is bit 5 - // IEP3 IN is bit 6 - // IEP3 OUT is bit 7 - // etc - for(uint j = 0; j < 2; j++) - { - bit = 1 << (i*2+j); - if (remaining_buffers & bit) - { - remaining_buffers &= ~bit; - _handle_buff_status_bit(bit, &ep_pool[i]); - } - } + TU_LOG(3, "Single Buffered: "); } + TU_LOG_HEX(3, ep_ctrl); - if (remaining_buffers) + _handle_buff_status_bit(bit, ep); + } + + // Check "interrupt" (asynchronous) endpoints for both IN and OUT + for ( uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++ ) + { + // EPX is bit 0 & 1 + // IEP1 IN is bit 2 + // IEP1 OUT is bit 3 + // IEP2 IN is bit 4 + // IEP2 OUT is bit 5 + // IEP3 IN is bit 6 + // IEP3 OUT is bit 7 + // etc + for ( uint j = 0; j < 2; j++ ) { - panic("Unhandled buffer %d\n", remaining_buffers); + bit = 1 << (i * 2 + j); + if ( remaining_buffers & bit ) + { + remaining_buffers &= ~bit; + _handle_buff_status_bit(bit, &ep_pool[i]); + } } + } + + if ( remaining_buffers ) + { + panic("Unhandled buffer %d\n", remaining_buffers); + } } static void __tusb_irq_path_func(hw_trans_complete)(void) @@ -186,70 +187,72 @@ static void __tusb_irq_path_func(hw_trans_complete)(void) static void __tusb_irq_path_func(hcd_rp2040_irq)(void) { - uint32_t status = usb_hw->ints; - uint32_t handled = 0; + uint32_t status = usb_hw->ints; + uint32_t handled = 0; - if (status & USB_INTS_HOST_CONN_DIS_BITS) - { - handled |= USB_INTS_HOST_CONN_DIS_BITS; - - if (dev_speed()) - { - hcd_event_device_attach(RHPORT_NATIVE, true); - } - else - { - hcd_event_device_remove(RHPORT_NATIVE, true); - } - - // Clear speed change interrupt - usb_hw_clear->sie_status = USB_SIE_STATUS_SPEED_BITS; - } + if ( status & USB_INTS_HOST_CONN_DIS_BITS ) + { + handled |= USB_INTS_HOST_CONN_DIS_BITS; - if (status & USB_INTS_STALL_BITS) + if ( dev_speed() ) { - // We have rx'd a stall from the device - // NOTE THIS SHOULD HAVE PRIORITY OVER BUFF_STATUS - // AND TRANS_COMPLETE as the stall is an alternative response - // to one of those events - pico_trace("Stall REC\n"); - handled |= USB_INTS_STALL_BITS; - usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS; - hw_xfer_complete(&epx, XFER_RESULT_STALLED); + hcd_event_device_attach(RHPORT_NATIVE, true); } - - if (status & USB_INTS_BUFF_STATUS_BITS) + else { - handled |= USB_INTS_BUFF_STATUS_BITS; - TU_LOG(2, "Buffer complete\n"); - hw_handle_buff_status(); + hcd_event_device_remove(RHPORT_NATIVE, true); } - if (status & USB_INTS_TRANS_COMPLETE_BITS) - { - handled |= USB_INTS_TRANS_COMPLETE_BITS; - usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS; - TU_LOG(2, "Transfer complete\n"); - hw_trans_complete(); - } + // Clear speed change interrupt + usb_hw_clear->sie_status = USB_SIE_STATUS_SPEED_BITS; + } - if (status & USB_INTS_ERROR_RX_TIMEOUT_BITS) - { - handled |= USB_INTS_ERROR_RX_TIMEOUT_BITS; - usb_hw_clear->sie_status = USB_SIE_STATUS_RX_TIMEOUT_BITS; - } + if ( status & USB_INTS_STALL_BITS ) + { + // We have rx'd a stall from the device + // NOTE THIS SHOULD HAVE PRIORITY OVER BUFF_STATUS + // AND TRANS_COMPLETE as the stall is an alternative response + // to one of those events + pico_trace("Stall REC\n"); + handled |= USB_INTS_STALL_BITS; + usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS; + hw_xfer_complete(&epx, XFER_RESULT_STALLED); + } - if (status & USB_INTS_ERROR_DATA_SEQ_BITS) - { - usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS; - TU_LOG(3, " Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(*epx.buffer_control), tu_u32_high16(*epx.buffer_control)); - panic("Data Seq Error \n"); - } + if ( status & USB_INTS_BUFF_STATUS_BITS ) + { + handled |= USB_INTS_BUFF_STATUS_BITS; + TU_LOG(2, "Buffer complete\n"); + hw_handle_buff_status(); + } - if (status ^ handled) - { - panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled)); - } + if ( status & USB_INTS_TRANS_COMPLETE_BITS ) + { + handled |= USB_INTS_TRANS_COMPLETE_BITS; + usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS; + TU_LOG(2, "Transfer complete\n"); + hw_trans_complete(); + } + + if ( status & USB_INTS_ERROR_RX_TIMEOUT_BITS ) + { + handled |= USB_INTS_ERROR_RX_TIMEOUT_BITS; + usb_hw_clear->sie_status = USB_SIE_STATUS_RX_TIMEOUT_BITS; + } + + if ( status & USB_INTS_ERROR_DATA_SEQ_BITS ) + { + usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS; + TU_LOG(3, " Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n", + tu_u32_low16(*epx.buffer_control), + tu_u32_high16(*epx.buffer_control)); + panic("Data Seq Error \n"); + } + + if ( status ^ handled ) + { + panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled)); + } } void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport) @@ -260,116 +263,118 @@ void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport) static struct hw_endpoint *_next_free_interrupt_ep(void) { - struct hw_endpoint *ep = NULL; - for (uint i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) + struct hw_endpoint * ep = NULL; + for ( uint i = 1; i < TU_ARRAY_SIZE(ep_pool); i++ ) + { + ep = &ep_pool[i]; + if ( !ep->configured ) { - ep = &ep_pool[i]; - if (!ep->configured) - { - // Will be configured by _hw_endpoint_init / _hw_endpoint_allocate - ep->interrupt_num = (uint8_t) (i - 1); - return ep; - } + // Will be configured by _hw_endpoint_init / _hw_endpoint_allocate + ep->interrupt_num = (uint8_t) (i - 1); + return ep; } - return ep; + } + return ep; } static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) { - struct hw_endpoint *ep = NULL; + struct hw_endpoint * ep = NULL; - if (transfer_type != TUSB_XFER_CONTROL) - { - // Note: even though datasheet name these "Interrupt" endpoints. These are actually - // "Asynchronous" endpoints and can be used for other type such as: Bulk (ISO need confirmation) - ep = _next_free_interrupt_ep(); - pico_info("Allocate %s ep %d\n", tu_edpt_type_str(transfer_type), ep->interrupt_num); - assert(ep); - ep->buffer_control = &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; - ep->endpoint_control = &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; - // 0 for epx (double buffered): TODO increase to 1024 for ISO - // 2x64 for intep0 - // 3x64 for intep1 - // etc - ep->hw_data_buf = &usbh_dpram->epx_data[64 * (ep->interrupt_num + 2)]; - } - else - { - ep = &epx; - ep->buffer_control = &usbh_dpram->epx_buf_ctrl; - ep->endpoint_control = &usbh_dpram->epx_ctrl; - ep->hw_data_buf = &usbh_dpram->epx_data[0]; - } + if ( transfer_type != TUSB_XFER_CONTROL ) + { + // Note: even though datasheet name these "Interrupt" endpoints. These are actually + // "Asynchronous" endpoints and can be used for other type such as: Bulk (ISO need confirmation) + ep = _next_free_interrupt_ep(); + pico_info("Allocate %s ep %d\n", tu_edpt_type_str(transfer_type), ep->interrupt_num); + assert(ep); + ep->buffer_control = &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; + ep->endpoint_control = &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; + // 0 for epx (double buffered): TODO increase to 1024 for ISO + // 2x64 for intep0 + // 3x64 for intep1 + // etc + ep->hw_data_buf = &usbh_dpram->epx_data[64 * (ep->interrupt_num + 2)]; + } + else + { + ep = &epx; + ep->buffer_control = &usbh_dpram->epx_buf_ctrl; + ep->endpoint_control = &usbh_dpram->epx_ctrl; + ep->hw_data_buf = &usbh_dpram->epx_data[0]; + } - return ep; + return ep; } static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval) { - // Already has data buffer, endpoint control, and buffer control allocated at this point - assert(ep->endpoint_control); - assert(ep->buffer_control); - assert(ep->hw_data_buf); - - uint8_t const num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); - - ep->ep_addr = ep_addr; - ep->dev_addr = dev_addr; - - // For host, IN to host == RX, anything else rx == false - ep->rx = (dir == TUSB_DIR_IN); - - // Response to a setup packet on EP0 starts with pid of 1 - ep->next_pid = (num == 0 ? 1u : 0u); - ep->wMaxPacketSize = wMaxPacketSize; - ep->transfer_type = transfer_type; - - pico_trace("hw_endpoint_init dev %d ep %d %s xfer %d\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->transfer_type); - pico_trace("dev %d ep %d %s setup buffer @ 0x%p\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->hw_data_buf); - uint dpram_offset = hw_data_offset(ep->hw_data_buf); - // Bits 0-5 should be 0 - assert(!(dpram_offset & 0b111111)); - - // Fill in endpoint control register with buffer offset - uint32_t ep_reg = EP_CTRL_ENABLE_BITS - | EP_CTRL_INTERRUPT_PER_BUFFER - | (ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) - | dpram_offset; - if (bmInterval) + // Already has data buffer, endpoint control, and buffer control allocated at this point + assert(ep->endpoint_control); + assert(ep->buffer_control); + assert(ep->hw_data_buf); + + uint8_t const num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); + + ep->ep_addr = ep_addr; + ep->dev_addr = dev_addr; + + // For host, IN to host == RX, anything else rx == false + ep->rx = (dir == TUSB_DIR_IN); + + // Response to a setup packet on EP0 starts with pid of 1 + ep->next_pid = (num == 0 ? 1u : 0u); + ep->wMaxPacketSize = wMaxPacketSize; + ep->transfer_type = transfer_type; + + pico_trace("hw_endpoint_init dev %d ep %d %s xfer %d\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), + ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->transfer_type); + pico_trace("dev %d ep %d %s setup buffer @ 0x%p\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), + ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->hw_data_buf); + uint dpram_offset = hw_data_offset(ep->hw_data_buf); + // Bits 0-5 should be 0 + assert(!(dpram_offset & 0b111111)); + + // Fill in endpoint control register with buffer offset + uint32_t ep_reg = EP_CTRL_ENABLE_BITS + | EP_CTRL_INTERRUPT_PER_BUFFER + | (ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) + | dpram_offset; + if ( bmInterval ) + { + ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); + } + *ep->endpoint_control = ep_reg; + pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); + ep->configured = true; + + if ( ep != &epx ) + { + // Endpoint has its own addr_endp and interrupt bits to be setup! + // This is an interrupt/async endpoint. so need to set up ADDR_ENDP register with: + // - device address + // - endpoint number / direction + // - preamble + uint32_t reg = (uint32_t) (dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB)); + + if ( dir == TUSB_DIR_OUT ) { - ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); + reg |= USB_ADDR_ENDP1_INTEP_DIR_BITS; } - *ep->endpoint_control = ep_reg; - pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); - ep->configured = true; - if (ep != &epx) + if ( need_pre(dev_addr) ) { - // Endpoint has its own addr_endp and interrupt bits to be setup! - // This is an interrupt/async endpoint. so need to set up ADDR_ENDP register with: - // - device address - // - endpoint number / direction - // - preamble - uint32_t reg = (uint32_t) (dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB)); - - if (dir == TUSB_DIR_OUT) - { - reg |= USB_ADDR_ENDP1_INTEP_DIR_BITS; - } - - if (need_pre(dev_addr)) - { - reg |= USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS; - } - usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = reg; - - // Finally, enable interrupt that endpoint - usb_hw_set->int_ep_ctrl = 1 << (ep->interrupt_num + 1); - - // If it's an interrupt endpoint we need to set up the buffer control - // register + reg |= USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS; } + usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = reg; + + // Finally, enable interrupt that endpoint + usb_hw_set->int_ep_ctrl = 1 << (ep->interrupt_num + 1); + + // If it's an interrupt endpoint we need to set up the buffer control + // register + } } //--------------------------------------------------------------------+ @@ -434,16 +439,17 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; assert(rhport == 0); + // TODO: Should enumval this register - switch (dev_speed()) + switch ( dev_speed() ) { - case 1: - return TUSB_SPEED_LOW; - case 2: - return TUSB_SPEED_FULL; - default: - panic("Invalid speed\n"); - return TUSB_SPEED_INVALID; + case 1: + return TUSB_SPEED_LOW; + case 2: + return TUSB_SPEED_FULL; + default: + panic("Invalid speed\n"); + return TUSB_SPEED_INVALID; } } @@ -476,8 +482,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) uint32_t hcd_frame_number(uint8_t rhport) { - (void) rhport; - return usb_hw->sof_rd; + (void) rhport; + return usb_hw->sof_rd; } void hcd_int_enable(uint8_t rhport) @@ -501,117 +507,116 @@ void hcd_int_disable(uint8_t rhport) bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { - (void) rhport; + (void) rhport; - pico_trace("hcd_edpt_open dev_addr %d, ep_addr %d\n", dev_addr, ep_desc->bEndpointAddress); + pico_trace("hcd_edpt_open dev_addr %d, ep_addr %d\n", dev_addr, ep_desc->bEndpointAddress); - // Allocated differently based on if it's an interrupt endpoint or not - struct hw_endpoint *ep = _hw_endpoint_allocate(ep_desc->bmAttributes.xfer); - TU_ASSERT(ep); + // Allocated differently based on if it's an interrupt endpoint or not + struct hw_endpoint *ep = _hw_endpoint_allocate(ep_desc->bmAttributes.xfer); + TU_ASSERT(ep); - _hw_endpoint_init(ep, - dev_addr, - ep_desc->bEndpointAddress, - tu_edpt_packet_size(ep_desc), - ep_desc->bmAttributes.xfer, - ep_desc->bInterval); + _hw_endpoint_init(ep, + dev_addr, + ep_desc->bEndpointAddress, + tu_edpt_packet_size(ep_desc), + ep_desc->bmAttributes.xfer, + ep_desc->bInterval); - return true; + return true; } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { - (void) rhport; + (void) rhport; - pico_trace("hcd_edpt_xfer dev_addr %d, ep_addr 0x%x, len %d\n", dev_addr, ep_addr, buflen); - - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const ep_dir = tu_edpt_dir(ep_addr); + pico_trace("hcd_edpt_xfer dev_addr %d, ep_addr 0x%x, len %d\n", dev_addr, ep_addr, buflen); - // Get appropriate ep. Either EPX or interrupt endpoint - struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const ep_dir = tu_edpt_dir(ep_addr); - TU_ASSERT(ep); + // Get appropriate ep. Either EPX or interrupt endpoint + struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); - // EP should be inactive - assert(!ep->active); + TU_ASSERT(ep); - // Control endpoint can change direction 0x00 <-> 0x80 - if ( ep_addr != ep->ep_addr ) - { - assert(ep_num == 0); + // EP should be inactive + assert(!ep->active); - // Direction has flipped on endpoint control so re init it but with same properties - _hw_endpoint_init(ep, dev_addr, ep_addr, ep->wMaxPacketSize, ep->transfer_type, 0); - } + // Control endpoint can change direction 0x00 <-> 0x80 + if ( ep_addr != ep->ep_addr ) + { + assert(ep_num == 0); - // If a normal transfer (non-interrupt) then initiate using - // sie ctrl registers. Otherwise interrupt ep registers should - // already be configured - if (ep == &epx) { - hw_endpoint_xfer_start(ep, buffer, buflen); + // Direction has flipped on endpoint control so re init it but with same properties + _hw_endpoint_init(ep, dev_addr, ep_addr, ep->wMaxPacketSize, ep->transfer_type, 0); + } - // That has set up buffer control, endpoint control etc - // for host we have to initiate the transfer - usb_hw->dev_addr_ctrl = (uint32_t) (dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB)); + // If a normal transfer (non-interrupt) then initiate using + // sie ctrl registers. Otherwise interrupt ep registers should + // already be configured + if ( ep == &epx ) + { + hw_endpoint_xfer_start(ep, buffer, buflen); - uint32_t flags = USB_SIE_CTRL_START_TRANS_BITS | SIE_CTRL_BASE | - (ep_dir ? USB_SIE_CTRL_RECEIVE_DATA_BITS : USB_SIE_CTRL_SEND_DATA_BITS); - // Set pre if we are a low speed device on full speed hub - flags |= need_pre(dev_addr) ? USB_SIE_CTRL_PREAMBLE_EN_BITS : 0; + // That has set up buffer control, endpoint control etc + // for host we have to initiate the transfer + usb_hw->dev_addr_ctrl = (uint32_t) (dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB)); - usb_hw->sie_ctrl = flags; - }else - { - hw_endpoint_xfer_start(ep, buffer, buflen); - } + uint32_t flags = USB_SIE_CTRL_START_TRANS_BITS | SIE_CTRL_BASE | + (ep_dir ? USB_SIE_CTRL_RECEIVE_DATA_BITS : USB_SIE_CTRL_SEND_DATA_BITS) | + (need_pre(dev_addr) ? USB_SIE_CTRL_PREAMBLE_EN_BITS : 0); + usb_hw->sie_ctrl = flags; + }else + { + hw_endpoint_xfer_start(ep, buffer, buflen); + } - return true; + return true; } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { - (void) rhport; + (void) rhport; - // Copy data into setup packet buffer - for(uint8_t i=0; i<8; i++) - { - usbh_dpram->setup_packet[i] = setup_packet[i]; - } + // Copy data into setup packet buffer + for ( uint8_t i = 0; i < 8; i++ ) + { + usbh_dpram->setup_packet[i] = setup_packet[i]; + } - // Configure EP0 struct with setup info for the trans complete - struct hw_endpoint *ep = _hw_endpoint_allocate(0); - TU_ASSERT(ep); + // Configure EP0 struct with setup info for the trans complete + struct hw_endpoint * ep = _hw_endpoint_allocate(0); + TU_ASSERT(ep); - // EPX should be inactive - assert(!ep->active); + // EPX should be inactive + assert(!ep->active); - // EP0 out - _hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); - assert(ep->configured); + // EP0 out + _hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); + assert(ep->configured); - ep->remaining_len = 8; - ep->active = true; + ep->remaining_len = 8; + ep->active = true; - // Set device address - usb_hw->dev_addr_ctrl = dev_addr; + // Set device address + usb_hw->dev_addr_ctrl = dev_addr; - // Set pre if we are a low speed device on full speed hub - uint32_t const flags = SIE_CTRL_BASE | USB_SIE_CTRL_SEND_SETUP_BITS | USB_SIE_CTRL_START_TRANS_BITS | - (need_pre(dev_addr) ? USB_SIE_CTRL_PREAMBLE_EN_BITS : 0); + // Set pre if we are a low speed device on full speed hub + uint32_t const flags = SIE_CTRL_BASE | USB_SIE_CTRL_SEND_SETUP_BITS | USB_SIE_CTRL_START_TRANS_BITS | + (need_pre(dev_addr) ? USB_SIE_CTRL_PREAMBLE_EN_BITS : 0); - usb_hw->sie_ctrl = flags; + usb_hw->sie_ctrl = flags; - return true; + return true; } bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) { - (void) dev_addr; - (void) ep_addr; + (void) dev_addr; + (void) ep_addr; - panic("hcd_clear_stall"); - return true; + panic("hcd_clear_stall"); + return true; } #endif diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index d7895175e..5c7645902 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -47,6 +47,12 @@ TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_lock_update(__unused struc static void _hw_endpoint_xfer_sync(struct hw_endpoint *ep); static void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep); +// if usb hardware is in host mode +TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) +{ + return (usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) ? true : false; +} + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ @@ -69,6 +75,8 @@ void rp2040_usb_init(void) // Mux the controller to the onboard usb phy usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS; + + TU_LOG2_INT(sizeof(hw_endpoint_t)); } void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint *ep) @@ -80,19 +88,23 @@ void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint *ep) } void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { - uint32_t value = 0; - if (and_mask) { - value = *ep->buffer_control & and_mask; - } - if (or_mask) { - value |= or_mask; - if (or_mask & USB_BUF_CTRL_AVAIL) { - if (*ep->buffer_control & USB_BUF_CTRL_AVAIL) { - panic("ep %d %s was already available", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); - } - *ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL; - // 12 cycle delay.. (should be good for 48*12Mhz = 576Mhz) - // Don't need delay in host mode as host is in charge + uint32_t value = 0; + if ( and_mask ) + { + value = *ep->buffer_control & and_mask; + } + if ( or_mask ) + { + value |= or_mask; + if ( or_mask & USB_BUF_CTRL_AVAIL ) + { + if ( *ep->buffer_control & USB_BUF_CTRL_AVAIL ) + { + panic("ep %d %s was already available", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + } + *ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL; + // 12 cycle delay.. (should be good for 48*12Mhz = 576Mhz) + // Don't need delay in host mode as host is in charge #if !CFG_TUH_ENABLED __asm volatile ( "b 1f\n" @@ -104,9 +116,9 @@ void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoi "1:\n" : : : "memory"); #endif - } } - *ep->buffer_control = value; + } + *ep->buffer_control = value; } // prepare buffer, return buffer control @@ -152,12 +164,14 @@ static void __tusb_irq_path_func(_hw_endpoint_start_next_buffer)(struct hw_endpo // always compute and start with buffer 0 uint32_t buf_ctrl = prepare_ep_buffer(ep, 0) | USB_BUF_CTRL_SEL; - // For now: skip double buffered for Device mode, OUT endpoint since + // For now: skip double buffered for OUT endpoint in Device mode, since // host could send < 64 bytes and cause short packet on buffer0 - // NOTE this could happen to Host mode IN endpoint - // Also, Host mode interrupt endpoint hardware is only single buffered - bool const force_single = (!(usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) && !tu_edpt_dir(ep->ep_addr)) || - ((usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) && tu_edpt_number(ep->ep_addr) != 0); + // NOTE: this could happen to Host mode IN endpoint + // Also, Host mode "interrupt" endpoint hardware is only single buffered, + // NOTE2: Currently Host bulk is implemented using "interrupt" endpoint + bool const is_host = is_host_mode(); + bool const force_single = (!is_host && !tu_edpt_dir(ep->ep_addr)) || + (is_host && tu_edpt_number(ep->ep_addr) != 0); if(ep->remaining_len && !force_single) { -- cgit v1.3.1 From c9c7dfa868ea78afd6b3bb490542e65660c39149 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 30 Nov 2022 18:59:58 +0700 Subject: more clean up --- src/portable/raspberrypi/rp2040/rp2040_usb.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index c72dae64c..b65d32fd4 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -82,26 +82,30 @@ void hw_endpoint_reset_transfer(struct hw_endpoint *ep); void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask); -TU_ATTR_ALWAYS_INLINE static inline uint32_t _hw_endpoint_buffer_control_get_value32(struct hw_endpoint *ep) { - return *ep->buffer_control; +TU_ATTR_ALWAYS_INLINE static inline uint32_t _hw_endpoint_buffer_control_get_value32 (struct hw_endpoint *ep) +{ + return *ep->buffer_control; } -TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_value32(struct hw_endpoint *ep, uint32_t value) { - return _hw_endpoint_buffer_control_update32(ep, 0, value); +TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_value32 (struct hw_endpoint *ep, uint32_t value) +{ + return _hw_endpoint_buffer_control_update32(ep, 0, value); } -TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_mask32(struct hw_endpoint *ep, uint32_t value) { - return _hw_endpoint_buffer_control_update32(ep, ~value, value); +TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_mask32 (struct hw_endpoint *ep, uint32_t value) +{ + return _hw_endpoint_buffer_control_update32(ep, ~value, value); } -TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_clear_mask32(struct hw_endpoint *ep, uint32_t value) { - return _hw_endpoint_buffer_control_update32(ep, ~value, 0); +TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_clear_mask32 (struct hw_endpoint *ep, uint32_t value) +{ + return _hw_endpoint_buffer_control_update32(ep, ~value, 0); } -static inline uintptr_t hw_data_offset(uint8_t *buf) +static inline uintptr_t hw_data_offset (uint8_t *buf) { - // Remove usb base from buffer pointer - return (uintptr_t)buf ^ (uintptr_t)usb_dpram; + // Remove usb base from buffer pointer + return (uintptr_t) buf ^ (uintptr_t) usb_dpram; } extern const char *ep_dir_string[]; -- cgit v1.3.1 From 25abb10de17ed868b2189ae5038a7c47aab19ae5 Mon Sep 17 00:00:00 2001 From: pete-pjb Date: Wed, 30 Nov 2022 13:26:59 +0000 Subject: Fix white space issue. --- src/osal/osal_freertos.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index a2b0573f8..fed70400e 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -62,7 +62,7 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ -#if configSUPPORT_STATIC_ALLOCATION == 1 +#if configSUPPORT_STATIC_ALLOCATION == 1 typedef StaticSemaphore_t osal_semaphore_def_t; #else typedef SemaphoreHandle_t osal_semaphore_def_t; @@ -71,7 +71,7 @@ typedef SemaphoreHandle_t osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { -#if configSUPPORT_STATIC_ALLOCATION == 1 +#if configSUPPORT_STATIC_ALLOCATION == 1 return xSemaphoreCreateBinaryStatic(semdef); #else return xSemaphoreCreateBinary(); @@ -113,7 +113,7 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t c //--------------------------------------------------------------------+ // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ -#if configSUPPORT_STATIC_ALLOCATION == 1 +#if configSUPPORT_STATIC_ALLOCATION == 1 typedef StaticSemaphore_t osal_mutex_def_t; #else typedef SemaphoreHandle_t osal_mutex_def_t; @@ -122,7 +122,7 @@ typedef SemaphoreHandle_t osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { -#if configSUPPORT_STATIC_ALLOCATION == 1 +#if configSUPPORT_STATIC_ALLOCATION == 1 return xSemaphoreCreateMutexStatic(mdef); #else return xSemaphoreCreateMutex(); @@ -162,7 +162,7 @@ typedef QueueHandle_t osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { -#if configSUPPORT_STATIC_ALLOCATION == 1 +#if configSUPPORT_STATIC_ALLOCATION == 1 return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); #else return xQueueCreate(qdef->depth, qdef->item_sz); -- cgit v1.3.1 From ae588d796e1b035c7efd582a4e4f3fc28b3a5ac0 Mon Sep 17 00:00:00 2001 From: PeterB Date: Thu, 1 Dec 2022 16:06:15 +0000 Subject: Alter tuh_task_ext() function so no need to return when using FreeRTOS --- src/host/usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index d97b160c9..a90b54924 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -509,7 +509,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) default: break; } -#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO +#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO && CFG_TUSB_OS != OPT_OS_FREERTOS // return if there is no more events, for application to run other background if (osal_queue_empty(_usbh_q)) return; #endif -- cgit v1.3.1 From c31b95c91652f58b8b991a5481c9f7c37be7f09a Mon Sep 17 00:00:00 2001 From: pete-pjb Date: Thu, 1 Dec 2022 17:53:35 +0000 Subject: Added CFG_TUSB_MEM_SECTION define to struct _ctrl_xfer in usbh.c --- src/host/usbh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index a90b54924..f28554b81 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -246,8 +246,8 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; // Control transfer: since most controller does not support multiple control transfer // on multiple devices concurrently. And control transfer is not used much except enumeration -// We will only execute control transfer one at a time. -struct +// We will only execute control transfer one at a time.CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4096) +CFG_TUSB_MEM_SECTION struct { tusb_control_request_t request TU_ATTR_ALIGNED(4); uint8_t* buffer; -- cgit v1.3.1 From 3816869fce15509fd43eb5a6d14de76478f86cf1 Mon Sep 17 00:00:00 2001 From: pete-pjb Date: Fri, 2 Dec 2022 10:00:19 +0000 Subject: Some reverts and changes after discussion. --- src/host/usbh.c | 6 +++--- src/osal/osal_freertos.h | 5 ++++- src/portable/ehci/ehci.c | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index f28554b81..d97b160c9 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -246,8 +246,8 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; // Control transfer: since most controller does not support multiple control transfer // on multiple devices concurrently. And control transfer is not used much except enumeration -// We will only execute control transfer one at a time.CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4096) -CFG_TUSB_MEM_SECTION struct +// We will only execute control transfer one at a time. +struct { tusb_control_request_t request TU_ATTR_ALIGNED(4); uint8_t* buffer; @@ -509,7 +509,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) default: break; } -#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO && CFG_TUSB_OS != OPT_OS_FREERTOS +#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO // return if there is no more events, for application to run other background if (osal_queue_empty(_usbh_q)) return; #endif diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index fed70400e..ccb98cc99 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -74,6 +74,7 @@ TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_ #if configSUPPORT_STATIC_ALLOCATION == 1 return xSemaphoreCreateBinaryStatic(semdef); #else + (void)(semdef); return xSemaphoreCreateBinary(); #endif } @@ -125,6 +126,7 @@ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_de #if configSUPPORT_STATIC_ALLOCATION == 1 return xSemaphoreCreateMutexStatic(mdef); #else + (void)(mdef); return xSemaphoreCreateMutex(); #endif @@ -154,8 +156,9 @@ typedef struct uint16_t depth; uint16_t item_sz; void* buf; - +#if configSUPPORT_STATIC_ALLOCATION == 1 StaticQueue_t sq; +#endif }osal_queue_def_t; typedef QueueHandle_t osal_queue_t; diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 76ba2a921..0af8c3b2d 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -193,7 +193,8 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) { // TODO check type for ISO iTD and siTD // TODO Suppress cast-align warning - #pragma GCC diagnostic push + if( prev == NULL ) break; + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" ehci_qhd_t* qhd = (ehci_qhd_t*) list_next(prev); #pragma GCC diagnostic pop -- cgit v1.3.1 From 52261ac02dfbe58f35f959be852f0949cc0744cd Mon Sep 17 00:00:00 2001 From: pete-pjb Date: Fri, 2 Dec 2022 10:13:35 +0000 Subject: Back out another of my changes I am still investigating. --- src/portable/ehci/ehci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 0af8c3b2d..361015964 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -193,7 +193,6 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) { // TODO check type for ISO iTD and siTD // TODO Suppress cast-align warning - if( prev == NULL ) break; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" ehci_qhd_t* qhd = (ehci_qhd_t*) list_next(prev); -- cgit v1.3.1 From 6a2cf6728906aa61b44ecfe43b4ceef287b29bf8 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sun, 4 Dec 2022 13:58:47 +0700 Subject: Fix typos --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- docs/contributing/porting.rst | 4 ++-- docs/info/changelog.rst | 22 +++++++++++----------- examples/device/cdc_msc/src/main.c | 2 +- examples/device/cdc_msc_freertos/CMakeLists.txt | 2 +- examples/device/dfu_runtime/src/main.c | 2 +- examples/device/hid_boot_interface/src/main.c | 6 +++--- examples/host/cdc_msc_hid/src/hid_app.c | 2 +- hw/bsp/ansi_escape.h | 2 +- .../led_strip/src/led_strip_rmt_ws2812.c | 2 +- .../led_strip/src/led_strip_rmt_ws2812.c | 2 +- hw/bsp/family_support.cmake | 4 ++-- hw/bsp/gd32vf103/family.c | 2 +- hw/bsp/gd32vf103/system_gd32vf103.c | 2 +- .../evkmimxrt1010_flexspi_nor_config.h | 10 +++++----- .../evkmimxrt1015_flexspi_nor_config.h | 10 +++++----- .../evkmimxrt1020_flexspi_nor_config.h | 10 +++++----- .../evkbimxrt1050_flexspi_nor_config.h | 10 +++++----- .../evkmimxrt1060_flexspi_nor_config.h | 10 +++++----- .../evkmimxrt1064_flexspi_nor_config.h | 10 +++++----- .../boards/teensy_40/teensy40_flexspi_nor_config.h | 10 +++++----- .../boards/teensy_41/teensy41_flexspi_nor_config.h | 10 +++++----- hw/bsp/imxrt/family.mk | 2 +- hw/bsp/lpc54/family.c | 4 ++-- hw/bsp/lpc55/family.c | 4 ++-- hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld | 2 +- hw/bsp/rp2040/family.c | 2 +- .../stm32f070rbnucleo/stm32F070rbtx_flash.ld | 2 +- .../boards/stm32f072disco/STM32F072RBTx_FLASH.ld | 2 +- .../boards/stm32f103_bluepill/STM32F103X8_FLASH.ld | 2 +- .../boards/stm32f103_mini_2/STM32F103XC_FLASH.ld | 2 +- hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld | 2 +- hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld | 2 +- .../feather_stm32f405/STM32F405RGTx_FLASH.ld | 2 +- .../boards/pyboardv11/STM32F405RGTx_FLASH.ld | 2 +- .../stm32f401blackpill/STM32F401VCTx_FLASH.ld | 2 +- hw/bsp/stm32f4/boards/stm32f401blackpill/board.h | 2 +- .../boards/stm32f407disco/STM32F407VGTx_FLASH.ld | 2 +- .../stm32f411blackpill/STM32F411CEUx_FLASH.ld | 2 +- hw/bsp/stm32f4/boards/stm32f411blackpill/board.h | 2 +- .../boards/stm32f411disco/STM32F411VETx_FLASH.ld | 2 +- .../boards/stm32f412disco/STM32F412ZGTx_FLASH.ld | 2 +- .../boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld | 2 +- .../boards/stlinkv3mini/STM32F723xE_FLASH.ld | 2 +- .../boards/stm32f723disco/STM32F723xE_FLASH.ld | 2 +- .../boards/stm32f746disco/STM32F746ZGTx_FLASH.ld | 2 +- .../boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld | 2 +- .../boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld | 2 +- .../boards/stm32f769disco/STM32F769ZITx_FLASH.ld | 2 +- hw/bsp/stm32g4/boards/stm32g474nucleo/board.h | 4 ++-- .../boards/stm32h743eval/stm32h743xx_flash.ld | 2 +- .../boards/stm32h743nucleo/stm32h743xx_flash.ld | 2 +- .../waveshare_openh743i/STM32H743IITX_FLASH.ld | 2 +- hw/bsp/stm32h7/boards/waveshare_openh743i/board.h | 2 +- .../boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld | 2 +- hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld | 2 +- .../boards/stm32l476disco/STM32L476VGTx_FLASH.ld | 2 +- .../boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld | 2 +- hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h | 4 ++-- hw/bsp/tm4c123/family.c | 2 +- lib/SEGGER_RTT/RTT/SEGGER_RTT.c | 2 +- lib/networking/dnserver.c | 8 ++++---- lib/networking/ndis.h | 2 +- lib/networking/rndis_reports.c | 2 +- src/class/cdc/cdc.h | 2 +- src/class/cdc/cdc_rndis_host.c | 2 +- src/class/hid/hid_host.h | 2 +- src/class/msc/msc_host.c | 4 ++-- src/class/msc/msc_host.h | 2 +- src/class/net/ecm_rndis_device.c | 2 +- src/class/usbtmc/usbtmc.h | 2 +- src/class/usbtmc/usbtmc_device.h | 2 +- src/common/tusb_fifo.c | 8 ++++---- src/common/tusb_fifo.h | 4 ++-- src/device/usbd.h | 2 +- src/host/usbh.c | 4 ++-- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 6 +++--- src/portable/ehci/ehci.c | 4 ++-- src/portable/ehci/ehci.h | 10 +++++----- src/portable/espressif/esp32sx/dcd_esp32sx.c | 2 +- src/portable/microchip/pic32mz/usbhs_registers.h | 6 +++--- src/portable/microchip/samx7x/dcd_samx7x.c | 6 +++--- src/portable/nuvoton/nuc505/dcd_nuc505.c | 2 +- src/portable/ohci/ohci.c | 2 +- src/portable/ohci/ohci.h | 2 +- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- src/portable/sunxi/dcd_sunxi_musb.c | 2 +- src/portable/sunxi/musb_def.h | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- src/portable/synopsys/dwc2/dwc2_stm32.h | 2 +- 90 files changed, 160 insertions(+), 160 deletions(-) (limited to 'src') diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2958d3b12..8c39b95e1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -64,7 +64,7 @@ body: placeholder: | Attach your debug log txt file here, where the issue occurred, best with comments to explain the actual events. - Note1: Please DO NOT paste your lengthy log contents here since it hurts the readibility. + Note1: Please DO NOT paste your lengthy log contents here since it hurts the readability. Note2: To enable logging, add `LOG=3` to to the make command if building with stock examples or set `CFG_TUSB_DEBUG=3` in your tusb_config.h. More information can be found at [example's readme](https://github.com/hathach/tinyusb/blob/master/docs/getting_started.md) validations: diff --git a/docs/contributing/porting.rst b/docs/contributing/porting.rst index 7e9e462f0..710af51c3 100644 --- a/docs/contributing/porting.rst +++ b/docs/contributing/porting.rst @@ -195,7 +195,7 @@ Others (like the nRF52) may need each USB packet queued individually. To make th some state for yourself and queue up an intermediate USB packet from the interrupt handler. Once the transaction is going, the interrupt handler will notify TinyUSB of transfer completion. -During transmission, the IN data buffer is guarenteed to remain unchanged in memory until the ``dcd_xfer_complete`` function is called. +During transmission, the IN data buffer is guaranteed to remain unchanged in memory until the ``dcd_xfer_complete`` function is called. The dcd_edpt_xfer function must never add zero-length-packets (ZLP) on its own to a transfer. If a ZLP is required, then it must be explicitly sent by the stack calling dcd_edpt_xfer(), by calling dcd_edpt_xfer() a second time with len=0. @@ -238,4 +238,4 @@ Use `WireShark `_ or `a Beagle PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK; CLOCK_DisableClock(kCLOCK_Usbhsl0); /* disable usb0 host clock */ @@ -182,7 +182,7 @@ void board_init(void) // Port1 is High Speed POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); - /*According to reference mannual, device mode setting has to be set by access usb host register */ + /*According to reference manual, device mode setting has to be set by access usb host register */ CLOCK_EnableClock(kCLOCK_Usbh1); /* enable usb1 host clock */ USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK; CLOCK_DisableClock(kCLOCK_Usbh1); /* enable usb1 host clock */ diff --git a/hw/bsp/lpc55/family.c b/hw/bsp/lpc55/family.c index e7aed5759..5b6c56dd3 100644 --- a/hw/bsp/lpc55/family.c +++ b/hw/bsp/lpc55/family.c @@ -192,7 +192,7 @@ void board_init(void) CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); CLOCK_AttachClk(kFRO_HF_to_USB0_CLK); - /*According to reference mannual, device mode setting has to be set by access usb host register */ + /*According to reference manual, device mode setting has to be set by access usb host register */ CLOCK_EnableClock(kCLOCK_Usbhsl0); // enable usb0 host clock USBFSH->PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK; CLOCK_DisableClock(kCLOCK_Usbhsl0); // disable usb0 host clock @@ -213,7 +213,7 @@ void board_init(void) RESET_PeripheralReset(kUSB1_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSB1RAM_RST_SHIFT_RSTn); - /* According to reference mannual, device mode setting has to be set by access usb host register */ + /* According to reference manual, device mode setting has to be set by access usb host register */ CLOCK_EnableClock(kCLOCK_Usbh1); // enable usb0 host clock USBHSH->PORTMODE = USBHSH_PORTMODE_SW_PDCOM_MASK; // Put PHY powerdown under software control diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld b/hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld index d96d6e43d..0b45ee7bd 100644 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld @@ -126,7 +126,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 26008168d..f7ee56990 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -226,6 +226,6 @@ int board_getchar(void) //--------------------------------------------------------------------+ // USB Interrupt Handler -// rp2040 implementation will install approriate handler when initializing +// rp2040 implementation will install appropriate handler when initializing // tinyusb. There is no need to forward IRQ from application //--------------------------------------------------------------------+ diff --git a/hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld b/hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld index 59e18f375..4a6491510 100644 --- a/hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld +++ b/hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld @@ -165,7 +165,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld b/hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld index 8d31f6a00..f0879e929 100644 --- a/hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld +++ b/hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld b/hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld index ca1804905..c434ca038 100644 --- a/hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld +++ b/hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld b/hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld index da40d1eb2..da637d1b0 100644 --- a/hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld +++ b/hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld b/hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld index 29e387f28..5010435ae 100644 --- a/hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld +++ b/hw/bsp/stm32f207nucleo/STM32F207ZGTx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld b/hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld index ca9046d29..7f46c71b2 100644 --- a/hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld +++ b/hw/bsp/stm32f303disco/STM32F303VCTx_FLASH.ld @@ -150,7 +150,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld b/hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld index 57ef61e26..9eb53bcc0 100644 --- a/hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld @@ -150,7 +150,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld b/hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld index 57ef61e26..9eb53bcc0 100644 --- a/hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld @@ -150,7 +150,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld index f51f1ab41..2bc5f6c14 100644 --- a/hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f4/boards/stm32f401blackpill/board.h b/hw/bsp/stm32f4/boards/stm32f401blackpill/board.h index 0f820512c..e1fef7277 100644 --- a/hw/bsp/stm32f4/boards/stm32f401blackpill/board.h +++ b/hw/bsp/stm32f4/boards/stm32f401blackpill/board.h @@ -93,7 +93,7 @@ static inline void board_clock_init(void) static inline void board_vbus_sense_init(void) { - // Blackpill doens't use VBUS sense (B device) explicitly disable it + // Blackpill doesn't use VBUS sense (B device) explicitly disable it USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN; USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN; diff --git a/hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld index c41602720..aac6577ea 100644 --- a/hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld @@ -150,7 +150,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld index efea1e067..56dcea605 100644 --- a/hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f4/boards/stm32f411blackpill/board.h b/hw/bsp/stm32f4/boards/stm32f411blackpill/board.h index 0f820512c..e1fef7277 100644 --- a/hw/bsp/stm32f4/boards/stm32f411blackpill/board.h +++ b/hw/bsp/stm32f4/boards/stm32f411blackpill/board.h @@ -93,7 +93,7 @@ static inline void board_clock_init(void) static inline void board_vbus_sense_init(void) { - // Blackpill doens't use VBUS sense (B device) explicitly disable it + // Blackpill doesn't use VBUS sense (B device) explicitly disable it USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN; USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN; diff --git a/hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld index 3a0ce526f..4477229ea 100644 --- a/hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld index b00b5dbe0..2372cc1d9 100644 --- a/hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld index b00b5dbe0..2372cc1d9 100644 --- a/hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld b/hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld index 8645ce5c5..f4be85703 100644 --- a/hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld +++ b/hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld b/hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld index 8645ce5c5..f4be85703 100644 --- a/hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld +++ b/hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld b/hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld index 045ec76f9..eeb0e29f3 100644 --- a/hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld +++ b/hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld b/hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld index b434a01b7..e1e60bc78 100644 --- a/hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld +++ b/hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld b/hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld index 0b6d5a494..3785f9cbf 100644 --- a/hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld +++ b/hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld b/hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld index 378ed80dd..520a75539 100644 --- a/hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld +++ b/hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h index eab0bd5f0..aa2bf20bb 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h @@ -66,7 +66,7 @@ static inline void board_clock_init(void) // Configure the main internal regulator output voltage HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); - // Initializes the CPU, AHB and APB busses clocks + // Initializes the CPU, AHB and APB buses clocks RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; @@ -79,7 +79,7 @@ static inline void board_clock_init(void) RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); - // Initializes the CPU, AHB and APB busses clocks + // Initializes the CPU, AHB and APB buses clocks RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/stm32h743xx_flash.ld b/hw/bsp/stm32h7/boards/stm32h743eval/stm32h743xx_flash.ld index 59b9ff4df..7ee40671c 100644 --- a/hw/bsp/stm32h7/boards/stm32h743eval/stm32h743xx_flash.ld +++ b/hw/bsp/stm32h7/boards/stm32h743eval/stm32h743xx_flash.ld @@ -134,7 +134,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32h7/boards/stm32h743nucleo/stm32h743xx_flash.ld b/hw/bsp/stm32h7/boards/stm32h743nucleo/stm32h743xx_flash.ld index 59b9ff4df..7ee40671c 100644 --- a/hw/bsp/stm32h7/boards/stm32h743nucleo/stm32h743xx_flash.ld +++ b/hw/bsp/stm32h7/boards/stm32h743nucleo/stm32h743xx_flash.ld @@ -134,7 +134,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32h7/boards/waveshare_openh743i/STM32H743IITX_FLASH.ld b/hw/bsp/stm32h7/boards/waveshare_openh743i/STM32H743IITX_FLASH.ld index 73d2dedb2..e99bb977b 100644 --- a/hw/bsp/stm32h7/boards/waveshare_openh743i/STM32H743IITX_FLASH.ld +++ b/hw/bsp/stm32h7/boards/waveshare_openh743i/STM32H743IITX_FLASH.ld @@ -138,7 +138,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h b/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h index 09442c233..2b072e07c 100644 --- a/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h +++ b/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h @@ -186,7 +186,7 @@ static inline void timer_board_delay(TIM_HandleTypeDef* tim_hdl, uint32_t ms) static inline void board_stm32h7_post_init(void) { - // walkaround for reseting the ULPI PHY using Timer since systick is not + // walkaround for resetting the ULPI PHY using Timer since systick is not // available when RTOS is used. // Init timer diff --git a/hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld b/hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld index 1bc16cc7b..dfefe59f1 100644 --- a/hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld +++ b/hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld b/hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld index 787418e09..79427d80b 100644 --- a/hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld +++ b/hw/bsp/stm32l0538disco/STM32L053C8Tx_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld b/hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld index 98f468ac0..d6865f49d 100644 --- a/hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld +++ b/hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld @@ -144,7 +144,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld b/hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld index f93a16041..f77c72d1b 100644 --- a/hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld +++ b/hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld @@ -130,7 +130,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h index f42c7d6dd..ea975df03 100644 --- a/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h +++ b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h @@ -59,7 +59,7 @@ static inline void board_clock_init(void) RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; - // Initializes the CPU, AHB and APB busses clocks + // Initializes the CPU, AHB and APB buses clocks RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; @@ -72,7 +72,7 @@ static inline void board_clock_init(void) RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV3; HAL_RCC_OscConfig(&RCC_OscInitStruct); - // Initializes the CPU, AHB and APB busses clocks + // Initializes the CPU, AHB and APB buses clocks RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c123/family.c index b0947d6c4..87b94289b 100644 --- a/hw/bsp/tm4c123/family.c +++ b/hw/bsp/tm4c123/family.c @@ -39,7 +39,7 @@ static void board_uart_init (void) UART0->LCRH = (0x3 << 5); // 8-bit, no parity, 1 stop bit UART0->CC = 0x0; // Configure the UART clock source as system clock - UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Recieve Enable + UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Receive Enable } static void initialize_board_led (GPIOA_Type *port, uint8_t PinMsk, uint8_t dirmsk) diff --git a/lib/SEGGER_RTT/RTT/SEGGER_RTT.c b/lib/SEGGER_RTT/RTT/SEGGER_RTT.c index 3ad2b1a12..a7ae013dd 100644 --- a/lib/SEGGER_RTT/RTT/SEGGER_RTT.c +++ b/lib/SEGGER_RTT/RTT/SEGGER_RTT.c @@ -1404,7 +1404,7 @@ int SEGGER_RTT_GetKey(void) { * SEGGER_RTT_WaitKey * * Function description -* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Waits until at least one character is available in the SEGGER RTT buffer. * Once a character is available, it is read and this function returns. * * Return value diff --git a/lib/networking/dnserver.c b/lib/networking/dnserver.c index e4e7c3492..539cc2cea 100644 --- a/lib/networking/dnserver.c +++ b/lib/networking/dnserver.c @@ -93,11 +93,11 @@ static uint16_t get_uint16(const uint8_t *pnt) static int parse_next_query(void *data, int size, dns_query_t *query) { int len; - int lables; + int labels; uint8_t *ptr; len = 0; - lables = 0; + labels = 0; ptr = (uint8_t *)data; while (true) @@ -107,7 +107,7 @@ static int parse_next_query(void *data, int size, dns_query_t *query) lable_len = *ptr++; size--; if (lable_len == 0) break; - if (lables > 0) + if (labels > 0) { if (len == DNS_MAX_HOST_NAME_LEN) return -2; query->name[len++] = '.'; @@ -118,7 +118,7 @@ static int parse_next_query(void *data, int size, dns_query_t *query) len += lable_len; ptr += lable_len; size -= lable_len; - lables++; + labels++; } if (size < 4) return -1; diff --git a/lib/networking/ndis.h b/lib/networking/ndis.h index 1c737574c..06258e6bb 100644 --- a/lib/networking/ndis.h +++ b/lib/networking/ndis.h @@ -22,7 +22,7 @@ * ntddndis.h modified by Benedikt Spranger * * Thanks to the cygwin development team, - * espacially to Casper S. Hornstrup + * especially to Casper S. Hornstrup * * THIS SOFTWARE IS NOT COPYRIGHTED * diff --git a/lib/networking/rndis_reports.c b/lib/networking/rndis_reports.c index ee611c883..d129466c8 100644 --- a/lib/networking/rndis_reports.c +++ b/lib/networking/rndis_reports.c @@ -220,7 +220,7 @@ static void rndis_handle_set_msg(void) case OID_802_3_MULTICAST_LIST: break; - /* Power Managment: fails for now */ + /* Power Management: fails for now */ case OID_PNP_ADD_WAKE_UP_PATTERN: case OID_PNP_REMOVE_WAKE_UP_PATTERN: case OID_PNP_ENABLE_WAKE_UP: diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index e345139ea..c428af865 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -193,7 +193,7 @@ typedef enum }cdc_management_request_t; //--------------------------------------------------------------------+ -// Management Elemenent Notification (Notification Endpoint) +// Management Element Notification (Notification Endpoint) //--------------------------------------------------------------------+ /// 6.3 Notification Codes diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c index 8f28f51ac..44de85b45 100644 --- a/src/class/cdc/cdc_rndis_host.c +++ b/src/class/cdc/cdc_rndis_host.c @@ -117,7 +117,7 @@ void rndish_init(void) //------------- Task creation -------------// - //------------- semaphore creation for notificaiton pipe -------------// + //------------- semaphore creation for notification pipe -------------// for(uint8_t i=0; iMSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RMWAKEUP; - // Atleast 2 ms of delay needed for RESUME Data K state. + // At least 2 ms of delay needed for RESUME Data K state. delayms(2); SYS->MSC0CFG &= ~MASK_SYS_MSC0CFG_DEV_RMWAKEUP; @@ -720,7 +720,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) else total_ram = USBD_RAMTOTAL_OUT; // Work out how much has been allocated to existing endpoints. - // The total RAM allocated shoudl alsyes be a positive number as this + // The total RAM allocated should always be a positive number as this // algorithm should not let it go below zero. for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) { @@ -976,7 +976,7 @@ void dcd_int_handler(uint8_t rhport) USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL; } - // Host has sent a SETUP packet. Recieve this into the setup packet store. + // Host has sent a SETUP packet. Receive this into the setup packet store. _ft90x_dusb_out(USBD_EP_0, (uint8_t *)_ft90x_setup_packet, sizeof(USB_device_request)); // Send the packet to tinyusb. diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 76ba2a921..80f616478 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -199,7 +199,7 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) #pragma GCC diagnostic pop if ( qhd->dev_addr == dev_addr ) { - // TODO deactive all TD, wait for QHD to inactive before removal + // TODO deactivate all TD, wait for QHD to inactive before removal prev->address = qhd->next.address; // EHCI 4.8.2 link the removed qhd to async head (which always reachable by Host Controller) @@ -839,7 +839,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c if (TUSB_SPEED_HIGH == p_qhd->ep_speed) { TU_ASSERT( interval <= 16, ); - if ( interval < 4) // sub milisecond interval + if ( interval < 4) // sub millisecond interval { p_qhd->interval_ms = 0; p_qhd->int_smask = (interval == 1) ? TU_BIN8(11111111) : diff --git a/src/portable/ehci/ehci.h b/src/portable/ehci/ehci.h index ff9ae12e7..36f8649be 100644 --- a/src/portable/ehci/ehci.h +++ b/src/portable/ehci/ehci.h @@ -114,7 +114,7 @@ typedef struct volatile uint32_t current_page : 3 ; ///< Index into the qTD buffer pointer list uint32_t int_on_complete : 1 ; ///< Interrupt on complete volatile uint32_t total_bytes : 15 ; ///< Transfer bytes, decreased during transaction - volatile uint32_t data_toggle : 1 ; ///< Data Toogle bit + volatile uint32_t data_toggle : 1 ; ///< Data Toggle bit /// Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page @@ -160,7 +160,7 @@ typedef struct TU_ATTR_ALIGNED(32) uint8_t used; uint8_t removing; // removed from asyn list, waiting for async advance uint8_t pid; - uint8_t interval_ms; // polling interval in frames (or milisecond) + uint8_t interval_ms; // polling interval in frames (or millisecond) uint16_t total_xferred_bytes; // number of bytes xferred until a qtd with ioc bit set uint8_t reserved2[2]; @@ -225,7 +225,7 @@ typedef struct TU_ATTR_ALIGNED(32) uint16_t reserved ; ///< reserved // Word 3: siTD Transfer Status and Control - // Status [7:0] TODO indentical to qTD Token'status --> refractor later + // Status [7:0] TODO identical to qTD Token'status --> refactor later volatile uint32_t : 1 ; // reserved volatile uint32_t split_state : 1 ; volatile uint32_t missed_uframe : 1 ; @@ -350,8 +350,8 @@ typedef volatile struct uint32_t periodic_status : 1 ; ///< Periodic schedule status uint32_t async_status : 1 ; ///< Async schedule status uint32_t : 2 ; - uint32_t nxp_int_async : 1 ; ///< NXP customized: This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set andthe TD was from the asynchronous schedule. This bit is also set by the Host when a short packet is detected andthe packet is on the asynchronous schedule. - uint32_t nxp_int_period : 1 ; ///< NXP customized: This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set andthe TD was from the periodic schedule. + uint32_t nxp_int_async : 1 ; ///< NXP customized: This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set and the TD was from the asynchronous schedule. This bit is also set by the Host when a short packet is detected and the packet is on the asynchronous schedule. + uint32_t nxp_int_period : 1 ; ///< NXP customized: This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set and the TD was from the periodic schedule. uint32_t : 12 ; }status_bm; }; diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index 0b75af627..41240f737 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -741,7 +741,7 @@ static void handle_epin_ints(void) // XFER Timeout if (USB0.in_ep_reg[n].diepint & USB_D_TIMEOUT0_M) { - // Clear interrupt or enpoint will hang. + // Clear interrupt or endpoint will hang. USB0.in_ep_reg[n].diepint = USB_D_TIMEOUT0_M; // Maybe retry? } diff --git a/src/portable/microchip/pic32mz/usbhs_registers.h b/src/portable/microchip/pic32mz/usbhs_registers.h index 757e3f083..93b552322 100644 --- a/src/portable/microchip/pic32mz/usbhs_registers.h +++ b/src/portable/microchip/pic32mz/usbhs_registers.h @@ -21,16 +21,16 @@ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. *******************************************************************************/ /******************************************************************************* - USBHS Peripheral Library Register Defintions + USBHS Peripheral Library Register Definitions File Name: usbhs_registers.h Summary: - USBHS PLIB Register Defintions + USBHS PLIB Register Definitions Description: - This file contains the constants and defintions which are required by the + This file contains the constants and definitions which are required by the the USBHS library. *******************************************************************************/ diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 7507c0f69..24657872b 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -42,7 +42,7 @@ # define USE_SOF 0 #endif -// Dual bank can imporve performance, but need 2 times bigger packet buffer +// Dual bank can improve performance, but need 2 times bigger packet buffer // As SAM7x has only 4KB packet buffer, use with caution ! // Enable in FS mode as packets are smaller #ifndef USE_DUAL_BANK @@ -644,7 +644,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t } __set_PRIMASK(irq_state); - // Here a ZLP has been recieved + // Here a ZLP has been received // and the DMA transfer must be not started. // It is the end of transfer return false; @@ -734,7 +734,7 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 } __set_PRIMASK(irq_state); - // Here a ZLP has been recieved + // Here a ZLP has been received // and the DMA transfer must be not started. // It is the end of transfer return false; diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c index 886720e33..3fa7c1ec1 100644 --- a/src/portable/nuvoton/nuc505/dcd_nuc505.c +++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c @@ -181,7 +181,7 @@ static void dcd_userEP_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) ep->EPINTEN = USBD_EPINTEN_TXPKIEN_Msk; } - /* provided buffers are thankfully 32-bit aligned, allowing most data to be transfered as 32-bit */ + /* provided buffers are thankfully 32-bit aligned, allowing most data to be transferred as 32-bit */ #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 3e523ebc2..228da6ae0 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -165,7 +165,7 @@ bool hcd_init(uint8_t rhport) //------------- Data Structure init -------------// tu_memclr(&ohci_data, sizeof(ohci_data_t)); for(uint8_t i=0; i<32; i++) - { // assign all interrupt pointes to period head ed + { // assign all interrupt pointers to period head ed ohci_data.hcca.interrupt_table[i] = (uint32_t) &ohci_data.period_head_ed; } diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index 9fc954c8f..f40ae24cc 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -34,7 +34,7 @@ //--------------------------------------------------------------------+ // OHCI CONFIGURATION & CONSTANTS //--------------------------------------------------------------------+ -#define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enalbed +#define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enabled #define OHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS) // TODO merge OHCI with EHCI diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index c88a8a3a2..54c3c95e7 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -122,7 +122,7 @@ (TU_CHECK_MCU(OPT_MCU_STM32L4) && defined(STM32L4_FSDEV)) \ ) -// In order to reduce the dependance on HAL, we undefine this. +// In order to reduce the dependence on HAL, we undefine this. // Some definitions are copied to our private include file. #undef USE_HAL_DRIVER diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index a0be846a5..2d0e379ad 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -243,7 +243,7 @@ static void USBC_Dev_SetAddress(u8 address) static void __USBC_Dev_Tx_SendStall(void) { - //send stall, and fifo is flushed automaticly + //send stall, and fifo is flushed automatically USBC_REG_set_bit_w(USBC_BP_TXCSR_D_SEND_STALL, USBC_REG_TXCSR(USBC0_BASE)); } static u32 __USBC_Dev_Tx_IsEpStall(void) diff --git a/src/portable/sunxi/musb_def.h b/src/portable/sunxi/musb_def.h index 602b4f113..53da5ded2 100644 --- a/src/portable/sunxi/musb_def.h +++ b/src/portable/sunxi/musb_def.h @@ -93,7 +93,7 @@ #define USBC1_BASE 0x01c14000 #define USBC2_BASE 0x01c1E000 -//Some reg whithin musb +//Some reg within musb #define USBPHY_CLK_REG 0x01c200CC #define USBPHY_CLK_RST_BIT 0 #define USBPHY_CLK_GAT_BIT 1 diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index f5ecdfe4f..b53735a5e 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1003,7 +1003,7 @@ static void handle_rxflvl_irq(uint8_t rhport) switch ( pktsts ) { - // Global OUT NAK: do nothign + // Global OUT NAK: do nothing case GRXSTS_PKTSTS_GLOBALOUTNAK: break; case GRXSTS_PKTSTS_SETUPRX: diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index ea786362e..b63d1fcd0 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -116,7 +116,7 @@ static const dwc2_controller_t _dwc2_controller[] = // //--------------------------------------------------------------------+ -// SystemCoreClock is alrady included by family header +// SystemCoreClock is already included by family header // extern uint32_t SystemCoreClock; TU_ATTR_ALWAYS_INLINE -- cgit v1.3.1 From 43b255f413e08b9e567a23b24701efbdaebcb824 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 4 Dec 2022 18:51:52 +0700 Subject: more typos --- docs/contributing/index.rst | 2 +- examples/device/hid_generic_inout/hid_test.py | 4 ++-- hw/bsp/gd32vf103/family.c | 2 +- hw/bsp/sltb009a/sltb009a.c | 2 +- hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld | 4 ++-- hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld | 2 +- hw/bsp/stm32u5/boards/stm32u575eval/board.h | 4 ++-- src/class/hid/hid_device.h | 2 +- src/class/usbtmc/usbtmc_device.c | 2 +- src/portable/dialog/da146xx/dcd_da146xx.c | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 2 +- src/portable/renesas/usba/hcd_usba.c | 2 +- src/portable/valentyusb/eptri/dcd_eptri.c | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/docs/contributing/index.rst b/docs/contributing/index.rst index c572894ad..7ff79cb32 100644 --- a/docs/contributing/index.rst +++ b/docs/contributing/index.rst @@ -6,7 +6,7 @@ Contributing can be highly rewarding, but it can also be frustrating at times. It takes time to review patches, and as this is an open source project, that sometimes can take a while. The reviewing process depends on the availability of the maintainers, who may not be always available. Please try to be -understanding throught the process. +understanding through the process. There a few guidelines you need to keep in mind when contributing. Please have a look at them as that will make the contribution process easier for all diff --git a/examples/device/hid_generic_inout/hid_test.py b/examples/device/hid_generic_inout/hid_test.py index 21fd3f421..5bdba9db0 100644 --- a/examples/device/hid_generic_inout/hid_test.py +++ b/examples/device/hid_generic_inout/hid_test.py @@ -13,8 +13,8 @@ for vid in USB_VID: if dev: while True: # Get input from console and encode to UTF8 for array of chars. - # hid generic inout is single report therefore by HIDAPI requirement - # it must be preceeded with 0x00 as dummy reportID + # hid generic in/out is single report therefore by HIDAPI requirement + # it must be preceded, with 0x00 as dummy reportID str_out = b'\x00' str_out += input("Send text to HID Device : ").encode('utf-8') dev.write(str_out) diff --git a/hw/bsp/gd32vf103/family.c b/hw/bsp/gd32vf103/family.c index 5427c8dd0..60a326d27 100644 --- a/hw/bsp/gd32vf103/family.c +++ b/hw/bsp/gd32vf103/family.c @@ -112,7 +112,7 @@ void board_init(void) { otg_core_regs->GCCFG &= ~GCCFG_VBUSIG; #endif - /* Enable interrupts globaly */ + /* Enable interrupts globally */ __enable_irq(); } diff --git a/hw/bsp/sltb009a/sltb009a.c b/hw/bsp/sltb009a/sltb009a.c index b929adb13..b5eb5ed5d 100644 --- a/hw/bsp/sltb009a/sltb009a.c +++ b/hw/bsp/sltb009a/sltb009a.c @@ -397,7 +397,7 @@ void cmu_init(void) CMU->HFCLKSEL = CMU_HFCLKSEL_HF_HFXO; while((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) != CMU_HFCLKSTATUS_SELECTED_HFXO); - // Calibrate HFRCO for 72MHz and enable tunning by PLL + // Calibrate HFRCO for 72MHz and enable tuning by PLL cmu_hfrco_calib((DEVINFO->HFRCOCAL16) | CMU_HFRCOCTRL_FINETUNINGEN); // Setup the PLL diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld b/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld index 935d97c87..9c327483b 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld @@ -16,7 +16,7 @@ ** ** Target : STMicroelectronics STM32 ** -** Distribution: The file is distributed as is, without any warranty +** Distribution: The file is distributed �as is,� without any warranty ** of any kind. ** ***************************************************************************** @@ -151,7 +151,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld b/hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld index 28cd96131..d4b86b3e3 100644 --- a/hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld +++ b/hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld @@ -145,7 +145,7 @@ SECTIONS . = ALIGN(4); .bss : { - /* This is used by the startup in order to initialize the .bss secion */ + /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.h b/hw/bsp/stm32u5/boards/stm32u575eval/board.h index 5c348b812..5562b95a8 100644 --- a/hw/bsp/stm32u5/boards/stm32u575eval/board.h +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.h @@ -69,7 +69,7 @@ static inline void board_clock_init(void) */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); - /** Initializes the CPU, AHB and APB busses clocks + /** Initializes the CPU, AHB and APB buses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; @@ -92,7 +92,7 @@ static inline void board_clock_init(void) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); - /** Initializes the CPU, AHB and APB busses clocks + /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 3143b1024..fa41ebf8a 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -182,7 +182,7 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */\ __VA_ARGS__ \ - /* 8 bits Modifier Keys (Shfit, Control, Alt) */ \ + /* 8 bits Modifier Keys (Shift, Control, Alt) */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\ HID_USAGE_MIN ( 224 ) ,\ HID_USAGE_MAX ( 231 ) ,\ diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index af4a92732..0f6d3f60d 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -599,7 +599,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request // At this point, a transfer MAY be in progress. Based on USB spec, when clearing bulk EP HALT, // the EP transfer buffer needs to be cleared and DTOG needs to be reset, even if - // the EP is not halted. The only USBD API interface to do this is to stall and then unstall the EP. + // the EP is not halted. The only USBD API interface to do this is to stall and then un-stall the EP. if(ep_addr == usbtmc_state.ep_bulk_out) { criticalEnter(); diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 0bb8b6e41..961da81d6 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -243,7 +243,7 @@ static struct // Converts xfer pointer to epnum (0,1,2,3) regardless of xfer direction #define XFER_EPNUM(xfer) ((xfer - &_dcd.xfer_status[0][0]) >> 1) -// Converts xfer pinter to EPx_REGS pointer (returns same pointer for IN and OUT with same endpoint number) +// Converts xfer pointer to EPx_REGS pointer (returns same pointer for IN and OUT with same endpoint number) #define XFER_REGS(xfer) ep_regs[XFER_EPNUM(xfer)] // Converts epnum (0,1,2,3) to EPx_REGS pointer #define EPNUM_REGS(epnum) ep_regs[epnum] diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index ca37d799f..afc14b010 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -170,7 +170,7 @@ static void xact_out_dma(uint8_t epnum) uint32_t xact_len; // DMA can't be active during read of SIZE.EPOUT or SIZE.ISOOUT, so try to lock, - // If already running deffer call regardless if it was called from ISR or task, + // If already running defer call regardless if it was called from ISR or task, if ( atomic_flag_test_and_set(&_dcd.dma_running) ) { usbd_defer_func((osal_task_func_t)xact_out_dma_wrapper, (void *)(uint32_t)epnum, is_in_isr()); diff --git a/src/portable/renesas/usba/hcd_usba.c b/src/portable/renesas/usba/hcd_usba.c index 5246ecb94..18cd5f148 100644 --- a/src/portable/renesas/usba/hcd_usba.c +++ b/src/portable/renesas/usba/hcd_usba.c @@ -600,7 +600,7 @@ uint32_t hcd_frame_number(uint8_t rhport) bool hcd_port_connect_status(uint8_t rhport) { (void)rhport; - return USB0.INTSTS1.BIT.ATTCH ? true: false; + return USB0.INTSTS1.BIT.ATTCH ? true : false; } void hcd_port_reset(uint8_t rhport) diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index e368b5f39..a3f228dd9 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -465,7 +465,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) enable = 1; usb_out_ctrl_write((0 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr)); } - // IN endpoints will get unstalled when more data is written. + // IN endpoints will get un-stalled when more data is written. } bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) -- cgit v1.3.1 From de5a67bf3b8737a580539c5fbc6a054c90e4a084 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 5 Dec 2022 12:09:41 +0700 Subject: clean osal_freertos, update freertos examples to work with configSUPPORT_DYNAMIC_ALLOCATION only note: for example to build with configSUPPORT_STATIC_ALLOCATION = 0, one of heap_n.c must be included in makefile/cmake --- examples/device/cdc_msc_freertos/Makefile | 11 ++- .../src/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- examples/device/cdc_msc_freertos/src/main.c | 24 ++++--- examples/device/hid_composite_freertos/Makefile | 11 ++- .../src/FreeRTOSConfig/FreeRTOSConfig.h | 7 +- examples/device/hid_composite_freertos/src/main.c | 24 ++++--- src/osal/osal_freertos.h | 84 +++++++++++----------- src/portable/ehci/ehci.c | 2 +- 8 files changed, 100 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/examples/device/cdc_msc_freertos/Makefile b/examples/device/cdc_msc_freertos/Makefile index 3352dd37d..ff4b41108 100644 --- a/examples/device/cdc_msc_freertos/Makefile +++ b/examples/device/cdc_msc_freertos/Makefile @@ -29,8 +29,15 @@ SRC_C += \ $(FREERTOS_SRC)/timers.c \ $(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c)) -# Suppress FreeRTOS warnings -CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls +# include heap manage if configSUPPORT_DYNAMIC_ALLOCATION = 1 +# SRC_C += $(FREERTOS_SRC)/portable/MemMang/heap_1.c +# CFLAGS += -Wno-error=sign-compare + +# Suppress FreeRTOSConfig.h warnings +CFLAGS += -Wno-error=redundant-decls + +# Suppress FreeRTOS source warnings +CFLAGS += -Wno-error=cast-qual # FreeRTOS (lto + Os) linker issue LDFLAGS += -Wl,--undefined=vTaskSwitchContext diff --git a/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index 6a3630dbc..968c59749 100644 --- a/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -69,7 +69,7 @@ #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( 0*1024 ) // dynamic is not used +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 755220c13..cfb14aa2b 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -51,6 +51,8 @@ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif +#define CDC_STACK_SZIE configMINIMAL_STACK_SIZE + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ @@ -66,19 +68,18 @@ enum { BLINK_SUSPENDED = 2500, }; -// static timer +// static timer & task +#if configSUPPORT_STATIC_ALLOCATION StaticTimer_t blinky_tmdef; -TimerHandle_t blinky_tm; -// static task StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; -// static task for cdc -#define CDC_STACK_SZIE configMINIMAL_STACK_SIZE StackType_t cdc_stack[CDC_STACK_SZIE]; StaticTask_t cdc_taskdef; +#endif +TimerHandle_t blinky_tm; void led_blinky_cb(TimerHandle_t xTimer); void usb_device_task(void* param); @@ -92,15 +93,22 @@ int main(void) { board_init(); +#if configSUPPORT_STATIC_ALLOCATION // soft timer for blinky blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); - xTimerStart(blinky_tm, 0); // Create a task for tinyusb device stack - (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); // Create CDC task - (void) xTaskCreateStatic( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); + xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); +#else + blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); + xTaskCreate( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); + xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); +#endif + + xTimerStart(blinky_tm, 0); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) diff --git a/examples/device/hid_composite_freertos/Makefile b/examples/device/hid_composite_freertos/Makefile index 6c8c43ddd..9c66b896d 100644 --- a/examples/device/hid_composite_freertos/Makefile +++ b/examples/device/hid_composite_freertos/Makefile @@ -28,8 +28,15 @@ SRC_C += \ $(FREERTOS_SRC)/timers.c \ $(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c)) -# Suppress FreeRTOS warnings -CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls +# include heap manage if configSUPPORT_DYNAMIC_ALLOCATION = 1 +# SRC_C += $(FREERTOS_SRC)/portable/MemMang/heap_1.c +# CFLAGS += -Wno-error=sign-compare + +# Suppress FreeRTOSConfig.h warnings +CFLAGS += -Wno-error=redundant-decls + +# Suppress FreeRTOS source warnings +CFLAGS += -Wno-error=cast-qual # FreeRTOS (lto + Os) linker issue LDFLAGS += -Wl,--undefined=vTaskSwitchContext diff --git a/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index bfdf1e926..968c59749 100644 --- a/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -46,13 +46,14 @@ #include "bsp/board_mcu.h" #if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 -#error "ESP32-Sx should use IDF's FreeRTOSConfig.h" + #error "ESP32-Sx should use IDF's FreeRTOSConfig.h" #endif +// TODO fix later #if CFG_TUSB_MCU == OPT_MCU_MM32F327X - // TODO fix/remove later extern u32 SystemCoreClock; #else + // FIXME cause redundant-decls warnings extern uint32_t SystemCoreClock; #endif @@ -68,7 +69,7 @@ #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( 0*1024 ) // dynamic is not used +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index b67c10937..fb0d69258 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -53,6 +53,8 @@ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif +#define HID_STACK_SZIE configMINIMAL_STACK_SIZE + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ @@ -68,19 +70,18 @@ enum { BLINK_SUSPENDED = 2500, }; -// static timer +// static timer & task +#if configSUPPORT_STATIC_ALLOCATION StaticTimer_t blinky_tmdef; -TimerHandle_t blinky_tm; -// static task StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; -// static task for hid -#define HID_STACK_SZIE configMINIMAL_STACK_SIZE StackType_t hid_stack[HID_STACK_SZIE]; StaticTask_t hid_taskdef; +#endif +TimerHandle_t blinky_tm; void led_blinky_cb(TimerHandle_t xTimer); void usb_device_task(void* param); @@ -94,15 +95,22 @@ int main(void) { board_init(); +#if configSUPPORT_STATIC_ALLOCATION // soft timer for blinky blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); - xTimerStart(blinky_tm, 0); // Create a task for tinyusb device stack - (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); // Create HID task - (void) xTaskCreateStatic( hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, hid_stack, &hid_taskdef); + xTaskCreateStatic(hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, hid_stack, &hid_taskdef); +#else + blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); + xTaskCreate(hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); +#endif + + xTimerStart(blinky_tm, 0); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index ccb98cc99..327aa9970 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -37,6 +37,43 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +#if configSUPPORT_STATIC_ALLOCATION + typedef StaticSemaphore_t osal_semaphore_def_t; + typedef StaticSemaphore_t osal_mutex_def_t; +#else + // not used therefore defined to smallest possible type to save space + typedef uint8_t osal_semaphore_def_t; + typedef uint8_t osal_mutex_def_t; +#endif + +typedef SemaphoreHandle_t osal_semaphore_t; +typedef SemaphoreHandle_t osal_mutex_t; + +// _int_set is not used with an RTOS +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ + static _type _name##_##buf[_depth];\ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; +#if configSUPPORT_STATIC_ALLOCATION + StaticQueue_t sq; +#endif +}osal_queue_def_t; + +typedef QueueHandle_t osal_queue_t; + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ + TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) { if (msec == OSAL_TIMEOUT_WAIT_FOREVER) return portMAX_DELAY; @@ -51,9 +88,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) return ticks; } -//--------------------------------------------------------------------+ -// TASK API -//--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { vTaskDelay( pdMS_TO_TICKS(msec) ); @@ -62,19 +96,13 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ -#if configSUPPORT_STATIC_ALLOCATION == 1 -typedef StaticSemaphore_t osal_semaphore_def_t; -#else -typedef SemaphoreHandle_t osal_semaphore_def_t; -#endif -typedef SemaphoreHandle_t osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { -#if configSUPPORT_STATIC_ALLOCATION == 1 +#if configSUPPORT_STATIC_ALLOCATION return xSemaphoreCreateBinaryStatic(semdef); #else - (void)(semdef); + (void) semdef; return xSemaphoreCreateBinary(); #endif } @@ -101,7 +129,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t se } } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return xSemaphoreTake(sem_hdl, _osal_ms2tick(msec)); } @@ -114,25 +142,18 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t c //--------------------------------------------------------------------+ // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ -#if configSUPPORT_STATIC_ALLOCATION == 1 -typedef StaticSemaphore_t osal_mutex_def_t; -#else -typedef SemaphoreHandle_t osal_mutex_def_t; -#endif -typedef SemaphoreHandle_t osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { -#if configSUPPORT_STATIC_ALLOCATION == 1 +#if configSUPPORT_STATIC_ALLOCATION return xSemaphoreCreateMutexStatic(mdef); #else - (void)(mdef); + (void) mdef; return xSemaphoreCreateMutex(); #endif - } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } @@ -146,26 +167,9 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd // QUEUE API //--------------------------------------------------------------------+ -// _int_set is not used with an RTOS -#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ - static _type _name##_##buf[_depth];\ - osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; - -typedef struct -{ - uint16_t depth; - uint16_t item_sz; - void* buf; -#if configSUPPORT_STATIC_ALLOCATION == 1 - StaticQueue_t sq; -#endif -}osal_queue_def_t; - -typedef QueueHandle_t osal_queue_t; - TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { -#if configSUPPORT_STATIC_ALLOCATION == 1 +#if configSUPPORT_STATIC_ALLOCATION return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); #else return xQueueCreate(qdef->depth, qdef->item_sz); diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 361015964..76ba2a921 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -193,7 +193,7 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) { // TODO check type for ISO iTD and siTD // TODO Suppress cast-align warning - #pragma GCC diagnostic push + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" ehci_qhd_t* qhd = (ehci_qhd_t*) list_next(prev); #pragma GCC diagnostic pop -- cgit v1.3.1 From d58120647aef366de7a57e40b2572da03efdb415 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 5 Dec 2022 13:18:05 +0700 Subject: rename to match fido sample uf2_hid..h --- src/class/hid/hid.h | 8 ++++---- src/class/hid/hid_device.h | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 296664f62..d9b0ead10 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -708,7 +708,7 @@ enum { HID_USAGE_PAGE_MSR = 0x8e, HID_USAGE_PAGE_CAMERA = 0x90, HID_USAGE_PAGE_ARCADE = 0x91, - HID_USAGE_PAGE_FIDO_ALLIANCE = 0xF1D0, + HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; @@ -848,9 +848,9 @@ enum /// HID Usage Table: FIDO Alliance Page (0xF1D0) enum { - HID_USAGE_FIDO_U2F_AUTHENTICATOR_DEVICE = 0x01, - HID_USAGE_FIDO_INPUT_REPORT_DATA = 0x20, - HID_USAGE_FIDO_OUTPUT_REPORT_DATA = 0x21 + 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 a9f47d644..025394126 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -356,20 +356,20 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y // - 1st parameter is report size, which is 64 bytes maximum in U2F // - 2nd parameter is HID_REPORT_ID(n) (optional) #define TUD_HID_REPORT_DESC_FIDO_U2F(report_size, ...) \ - HID_USAGE_PAGE_N ( HID_USAGE_PAGE_FIDO_ALLIANCE, 2 ) ,\ - HID_USAGE ( HID_USAGE_FIDO_U2F_AUTHENTICATOR_DEVICE ) ,\ - HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + HID_USAGE_PAGE_N ( HID_USAGE_PAGE_FIDO, 2 ) ,\ + HID_USAGE ( HID_USAGE_FIDO_U2FHID ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */ \ __VA_ARGS__ \ /* Usage Data In */ \ - HID_USAGE ( HID_USAGE_FIDO_INPUT_REPORT_DATA ) ,\ + HID_USAGE ( HID_USAGE_FIDO_DATA_IN ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX_N ( 0xff, 2 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_REPORT_COUNT ( report_size ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* Usage Data Out */ \ - HID_USAGE ( HID_USAGE_FIDO_OUTPUT_REPORT_DATA ) ,\ + HID_USAGE ( HID_USAGE_FIDO_DATA_OUT ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX_N ( 0xff, 2 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ -- cgit v1.3.1 From 603effbb77ab587bae9800993a53599a9dbff97e Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Thu, 2 Jun 2022 13:22:53 +0200 Subject: cdc: Fix autoflush for FIFO < MPS --- src/class/cdc/cdc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index fab6f0035..77c73030a 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -171,7 +171,7 @@ 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) bufsize); // flush if queue more than packet size - if ( tu_fifo_count(&p_cdc->tx_ff) >= 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)) ) { tud_cdc_n_write_flush(itf); } -- cgit v1.3.1 From 19400c8556ce4bf5e40653d0c87a9f07db0870a3 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Dec 2022 10:30:22 +0700 Subject: fix typo, add -Wno-error=unreachable-code for fuzz due to latest cdc changes --- fuzz/device/net/src/fuzz.cc | 4 ++-- fuzz/make.mk | 1 + src/class/cdc/cdc_device.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/fuzz/device/net/src/fuzz.cc b/fuzz/device/net/src/fuzz.cc index 1013cf7f7..ea4943665 100644 --- a/fuzz/device/net/src/fuzz.cc +++ b/fuzz/device/net/src/fuzz.cc @@ -88,7 +88,7 @@ void net_task(FuzzedDataProvider *provider) { case kNetworkCanXmit: (void)tud_network_can_xmit(provider->ConsumeIntegral()); case kNetworkXmit: - // TODO: Actuall pass real values here later. + // TODO: Actually pass real values here later. tud_network_xmit(NULL, 0); case kMaxValue: @@ -96,4 +96,4 @@ void net_task(FuzzedDataProvider *provider) { break; } } -} \ No newline at end of file +} diff --git a/fuzz/make.mk b/fuzz/make.mk index 299d2c843..796ddc443 100644 --- a/fuzz/make.mk +++ b/fuzz/make.mk @@ -72,6 +72,7 @@ CFLAGS += \ -O1 CFLAGS += \ + -Wno-error=unreachable-code \ -DOPT_MCU_FUZZ=1 \ -DCFG_TUSB_MCU=OPT_MCU_FUZZ diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 77c73030a..7b1e08d5d 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -171,6 +171,7 @@ 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) bufsize); // 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)) ) { tud_cdc_n_write_flush(itf); -- cgit v1.3.1 From 3e32fa36b86c502a35341f7f1aba62b89dae8fcb Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Dec 2022 16:39:24 +0700 Subject: enhance tu fifo - rename wr/rd absolute to index, and rel to pointer. - fix crash with _tu_fifo_remaining() - change get_relative_pointer() to idx2ptr() and merge with _ff_mod() --- src/common/tusb_fifo.c | 205 +++++++++++++++++++++++++++++-------------------- src/common/tusb_fifo.h | 6 +- 2 files changed, 124 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index b857c6444..853614d28 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -34,6 +34,8 @@ #pragma diag_suppress = Pa082 #endif +#define TU_FIFO_DBG 0 + // implement mutex lock and unlock #if CFG_FIFO_MUTEX @@ -90,12 +92,9 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si return true; } -// Static functions are intended to work on local variables -static inline uint16_t _ff_mod(uint16_t idx, uint16_t depth) -{ - while ( idx >= depth) idx -= depth; - return idx; -} +//--------------------------------------------------------------------+ +// Pull & Push +//--------------------------------------------------------------------+ // Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address // Code adapted from dcd_synopsys.c @@ -179,7 +178,7 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t // Write data to linear part of buffer memcpy(ff_buf, app_buf, nLin_bytes); - // Write data wrapped around + TU_ASSERT(nWrap_bytes <= f->depth, ); memcpy(f->buffer, ((uint8_t const*) app_buf) + nLin_bytes, nWrap_bytes); } break; @@ -317,21 +316,24 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu } } +//--------------------------------------------------------------------+ +// Index (free-running and real buffer pointer) +//--------------------------------------------------------------------+ + // Advance an absolute pointer +// "absolute" index is only in the range of [0..2*depth) static uint16_t advance_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index - if ((p > (uint16_t)(p + offset)) || ((uint16_t)(p + offset) > f->max_pointer_idx)) - { - p = (uint16_t) ((p + offset) + f->non_used_index_space); - } - else + uint16_t next_p = (uint16_t) (p + offset); + if ( (p > next_p) || (next_p > f->max_pointer_idx) ) { - p += offset; + next_p = (uint16_t) (next_p + f->non_used_index_space); } - return p; + + return next_p; } // Backward an absolute pointer @@ -340,30 +342,33 @@ static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index - if ((p < (uint16_t)(p - offset)) || ((uint16_t)(p - offset) > f->max_pointer_idx)) - { - p = (uint16_t) ((p - offset) - f->non_used_index_space); - } - else + uint16_t new_p = (uint16_t) (p - offset); + if ( (p < new_p) || (new_p > f->max_pointer_idx) ) { - p -= offset; + new_p = (uint16_t) (new_p - f->non_used_index_space); } - return p; + + return new_p; } -// get relative from absolute pointer -static uint16_t get_relative_pointer(tu_fifo_t* f, uint16_t p) +// index to pointer, simply an modulo with minus +static inline uint16_t idx2ptr(uint16_t idx, uint16_t depth) { - return _ff_mod(p, f->depth); + while ( idx >= depth ) idx -= depth; + return idx; } // Works on local copies of w and r - return only the difference and as such can be used to determine an overflow -static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) +static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) { - uint16_t cnt = wAbs-rAbs; + uint16_t cnt = (uint16_t) (wr_idx-rd_idx); // In case we have non-power of two depth we need a further modification - if (rAbs > wAbs) cnt -= f->non_used_index_space; + if (rd_idx > wr_idx) + { + // 2*f->depth - (rd_idx - wr_idx); + cnt = (uint16_t) (cnt - f->non_used_index_space); + } return cnt; } @@ -400,39 +405,39 @@ static inline void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wAbs) // Works on local copies of w and r // Must be protected by mutexes since in case of an overflow read pointer gets modified -static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wAbs, uint16_t rAbs) +static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16_t rd_idx) { - uint16_t cnt = _tu_fifo_count(f, wAbs, rAbs); + uint16_t cnt = _tu_fifo_count(f, wr_idx, rd_idx); // Check overflow and correct if required if (cnt > f->depth) { - _tu_fifo_correct_read_pointer(f, wAbs); + _tu_fifo_correct_read_pointer(f, wr_idx); cnt = f->depth; } // Skip beginning of buffer if (cnt == 0) return false; - uint16_t rRel = get_relative_pointer(f, rAbs); + uint16_t rd_ptr = idx2ptr(rd_idx, f->depth); // Peek data - _ff_pull(f, p_buffer, rRel); + _ff_pull(f, p_buffer, rd_ptr); return true; } // Works on local copies of w and r // Must be protected by mutexes since in case of an overflow read pointer gets modified -static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wAbs, uint16_t rAbs, tu_fifo_copy_mode_t copy_mode) +static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, tu_fifo_copy_mode_t copy_mode) { - uint16_t cnt = _tu_fifo_count(f, wAbs, rAbs); + uint16_t cnt = _tu_fifo_count(f, wr_idx, rd_idx); // Check overflow and correct if required if (cnt > f->depth) { - _tu_fifo_correct_read_pointer(f, wAbs); - rAbs = f->rd_idx; + _tu_fifo_correct_read_pointer(f, wr_idx); + rd_idx = f->rd_idx; cnt = f->depth; } @@ -442,53 +447,80 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1 // Check if we can read something at and after offset - if too less is available we read what remains if (cnt < n) n = cnt; - uint16_t rRel = get_relative_pointer(f, rAbs); + uint16_t rd_ptr = idx2ptr(rd_idx, f->depth); // Peek data - _ff_pull_n(f, p_buffer, n, rRel, copy_mode); + _ff_pull_n(f, p_buffer, n, rd_ptr, copy_mode); return n; } // Works on local copies of w and r -static inline uint16_t _tu_fifo_remaining(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) +static inline uint16_t _tu_fifo_remaining(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) { - return f->depth - _tu_fifo_count(f, wAbs, rAbs); + uint16_t const count = _tu_fifo_count(f, wr_idx, rd_idx); + return (f->depth > count) ? (f->depth - count) : 0; } static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu_fifo_copy_mode_t copy_mode) { if ( n == 0 ) return 0; + TU_LOG(TU_FIFO_DBG, "rd = %u, wr = %02u, n = %u: ", f->rd_idx, f->wr_idx, n); + _ff_lock(f->mutex_wr); - uint16_t w = f->wr_idx, r = f->rd_idx; + uint16_t wr_idx = f->wr_idx; + uint16_t rd_idx = f->rd_idx; + uint8_t const* buf8 = (uint8_t const*) data; + uint16_t const remain = _tu_fifo_remaining(f, wr_idx, rd_idx); - if (!f->overwritable) + if ( n > remain) { - // Not overwritable limit up to full - n = tu_min16(n, _tu_fifo_remaining(f, w, r)); + if ( !f->overwritable ) + { + // limit up to full + n = remain; + } + else + { + // oldest data in fifo i.e read pointer data will be overwritten + // Note: we modify read data but we do not want to modify the read pointer within a write function! + // since it would end up in a race condition with read functions! + // Note2: race condition could still occur if tu_fifo_read() is called while we modify its buffer (corrupted data) + + if ( n >= f->depth ) + { + // Only copy last part + buf8 = buf8 + (n - f->depth) * f->item_size; + n = f->depth; + + // We start writing at the read pointer's position since we fill the complete + // buffer and we do not want to modify the read pointer within a write function! + // This would end up in a race condition with read functions! + wr_idx = rd_idx; + }else + { + // TODO shift out oldest data from read pointer !!! + } + } } - else if (n >= f->depth) + + if (n) { - // Only copy last part - buf8 = buf8 + (n - f->depth) * f->item_size; - n = f->depth; - - // We start writing at the read pointer's position since we fill the complete - // buffer and we do not want to modify the read pointer within a write function! - // This would end up in a race condition with read functions! - w = r; - } + uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); - uint16_t wRel = get_relative_pointer(f, w); + TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_rel = %u", n, wr_ptr); - // Write data - _ff_push_n(f, buf8, n, wRel, copy_mode); + // Write data + _ff_push_n(f, buf8, n, wr_ptr, copy_mode); - // Advance pointer - f->wr_idx = advance_pointer(f, w, n); + // Advance pointer + f->wr_idx = advance_pointer(f, wr_idx, n); + + TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\n", f->wr_idx); + } _ff_unlock(f->mutex_wr); @@ -742,20 +774,20 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data) _ff_lock(f->mutex_wr); bool ret; - uint16_t const w = f->wr_idx; + uint16_t const wr_idx = f->wr_idx; - if ( _tu_fifo_full(f, w, f->rd_idx) && !f->overwritable ) + if ( _tu_fifo_full(f, wr_idx, f->rd_idx) && !f->overwritable ) { ret = false; }else { - uint16_t wRel = get_relative_pointer(f, w); + uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); // Write data - _ff_push(f, data, wRel); + _ff_push(f, data, wr_ptr); // Advance pointer - f->wr_idx = advance_pointer(f, w, 1); + f->wr_idx = advance_pointer(f, wr_idx, 1); ret = true; } @@ -909,17 +941,19 @@ void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { // Operate on temporary values in case they change in between - uint16_t w = f->wr_idx, r = f->rd_idx; + uint16_t wr_idx = f->wr_idx; + uint16_t rd_idx = f->rd_idx; - uint16_t cnt = _tu_fifo_count(f, w, r); + uint16_t cnt = _tu_fifo_count(f, wr_idx, rd_idx); // Check overflow and correct if required - may happen in case a DMA wrote too fast if (cnt > f->depth) { _ff_lock(f->mutex_rd); - _tu_fifo_correct_read_pointer(f, w); + _tu_fifo_correct_read_pointer(f, wr_idx); _ff_unlock(f->mutex_rd); - r = f->rd_idx; + + rd_idx = f->rd_idx; cnt = f->depth; } @@ -934,22 +968,24 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) } // Get relative pointers - w = get_relative_pointer(f, w); - r = get_relative_pointer(f, r); + uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); + uint16_t rd_ptr = idx2ptr(rd_idx, f->depth); // Copy pointer to buffer to start reading from - info->ptr_lin = &f->buffer[r]; + info->ptr_lin = &f->buffer[rd_ptr]; // Check if there is a wrap around necessary - if (w > r) { + if (wr_ptr > rd_ptr) { // Non wrapping case info->len_lin = cnt; + info->len_wrap = 0; info->ptr_wrap = NULL; } else { - info->len_lin = f->depth - r; // Also the case if FIFO was full + info->len_lin = f->depth - rd_ptr; // Also the case if FIFO was full + info->len_wrap = cnt - info->len_lin; info->ptr_wrap = f->buffer; } @@ -972,10 +1008,11 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) /******************************************************************************/ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { - uint16_t w = f->wr_idx, r = f->rd_idx; - uint16_t free = _tu_fifo_remaining(f, w, r); + uint16_t wr_idx = f->wr_idx; + uint16_t rd_idx = f->rd_idx; + uint16_t remain = _tu_fifo_remaining(f, wr_idx, rd_idx); - if (free == 0) + if (remain == 0) { info->len_lin = 0; info->len_wrap = 0; @@ -985,23 +1022,23 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) } // Get relative pointers - w = get_relative_pointer(f, w); - r = get_relative_pointer(f, r); + uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); + uint16_t rd_ptr = idx2ptr(rd_idx, f->depth); // Copy pointer to buffer to start writing to - info->ptr_lin = &f->buffer[w]; + info->ptr_lin = &f->buffer[wr_ptr]; - if (w < r) + if (wr_ptr < rd_ptr) { // Non wrapping case - info->len_lin = r-w; + info->len_lin = rd_ptr-wr_ptr; info->len_wrap = 0; info->ptr_wrap = NULL; } else { - info->len_lin = f->depth - w; - info->len_wrap = free - info->len_lin; // Remaining length - n already was limited to free or FIFO depth - info->ptr_wrap = f->buffer; // Always start of buffer + info->len_lin = f->depth - wr_ptr; + info->len_wrap = remain - info->len_lin; // Remaining length - n already was limited to remain or FIFO depth + info->ptr_wrap = f->buffer; // Always start of buffer } } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index e64ab4b6d..204d53081 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -101,10 +101,10 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si #if CFG_FIFO_MUTEX TU_ATTR_ALWAYS_INLINE static inline -void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t write_mutex_hdl, tu_fifo_mutex_t read_mutex_hdl) +void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t wr_mutex, tu_fifo_mutex_t rd_mutex) { - f->mutex_wr = write_mutex_hdl; - f->mutex_rd = read_mutex_hdl; + f->mutex_wr = wr_mutex; + f->mutex_rd = rd_mutex; } #endif -- cgit v1.3.1 From 15ab35d9b82590e49937457efd2654adb2dd8b65 Mon Sep 17 00:00:00 2001 From: Sebastien COUDREAU Date: Thu, 8 Dec 2022 11:18:28 +0100 Subject: usbtmc: correct packet size bug Code was only reading the first 64 bytes of a 512 bytes packet. --- src/class/usbtmc/usbtmc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 0f6d3f60d..0b7c28b6e 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -364,7 +364,7 @@ bool tud_usbtmc_start_bus_read() default: TU_VERIFY(false); } - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, usbtmc_state.ep_bulk_out_wMaxPacketSize)); return true; } -- cgit v1.3.1 From 071da47944a4345b41328dc514d8a73a537072a9 Mon Sep 17 00:00:00 2001 From: Sebastien COUDREAU Date: Thu, 8 Dec 2022 11:36:48 +0100 Subject: Correct interrupt polling interval in descriptor Use macro argument instead of 0x16 constant value. At least Linux kernel was complaining about this value: "config 1 interface 0 altsetting 0 endpoint 0x82 has an invalid bInterval 22, changing to 8" (warning obtained using usbtmc device config) --- src/device/usbd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/device/usbd.h b/src/device/usbd.h index dc5b35ffd..118e53ce4 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -603,7 +603,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* optional interrupt endpoint */ \ // _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number? #define TUD_USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \ - 7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16 + 7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), _int_pollingInterval #define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u) -- cgit v1.3.1 From 007ed1f0fe84c13567c7a4ccda79d71a05d79aec Mon Sep 17 00:00:00 2001 From: scoudreau <95369154+scoudreau@users.noreply.github.com> Date: Thu, 8 Dec 2022 14:50:34 +0100 Subject: Added missing typecast to pass build checks --- src/class/usbtmc/usbtmc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 0b7c28b6e..122b3f3cf 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -364,7 +364,7 @@ bool tud_usbtmc_start_bus_read() default: TU_VERIFY(false); } - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, usbtmc_state.ep_bulk_out_wMaxPacketSize)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, (uint16_t)usbtmc_state.ep_bulk_out_wMaxPacketSize)); return true; } -- cgit v1.3.1 From 82852774a74631e0916254022339c9713c44cb57 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 9 Dec 2022 18:20:09 +0700 Subject: add fifo implementation note - handle/fix double overflowed with write() - other minor clean upp --- src/common/tusb_fifo.c | 94 +++++++++++++++++++++++++++++--------------------- src/common/tusb_fifo.h | 63 ++++++++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 853614d28..df07a990c 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -81,8 +81,8 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si // Limit index space to 2*depth - this allows for a fast "modulo" calculation // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable // only if overflow happens once (important for unsupervised DMA applications) - f->max_pointer_idx = (uint16_t) (2*depth - 1); - f->non_used_index_space = UINT16_MAX - f->max_pointer_idx; + //f->max_pointer_idx = (uint16_t) (2*depth - 1); + f->non_used_index_space = UINT16_MAX - (2*f->depth-1); f->rd_idx = f->wr_idx = 0; @@ -320,15 +320,15 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu // Index (free-running and real buffer pointer) //--------------------------------------------------------------------+ -// Advance an absolute pointer +// Advance an absolute index // "absolute" index is only in the range of [0..2*depth) -static uint16_t advance_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) +static uint16_t advance_pointer(tu_fifo_t* f, uint16_t idx, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index - uint16_t next_p = (uint16_t) (p + offset); - if ( (p > next_p) || (next_p > f->max_pointer_idx) ) + uint16_t next_p = (uint16_t) (idx + offset); + if ( (idx > next_p) || (next_p >= 2*f->depth) ) { next_p = (uint16_t) (next_p + f->non_used_index_space); } @@ -343,7 +343,7 @@ static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index uint16_t new_p = (uint16_t) (p - offset); - if ( (p < new_p) || (new_p > f->max_pointer_idx) ) + if ( (p < new_p) || (new_p >= 2*f->depth) ) { new_p = (uint16_t) (new_p - f->non_used_index_space); } @@ -374,15 +374,15 @@ static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd } // Works on local copies of w and r -static inline bool _tu_fifo_empty(uint16_t wAbs, uint16_t rAbs) +static inline bool _tu_fifo_empty(uint16_t wr_idx, uint16_t rd_idx) { - return wAbs == rAbs; + return wr_idx == rd_idx; } // Works on local copies of w and r static inline bool _tu_fifo_full(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) { - return (_tu_fifo_count(f, wAbs, rAbs) == f->depth); + return _tu_fifo_count(f, wAbs, rAbs) == f->depth; } // Works on local copies of w and r @@ -391,9 +391,9 @@ static inline bool _tu_fifo_full(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) // write more than 2*depth-1 items in one rush without updating write pointer. Otherwise // write pointer wraps and you pointer states are messed up. This can only happen if you // use DMAs, write functions do not allow such an error. -static inline bool _tu_fifo_overflowed(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) +static inline bool _tu_fifo_overflowed(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) { - return (_tu_fifo_count(f, wAbs, rAbs) > f->depth); + return (_tu_fifo_count(f, wr_idx, rd_idx) > f->depth); } // Works on local copies of w @@ -466,44 +466,58 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu { if ( n == 0 ) return 0; - TU_LOG(TU_FIFO_DBG, "rd = %u, wr = %02u, n = %u: ", f->rd_idx, f->wr_idx, n); - _ff_lock(f->mutex_wr); uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; uint8_t const* buf8 = (uint8_t const*) data; + uint16_t overflowable_count = _tu_fifo_count(f, wr_idx, rd_idx); uint16_t const remain = _tu_fifo_remaining(f, wr_idx, rd_idx); - if ( n > remain) + TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", rd_idx, wr_idx, _tu_fifo_count(f, wr_idx, rd_idx), remain, n); + + if ( !f->overwritable ) { - if ( !f->overwritable ) - { - // limit up to full - n = remain; - } - else + // limit up to full + n = tu_min16(n, remain); + } + else + { + // In over-writable mode, fifo_write() is allowed even when fifo is full. In such case, + // oldest data in fifo i.e at read pointer data will be overwritten + // Note: we can modify read buffer contents but we must not modify the read index itself within a write function! + // Since it would end up in a race condition with read functions! + if ( n >= f->depth ) { - // oldest data in fifo i.e read pointer data will be overwritten - // Note: we modify read data but we do not want to modify the read pointer within a write function! - // since it would end up in a race condition with read functions! - // Note2: race condition could still occur if tu_fifo_read() is called while we modify its buffer (corrupted data) - - if ( n >= f->depth ) + // Only copy last part + if ( copy_mode == TU_FIFO_COPY_INC ) { - // Only copy last part - buf8 = buf8 + (n - f->depth) * f->item_size; - n = f->depth; - - // We start writing at the read pointer's position since we fill the complete - // buffer and we do not want to modify the read pointer within a write function! - // This would end up in a race condition with read functions! - wr_idx = rd_idx; + buf8 += (n - f->depth) * f->item_size; }else { - // TODO shift out oldest data from read pointer !!! + // TODO should read from hw fifo to discard data, however reading an odd number could + // accidentally discard data. } + + n = f->depth; + + // We start writing at the read pointer's position since we fill the whole buffer + wr_idx = rd_idx; + }else if (overflowable_count + n >= 2*f->depth) + { + // Double overflowed + // re-position write index to have a full fifo after pushed + wr_idx = advance_pointer(f, rd_idx, f->depth - n); + + // TODO we should also shift out n bytes from read index since we avoid changing rd index !! + // However memmove() is expensive due to actual copying + wrapping consideration. + // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory + // currently deliberately not implemented --> result in incorrect data read back + }else + { + // normal + single overflowed: just increase write index + // we will correct (re-position) read index later on in fifo_read() function } } @@ -511,12 +525,12 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu { uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); - TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_rel = %u", n, wr_ptr); + TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr); // Write data _ff_push_n(f, buf8, n, wr_ptr, copy_mode); - // Advance pointer + // Advance index f->wr_idx = advance_pointer(f, wr_idx, n); TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\n", f->wr_idx); @@ -850,8 +864,8 @@ bool tu_fifo_clear(tu_fifo_t *f) _ff_lock(f->mutex_rd); f->rd_idx = f->wr_idx = 0; - f->max_pointer_idx = (uint16_t) (2*f->depth-1); - f->non_used_index_space = UINT16_MAX - f->max_pointer_idx; + //f->max_pointer_idx = (uint16_t) (2*f->depth-1); + f->non_used_index_space = UINT16_MAX - (2*f->depth-1); _ff_unlock(f->mutex_wr); _ff_unlock(f->mutex_rd); diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 204d53081..fd149b75c 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -52,18 +52,74 @@ extern "C" { #define tu_fifo_mutex_t osal_mutex_t #endif +/* Write/Read index is always in the range of: + * 0 .. 2*depth-1 + * The extra window allow us to determine the fifo state of empty or full with only 2 indexes + * Following are examples with depth = 3 + * + * - empty: W = R + * | + * ------------------------- + * | 0 | RW| 2 | 3 | 4 | 5 | + * + * - full 1: W > R + * | + * ------------------------- + * | 0 | R | 2 | 3 | W | 5 | + * + * - full 2: W < R + * | + * ------------------------- + * | 0 | 1 | W | 3 | 4 | R | + * + * - Number of items in the fifo can be determined in either cases: + * - case W > R: Count = W - R + * - case W < R: Count = 2*depth - (R - W) + * + * In non-overwritable mode, computed Count (in above 2 cases) is at most equal to depth. + * However, in over-writable mode, write index can be repeatedly increased and count can be + * temporarily larger than depth (overflowed condition) e.g + * + * - Overflowed 1: write(3), write(1) + * In this case we will adjust Read index when read()/peek() is called so that count = depth. + * | + * ------------------------- + * | R | 1 | 2 | 3 | W | 5 | + * + * - Double Overflowed: write(3), write(1), write(2) + * Continue to write after overflowed to 2nd overflowed. + * We must prevent 2nd overflowed since it will cause incorrect computed of count, in above example + * if not handled the fifo will be empty instead of continue-to-be full. Since we must not modify + * read index in write() function, which cause race condition. We will re-position write index so that + * after data is written it is a full fifo i.e W = depth - R + * + * re-position W = 1 before write(2) + * Note: we should also move data from mem[4] to read index as well, but deliberately skipped here + * since it is an expensive operation !!! + * | + * ------------------------- + * | R | W | 2 | 3 | 4 | 5 | + * + * perform write(2), result is still a full fifo. + * + * | + * ------------------------- + * | R | 1 | 2 | W | 4 | 5 | + + */ typedef struct { uint8_t* buffer ; ///< buffer pointer uint16_t depth ; ///< max items uint16_t item_size ; ///< size of each item + bool overwritable ; uint16_t non_used_index_space ; ///< required for non-power-of-two buffer length - uint16_t max_pointer_idx ; ///< maximum absolute pointer index + //uint16_t max_pointer_idx ; ///< maximum absolute pointer index - volatile uint16_t wr_idx ; ///< write pointer - volatile uint16_t rd_idx ; ///< read pointer + volatile uint16_t wr_idx ; ///< write index + volatile uint16_t rd_idx ; ///< read index #if CFG_FIFO_MUTEX tu_fifo_mutex_t mutex_wr; @@ -87,7 +143,6 @@ typedef struct .item_size = sizeof(_type), \ .overwritable = _overwritable, \ .non_used_index_space = UINT16_MAX - (2*(_depth)-1), \ - .max_pointer_idx = 2*(_depth)-1, \ } #define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \ -- cgit v1.3.1 From ce064de6fd4416bb5368a2aaff4283f8e4b9fc36 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 10 Dec 2022 00:18:11 +0700 Subject: clean up --- src/common/tusb_fifo.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index df07a990c..a3933416c 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -178,7 +178,8 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t // Write data to linear part of buffer memcpy(ff_buf, app_buf, nLin_bytes); - TU_ASSERT(nWrap_bytes <= f->depth, ); + // Write data wrapped around + // TU_ASSERT(nWrap_bytes <= f->depth, ); memcpy(f->buffer, ((uint8_t const*) app_buf) + nLin_bytes, nWrap_bytes); } break; @@ -504,7 +505,8 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu // We start writing at the read pointer's position since we fill the whole buffer wr_idx = rd_idx; - }else if (overflowable_count + n >= 2*f->depth) + } + else if (overflowable_count + n >= 2*f->depth) { // Double overflowed // re-position write index to have a full fifo after pushed -- cgit v1.3.1 From 04a5c03ea8ea70510c332f0fafb44daf0ec7c7fb Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Dec 2022 11:54:33 +0700 Subject: fix int conversion warnings --- src/common/tusb_fifo.c | 4 ++-- src/common/tusb_fifo.h | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index a3933416c..70f514df2 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -82,7 +82,7 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable // only if overflow happens once (important for unsupervised DMA applications) //f->max_pointer_idx = (uint16_t) (2*depth - 1); - f->non_used_index_space = UINT16_MAX - (2*f->depth-1); + f->non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1)); f->rd_idx = f->wr_idx = 0; @@ -867,7 +867,7 @@ bool tu_fifo_clear(tu_fifo_t *f) f->rd_idx = f->wr_idx = 0; //f->max_pointer_idx = (uint16_t) (2*f->depth-1); - f->non_used_index_space = UINT16_MAX - (2*f->depth-1); + f->non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1)); _ff_unlock(f->mutex_wr); _ff_unlock(f->mutex_rd); diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index fd149b75c..932214c81 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -136,13 +136,13 @@ typedef struct void * ptr_wrap ; ///< wrapped part start pointer } tu_fifo_buffer_info_t; -#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ -{ \ - .buffer = _buffer, \ - .depth = _depth, \ - .item_size = sizeof(_type), \ - .overwritable = _overwritable, \ - .non_used_index_space = UINT16_MAX - (2*(_depth)-1), \ +#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ +{ \ + .buffer = _buffer, \ + .depth = _depth, \ + .item_size = sizeof(_type), \ + .overwritable = _overwritable, \ + .non_used_index_space = (uint16_t)(UINT16_MAX - (2*(_depth)-1)), \ } #define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \ -- cgit v1.3.1 From a05adfce86104c8ad217993db2707e1112918be3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Dec 2022 14:38:40 +0700 Subject: fix midi MS Header wTotalLength computation --- src/device/usbd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/device/usbd.h b/src/device/usbd.h index 118e53ce4..ad19d1045 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -293,7 +293,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* MIDI Streaming (MS) Interface */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 0, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, 0,\ /* MS Header */\ - 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(7 + (_numcables) * TUD_MIDI_DESC_JACK_LEN) + 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(7 + (_numcables) * TUD_MIDI_DESC_JACK_LEN + 2 * TUD_MIDI_DESC_EP_LEN(_numcables)) #define TUD_MIDI_JACKID_IN_EMB(_cablenum) \ (uint8_t)(((_cablenum) - 1) * 4 + 1) @@ -317,6 +317,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EMBEDDED, TUD_MIDI_JACKID_OUT_EMB(_cablenum), 1, TUD_MIDI_JACKID_IN_EXT(_cablenum), 1, _stridx,\ /* MS Out Jack (External), connected to In Jack Embedded */\ 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, TUD_MIDI_JACKID_OUT_EXT(_cablenum), 1, TUD_MIDI_JACKID_IN_EMB(_cablenum), 1, _stridx + #define TUD_MIDI_DESC_JACK(_cablenum) TUD_MIDI_DESC_JACK_DESC(_cablenum, 0) #define TUD_MIDI_DESC_EP_LEN(_numcables) (9 + 4 + (_numcables)) -- cgit v1.3.1 From 88e6da727370114b427287e74c3ade176c483b17 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Dec 2022 18:03:01 +0700 Subject: use OSAL_MUTEX_REQUIRED to replace CFG_FIFO_MUTEX/TUSB_OPT_MUTEX add macro to swallow mutex API in order to simplify code with mutex --- src/class/cdc/cdc_device.c | 8 ++------ src/common/tusb_fifo.h | 19 +++++++++++-------- src/common/tusb_mcu.h | 4 ++++ src/device/usbd.c | 20 +++++++------------- src/host/usbh.c | 41 +++++++++++------------------------------ src/osal/osal.h | 21 ++++++++++++++------- src/osal/osal_none.h | 12 ++++++++++++ src/tusb.c | 16 ++++------------ src/tusb_option.h | 3 --- 9 files changed, 65 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 7b1e08d5d..0bbbaaa83 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -62,10 +62,8 @@ typedef struct uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; -#if CFG_FIFO_MUTEX - osal_mutex_def_t rx_ff_mutex; - osal_mutex_def_t tx_ff_mutex; -#endif + OSAL_MUTEX_DEF(rx_ff_mutex); + OSAL_MUTEX_DEF(tx_ff_mutex); // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE]; @@ -248,10 +246,8 @@ void cdcd_init(void) // In this way, the most current data is prioritized. tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true); -#if CFG_FIFO_MUTEX tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex)); tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL); -#endif } } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index e64ab4b6d..e36e3a7f3 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -42,15 +42,13 @@ extern "C" { // within a certain number (see tu_fifo_overflow()). #include "common/tusb_common.h" +#include "osal/osal.h" + +#define tu_fifo_mutex_t osal_mutex_t // mutex is only needed for RTOS // for OS None, we don't get preempted -#define CFG_FIFO_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) - -#if CFG_FIFO_MUTEX -#include "osal/osal.h" -#define tu_fifo_mutex_t osal_mutex_t -#endif +#define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED typedef struct { @@ -65,7 +63,7 @@ typedef struct volatile uint16_t wr_idx ; ///< write pointer volatile uint16_t rd_idx ; ///< read pointer -#if CFG_FIFO_MUTEX +#if OSAL_MUTEX_REQUIRED tu_fifo_mutex_t mutex_wr; tu_fifo_mutex_t mutex_rd; #endif @@ -99,13 +97,18 @@ bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable); bool tu_fifo_clear(tu_fifo_t *f); bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable); -#if CFG_FIFO_MUTEX +#if OSAL_MUTEX_REQUIRED TU_ATTR_ALWAYS_INLINE static inline void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t write_mutex_hdl, tu_fifo_mutex_t read_mutex_hdl) { f->mutex_wr = write_mutex_hdl; f->mutex_rd = read_mutex_hdl; } + +#else + +#define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex) + #endif bool tu_fifo_write (tu_fifo_t* f, void const * p_data); diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 86c68baf8..bb4225ad5 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -281,6 +281,10 @@ // Default Values //--------------------------------------------------------------------+ +#ifndef TUP_MCU_MULTIPLE_CORE +#define TUP_MCU_MULTIPLE_CORE 0 +#endif + #ifndef TUP_DCD_ENDPOINT_MAX #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 diff --git a/src/device/usbd.c b/src/device/usbd.c index c199e647e..f9a7af21b 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -272,10 +272,12 @@ static uint8_t _usbd_rhport = RHPORT_INVALID; OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); static osal_queue_t _usbd_q; -// Mutex for claiming endpoint, only needed when using with preempted RTOS -#if CFG_TUSB_OS != OPT_OS_NONE -static osal_mutex_def_t _ubsd_mutexdef; -static osal_mutex_t _usbd_mutex; +// Mutex for claiming endpoint +#if OSAL_MUTEX_REQUIRED + static osal_mutex_def_t _ubsd_mutexdef; + static osal_mutex_t _usbd_mutex; +#else + #define _usbd_mutex NULL #endif @@ -389,7 +391,7 @@ bool tud_init (uint8_t rhport) tu_varclr(&_usbd_dev); -#if CFG_TUSB_OS != OPT_OS_NONE +#if OSAL_MUTEX_REQUIRED // Init device mutex _usbd_mutex = osal_mutex_create(&_ubsd_mutexdef); TU_ASSERT(_usbd_mutex); @@ -1209,11 +1211,7 @@ bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; -#if TUSB_OPT_MUTEX return tu_edpt_claim(ep_state, _usbd_mutex); -#else - return tu_edpt_claim(ep_state, NULL); -#endif } bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) @@ -1224,11 +1222,7 @@ bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; -#if TUSB_OPT_MUTEX return tu_edpt_release(ep_state, _usbd_mutex); -#else - return tu_edpt_release(ep_state, NULL); -#endif } bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) diff --git a/src/host/usbh.c b/src/host/usbh.c index 9065e5241..ff8fbaef3 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -212,28 +212,12 @@ static usbh_dev0_t _dev0; // TODO: hub can has its own simpler struct to save memory CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[TOTAL_DEVICES]; -// Mutex for claiming endpoint, only needed when using with preempted RTOS -#if TUSB_OPT_MUTEX -static osal_mutex_def_t _usbh_mutexdef; -static osal_mutex_t _usbh_mutex; - -TU_ATTR_ALWAYS_INLINE static inline void usbh_lock(void) -{ - osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); -} - -TU_ATTR_ALWAYS_INLINE static inline void usbh_unlock(void) -{ - osal_mutex_unlock(_usbh_mutex); -} - +// Mutex for claiming endpoint +#if OSAL_MUTEX_REQUIRED + static osal_mutex_def_t _usbh_mutexdef; + static osal_mutex_t _usbh_mutex; #else - -#define _usbh_mutex NULL - -#define usbh_lock() -#define usbh_unlock() - + #define _usbh_mutex NULL #endif // Event queue @@ -277,8 +261,6 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t // TODO rework time-related function later void osal_task_delay(uint32_t msec) { - (void) msec; - const uint32_t start = hcd_frame_number(_usbh_controller); while ( ( hcd_frame_number(_usbh_controller) - start ) < msec ) {} } @@ -352,8 +334,8 @@ bool tuh_init(uint8_t controller_id) _usbh_q = osal_queue_create( &_usbh_qdef ); TU_ASSERT(_usbh_q != NULL); -#if TUSB_OPT_MUTEX - // Mutex +#if OSAL_MUTEX_REQUIRED + // Init mutex _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); TU_ASSERT(_usbh_mutex); #endif @@ -537,8 +519,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) uint8_t const daddr = xfer->daddr; - // TODO probably better to use semaphore as resource management than mutex - usbh_lock(); + (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); if (is_idle) @@ -553,7 +534,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) _ctrl_xfer.user_data = xfer->user_data; } - usbh_unlock(); + (void) osal_mutex_unlock(_usbh_mutex); TU_VERIFY(is_idle); const uint8_t rhport = usbh_get_rhport(daddr); @@ -597,9 +578,9 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) { - usbh_lock(); + osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); _ctrl_xfer.stage = stage; - usbh_unlock(); + osal_mutex_unlock(_usbh_mutex); } static void _xfer_complete(uint8_t daddr, xfer_result_t result) diff --git a/src/osal/osal.h b/src/osal/osal.h index 9d11866df..9cdab2882 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -33,17 +33,24 @@ #include "common/tusb_common.h" -// Return immediately -#define OSAL_TIMEOUT_NOTIMEOUT (0) -// Default timeout -#define OSAL_TIMEOUT_NORMAL (10) -// Wait forever -#define OSAL_TIMEOUT_WAIT_FOREVER (UINT32_MAX) +typedef void (*osal_task_func_t)( void * ); +// Timeout +#define OSAL_TIMEOUT_NOTIMEOUT (0) // Return immediately +#define OSAL_TIMEOUT_NORMAL (10) // Default timeout +#define OSAL_TIMEOUT_WAIT_FOREVER (UINT32_MAX) // Wait forever #define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER -typedef void (*osal_task_func_t)( void * ); +// Mutex is required when using a preempted RTOS or MCU has multiple cores +#if (CFG_TUSB_OS == OPT_OS_NONE) && !TUP_MCU_MULTIPLE_CORE + #define OSAL_MUTEX_REQUIRED 0 + #define OSAL_MUTEX_DEF(_name) +#else + #define OSAL_MUTEX_REQUIRED 1 + #define OSAL_MUTEX_DEF(_name) osal_mutex_def_t _name +#endif +// OS thin implementation #if CFG_TUSB_OS == OPT_OS_NONE #include "osal_none.h" #elif CFG_TUSB_OS == OPT_OS_FREERTOS diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 9c80e4548..1ad130557 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -82,6 +82,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t s typedef osal_semaphore_def_t osal_mutex_def_t; typedef osal_semaphore_t osal_mutex_t; +#if OSAL_MUTEX_REQUIRED +// Note: multiple cores MCUs usually do provide IPC API for mutex +// or we can use std atomic function + TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { mdef->count = 1; @@ -98,6 +102,14 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd return osal_semaphore_post(mutex_hdl, false); } +#else + +#define osal_mutex_create(_mdef) (NULL) +#define osal_mutex_lock(_mutex_hdl, _ms) (true) +#define osal_mutex_unlock(_mutex_hdl) (true) + +#endif + //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ diff --git a/src/tusb.c b/src/tusb.c index c3787ff8f..f4380f89c 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -74,11 +74,9 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; -#if TUSB_OPT_MUTEX // pre-check to help reducing mutex lock TU_VERIFY((ep_state->busy == 0) && (ep_state->claimed == 0)); - osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); -#endif + (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only claim the endpoint if it is not busy and not claimed yet. bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0); @@ -87,9 +85,7 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) ep_state->claimed = 1; } -#if TUSB_OPT_MUTEX - osal_mutex_unlock(mutex); -#endif + (void) osal_mutex_unlock(mutex); return available; } @@ -98,9 +94,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; -#if TUSB_OPT_MUTEX - osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); -#endif + (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only release the endpoint if it is claimed and not busy bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0); @@ -109,9 +103,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) ep_state->claimed = 0; } -#if TUSB_OPT_MUTEX - osal_mutex_unlock(mutex); -#endif + (void) osal_mutex_unlock(mutex); return ret; } diff --git a/src/tusb_option.h b/src/tusb_option.h index f95ae6273..9ca6c794b 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -299,9 +299,6 @@ typedef int make_iso_compilers_happy; #define CFG_TUSB_OS_INC_PATH #endif -// mutex is only needed for RTOS TODO also required with multiple core MCUs -#define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) - //-------------------------------------------------------------------- // Device Options (Default) //-------------------------------------------------------------------- -- cgit v1.3.1 From 96d2be905ba331419a34a64bba6baaaf006ae26f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Dec 2022 18:47:54 +0700 Subject: fix build with usbtmc --- src/class/usbtmc/usbtmc_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 122b3f3cf..07c7c28a6 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -157,12 +157,12 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack static uint8_t termChar; static uint8_t termCharRequested = false; -osal_mutex_def_t usbtmcLockBuffer; +OSAL_MUTEX_DEF(usbtmcLockBuffer); static osal_mutex_t usbtmcLock; // Our own private lock, mostly for the state variable. -#define criticalEnter() do {osal_mutex_lock(usbtmcLock,OSAL_TIMEOUT_WAIT_FOREVER); } while (0) -#define criticalLeave() do {osal_mutex_unlock(usbtmcLock); } while (0) +#define criticalEnter() do { (void) osal_mutex_lock(usbtmcLock,OSAL_TIMEOUT_WAIT_FOREVER); } while (0) +#define criticalLeave() do { (void) osal_mutex_unlock(usbtmcLock); } while (0) bool atomicChangeState(usbtmcd_state_enum expectedState, usbtmcd_state_enum newState) { -- cgit v1.3.1 From 1e99480ad28808a29938673d5b05d9461da5d1c1 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 16 Dec 2022 15:19:40 +0700 Subject: fix ci with usbh and unit test --- src/host/usbh.c | 4 ++-- test/unit-test/test/device/msc/test_msc_device.c | 1 + test/unit-test/test/device/usbd/test_usbd.c | 1 + test/unit-test/test/test_fifo.c | 4 +++- 4 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index ff8fbaef3..ca42a523c 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -578,9 +578,9 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) { - osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); + (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); _ctrl_xfer.stage = stage; - osal_mutex_unlock(_usbh_mutex); + (void) osal_mutex_unlock(_usbh_mutex); } static void _xfer_complete(uint8_t daddr, xfer_result_t result) diff --git a/test/unit-test/test/device/msc/test_msc_device.c b/test/unit-test/test/device/msc/test_msc_device.c index 00bb86ccf..63684e76a 100644 --- a/test/unit-test/test/device/msc/test_msc_device.c +++ b/test/unit-test/test/device/msc/test_msc_device.c @@ -28,6 +28,7 @@ #include "unity.h" // Files to test +#include "osal/osal.h" #include "tusb_fifo.h" #include "tusb.h" #include "usbd.h" diff --git a/test/unit-test/test/device/usbd/test_usbd.c b/test/unit-test/test/device/usbd/test_usbd.c index c90383b57..ad95eb47a 100644 --- a/test/unit-test/test/device/usbd/test_usbd.c +++ b/test/unit-test/test/device/usbd/test_usbd.c @@ -25,6 +25,7 @@ #include "unity.h" // Files to test +#include "osal/osal.h" #include "tusb_fifo.h" #include "tusb.h" #include "usbd.h" diff --git a/test/unit-test/test/test_fifo.c b/test/unit-test/test/test_fifo.c index 0a5f4d3b9..1d87081bb 100644 --- a/test/unit-test/test/test_fifo.c +++ b/test/unit-test/test/test_fifo.c @@ -26,6 +26,8 @@ #include #include "unity.h" + +#include "osal/osal.h" #include "tusb_fifo.h" #define FIFO_SIZE 10 @@ -315,4 +317,4 @@ void test_rd_idx_wrap() n = tu_fifo_read_n(&ff10, dst, 4); TEST_ASSERT_EQUAL(n, 2); TEST_ASSERT_EQUAL(ff10.rd_idx, 6); -} \ No newline at end of file +} -- cgit v1.3.1 From 660343d2001c0ee943bf3e24cab6f235d3930b33 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 16 Dec 2022 16:55:25 +0700 Subject: update fifo per PanRe review --- src/common/tusb_fifo.c | 8 ++++++-- src/common/tusb_fifo.h | 7 ++++--- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 70f514df2..bbdd82982 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -352,9 +352,10 @@ static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) return new_p; } -// index to pointer, simply an modulo with minus +// index to pointer, simply an modulo with minus. static inline uint16_t idx2ptr(uint16_t idx, uint16_t depth) { + // Only run at most 3 times since index is limit in the range of [0..2*depth) while ( idx >= depth ) idx -= depth; return idx; } @@ -509,6 +510,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu else if (overflowable_count + n >= 2*f->depth) { // Double overflowed + // Index is bigger than the allowed range [0,2*depth) // re-position write index to have a full fifo after pushed wr_idx = advance_pointer(f, rd_idx, f->depth - n); @@ -518,7 +520,9 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu // currently deliberately not implemented --> result in incorrect data read back }else { - // normal + single overflowed: just increase write index + // normal + single overflowed: + // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read() + // Therefore we just increase write index // we will correct (re-position) read index later on in fifo_read() function } } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 932214c81..972d29d50 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -54,7 +54,7 @@ extern "C" { /* Write/Read index is always in the range of: * 0 .. 2*depth-1 - * The extra window allow us to determine the fifo state of empty or full with only 2 indexes + * The extra window allow us to determine the fifo state of empty or full with only 2 indices * Following are examples with depth = 3 * * - empty: W = R @@ -86,7 +86,8 @@ extern "C" { * ------------------------- * | R | 1 | 2 | 3 | W | 5 | * - * - Double Overflowed: write(3), write(1), write(2) + * - Double Overflowed i.e index is out of allowed range [0,2*depth) e.g: + * write(3), write(1), write(2) * Continue to write after overflowed to 2nd overflowed. * We must prevent 2nd overflowed since it will cause incorrect computed of count, in above example * if not handled the fifo will be empty instead of continue-to-be full. Since we must not modify @@ -94,7 +95,7 @@ extern "C" { * after data is written it is a full fifo i.e W = depth - R * * re-position W = 1 before write(2) - * Note: we should also move data from mem[4] to read index as well, but deliberately skipped here + * Note: we should also move data from mem[3] to read index as well, but deliberately skipped here * since it is an expensive operation !!! * | * ------------------------- -- cgit v1.3.1 From 4f0369508450883504e377b40aaec8860c8cb256 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Dec 2022 16:52:28 +0700 Subject: adding tuh_cdc_mount_cb/tuh_cdc_umount_cb start adding cdc_app.c to example --- examples/host/cdc_msc_hid/CMakeLists.txt | 3 +- examples/host/cdc_msc_hid/Makefile | 3 +- examples/host/cdc_msc_hid/src/cdc_app.c | 51 ++++++++++++++++++++++++++++++++ examples/host/cdc_msc_hid/src/main.c | 11 ++----- src/class/cdc/cdc_host.c | 12 ++++++++ src/class/cdc/cdc_host.h | 17 +++++++---- 6 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 examples/host/cdc_msc_hid/src/cdc_app.c (limited to 'src') diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index d84457bc9..2e89817a5 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -14,8 +14,9 @@ add_executable(${PROJECT}) # Example source target_sources(${PROJECT} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c ) diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile index ad28076a0..9adccfa3a 100644 --- a/examples/host/cdc_msc_hid/Makefile +++ b/examples/host/cdc_msc_hid/Makefile @@ -7,7 +7,8 @@ INC += \ # Example source EXAMPLE_SOURCE = \ - src/hid_app.c \ + src/cdc_app.c \ + src/hid_app.c \ src/main.c \ src/msc_app.c \ diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c new file mode 100644 index 000000000..29da02abc --- /dev/null +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -0,0 +1,51 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + + +//------------- IMPLEMENTATION -------------// + +void cdc_app_task(void) +{ + +} + +void tuh_cdc_mount_cb(uint8_t dev_addr) +{ + (void) dev_addr; + printf("A CDC device is mounted\r\n"); +} + +void tuh_cdc_umount_cb(uint8_t dev_addr) +{ + (void) dev_addr; + printf("A CDC device is unmounted\r\n"); +} diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index d26e41e8d..465e457f7 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -35,7 +35,7 @@ //--------------------------------------------------------------------+ void led_blinking_task(void); -extern void cdc_task(void); +extern void cdc_app_task(void); extern void hid_app_task(void); /*------------- MAIN -------------*/ @@ -52,9 +52,9 @@ int main(void) { // tinyusb host task tuh_task(); - led_blinking_task(); - cdc_task(); + led_blinking_task(); + cdc_app_task(); hid_app_task(); } @@ -79,11 +79,6 @@ void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_i tuh_cdc_receive(dev_addr, serial_in_buffer, sizeof(serial_in_buffer), true); // waiting for next data } -void cdc_task(void) -{ - -} - //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index ee824cb4e..aa3a7e1e5 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -239,6 +239,8 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num) { (void) dev_addr; (void) itf_num; + + if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(dev_addr); return true; } @@ -254,6 +256,16 @@ void cdch_close(uint8_t dev_addr) TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); cdch_data_t * p_cdc = get_itf(dev_addr); + + // Invoke application callback + if (tuh_cdc_umount_cb) + { + if (p_cdc->ep_out || p_cdc->ep_in || p_cdc->ep_notif) + { + tuh_cdc_umount_cb(dev_addr); + } + } + tu_memclr(p_cdc, sizeof(cdch_data_t)); } diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 33dbd2efb..c3b601b34 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -34,13 +34,18 @@ #endif //--------------------------------------------------------------------+ -// CDC APPLICATION PUBLIC API +// Application API //--------------------------------------------------------------------+ -/** \ingroup ClassDriver_CDC Communication Device Class (CDC) - * \addtogroup CDC_Serial Serial - * @{ - * \defgroup CDC_Serial_Host Host - * @{ */ + + +//------------- Application Callback -------------// + +// Invoked when a device with CDC interface is mounted +TU_ATTR_WEAK void tuh_cdc_mount_cb(uint8_t dev_addr); + +// Invoked when a device with CDC interface is unmounted +TU_ATTR_WEAK void tuh_cdc_umount_cb(uint8_t dev_addr); + bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb); -- cgit v1.3.1 From f0c51eae44e4cd8f38fdba6469e49b1d98100d7c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Dec 2022 17:35:01 +0700 Subject: cdc check for bNumEndpoints before checking for endpoint descriptor --- src/class/cdc/cdc_host.c | 64 ++++++++++++++++++++++++++---------------------- src/host/usbh.c | 3 +-- 2 files changed, 36 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index aa3a7e1e5..83fa1bf5e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -152,13 +152,43 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf } //--------------------------------------------------------------------+ -// USBH-CLASS DRIVER API +// CLASS-USBH API //--------------------------------------------------------------------+ + void cdch_init(void) { tu_memclr(cdch_data, sizeof(cdch_data)); } +void cdch_close(uint8_t dev_addr) +{ + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); + + cdch_data_t * p_cdc = get_itf(dev_addr); + + // Invoke application callback + if (tuh_cdc_umount_cb) + { + if (p_cdc->ep_out || p_cdc->ep_in || p_cdc->ep_notif) + { + tuh_cdc_umount_cb(dev_addr); + } + } + + tu_memclr(p_cdc, sizeof(cdch_data_t)); +} + +bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) +{ + (void) ep_addr; + tuh_cdc_xfer_isr( dev_addr, event, 0, xferred_bytes ); + return true; +} + +//--------------------------------------------------------------------+ +// Enumeration +//--------------------------------------------------------------------+ + bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; @@ -175,7 +205,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it p_cdc->itf_num = itf_desc->bInterfaceNumber; p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; - //------------- Communication Interface -------------// + //------------- Control Interface -------------// uint16_t drv_len = tu_desc_len(itf_desc); uint8_t const * p_desc = tu_desc_next(itf_desc); @@ -192,9 +222,10 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it p_desc = tu_desc_next(p_desc); } - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) + // Open notification endpoint of control interface if any + if (itf_desc->bNumEndpoints == 1) { - // notification endpoint + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)); tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; TU_ASSERT( tuh_edpt_open(dev_addr, desc_ep) ); @@ -244,29 +275,4 @@ bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) -{ - (void) ep_addr; - tuh_cdc_xfer_isr( dev_addr, event, 0, xferred_bytes ); - return true; -} - -void cdch_close(uint8_t dev_addr) -{ - TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); - - cdch_data_t * p_cdc = get_itf(dev_addr); - - // Invoke application callback - if (tuh_cdc_umount_cb) - { - if (p_cdc->ep_out || p_cdc->ep_in || p_cdc->ep_notif) - { - tuh_cdc_umount_cb(dev_addr); - } - } - - tu_memclr(p_cdc, sizeof(cdch_data_t)); -} - #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index ca42a523c..b0cd62bac 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1524,8 +1524,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find driver for this interface - uint8_t drv_id; - for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; -- cgit v1.3.1 From f62f97395626f316f1670f1777a0a75877e8e773 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Dec 2022 23:19:47 +0700 Subject: minor rename --- src/class/cdc/cdc_host.c | 51 +++++++++++++++++++++++++++++++++++++++--------- src/class/cdc/cdc_host.h | 26 ++++++++++++++++++------ src/class/hid/hid_host.c | 1 + src/tusb_option.h | 4 ++++ 4 files changed, 67 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 83fa1bf5e..9678b756c 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -37,6 +37,7 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { + // uint8_t daddr; uint8_t itf_num; uint8_t itf_protocol; @@ -46,21 +47,42 @@ typedef struct { cdc_acm_capability_t acm_capability; -} cdch_data_t; + // Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) + // uint8_t line_state; +#if 0 + + // FIFO + tu_fifo_t rx_ff; + tu_fifo_t tx_ff; + + uint8_t rx_ff_buf[CFG_TUH_CDC_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; + +#if CFG_FIFO_MUTEX + osal_mutex_def_t rx_ff_mutex; + osal_mutex_def_t tx_ff_mutex; +#endif + + // Endpoint Transfer buffer + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUH_CDC_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUH_CDC_EP_BUFSIZE]; +#endif + +} cdch_interface_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static cdch_data_t cdch_data[CFG_TUH_DEVICE_MAX]; +static cdch_interface_t cdch_data[CFG_TUH_DEVICE_MAX]; -static inline cdch_data_t* get_itf(uint8_t dev_addr) +static inline cdch_interface_t* get_itf(uint8_t dev_addr) { return &cdch_data[dev_addr-1]; } bool tuh_cdc_mounted(uint8_t dev_addr) { - cdch_data_t* cdc = get_itf(dev_addr); + cdch_interface_t* cdc = get_itf(dev_addr); return cdc->ep_in && cdc->ep_out; } @@ -68,7 +90,7 @@ bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid) { if ( !tuh_cdc_mounted(dev_addr) ) return false; - cdch_data_t const * p_cdc = get_itf(dev_addr); + cdch_interface_t const * p_cdc = get_itf(dev_addr); switch (pipeid) { @@ -89,6 +111,17 @@ bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid) //--------------------------------------------------------------------+ // APPLICATION API (parameter validation needed) //--------------------------------------------------------------------+ + +uint32_t tuh_cdc_write(uint8_t dev_addr, void const* buffer, uint32_t bufsize) +{ + (void) dev_addr; + (void) buffer; + (void) bufsize; + + return 0; +} + + bool tuh_cdc_serial_is_mounted(uint8_t dev_addr) { // TODO consider all AT Command as serial candidate @@ -122,7 +155,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb) { - cdch_data_t const * p_cdc = get_itf(dev_addr); + cdch_interface_t const * p_cdc = get_itf(dev_addr); tusb_control_request_t const request = { @@ -164,7 +197,7 @@ void cdch_close(uint8_t dev_addr) { TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); - cdch_data_t * p_cdc = get_itf(dev_addr); + cdch_interface_t * p_cdc = get_itf(dev_addr); // Invoke application callback if (tuh_cdc_umount_cb) @@ -175,7 +208,7 @@ void cdch_close(uint8_t dev_addr) } } - tu_memclr(p_cdc, sizeof(cdch_data_t)); + tu_memclr(p_cdc, sizeof(cdch_interface_t)); } bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) @@ -200,7 +233,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass && 0xFF != itf_desc->bInterfaceProtocol); - cdch_data_t * p_cdc = get_itf(dev_addr); + cdch_interface_t * p_cdc = get_itf(dev_addr); p_cdc->itf_num = itf_desc->bInterfaceNumber; p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index c3b601b34..ce1f0f309 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -34,19 +34,24 @@ #endif //--------------------------------------------------------------------+ -// Application API +// Class Driver Configuration //--------------------------------------------------------------------+ -//------------- Application Callback -------------// +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ -// Invoked when a device with CDC interface is mounted -TU_ATTR_WEAK void tuh_cdc_mount_cb(uint8_t dev_addr); +bool tuh_cdc_mounted(uint8_t dev_addr); -// Invoked when a device with CDC interface is unmounted -TU_ATTR_WEAK void tuh_cdc_umount_cb(uint8_t dev_addr); +uint32_t tuh_cdc_write(uint8_t dev_addr, void const* buffer, uint32_t bufsize); +//uint32_t tuh_cdc_read(uint8_t dev_addr, void* buffer, uint32_t bufsize); +//--------------------------------------------------------------------+ +// Control Endpoint (Request) API +//--------------------------------------------------------------------+ +// Set Control Line State (DTR, RTS) bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb); static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_xfer_cb_t complete_cb) @@ -59,6 +64,15 @@ static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_xfer_cb_t complete_c return tuh_cdc_set_control_line_state(dev_addr, false, false, complete_cb); } +//------------- Application Callback -------------// + +// Invoked when a device with CDC interface is mounted +TU_ATTR_WEAK void tuh_cdc_mount_cb(uint8_t dev_addr); + +// Invoked when a device with CDC interface is unmounted +TU_ATTR_WEAK void tuh_cdc_umount_cb(uint8_t dev_addr); + + /** \brief Check if device support CDC Serial interface or not * \param[in] dev_addr device address * \retval true if device supports diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index ca745464c..504ddca1e 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -62,6 +62,7 @@ typedef struct hidh_interface_t instances[CFG_TUH_HID]; } hidh_device_t; +CFG_TUSB_MEM_SECTION static hidh_device_t _hidh_dev[CFG_TUH_DEVICE_MAX]; //------------- Internal prototypes -------------// diff --git a/src/tusb_option.h b/src/tusb_option.h index 9ca6c794b..69972c630 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -256,6 +256,10 @@ typedef int make_iso_compilers_happy; // For backward compatible #define TUSB_OPT_HOST_ENABLED CFG_TUH_ENABLED +// highspeed support indicator +#define TUH_OPT_HIGH_SPEED (CFG_TUH_MAX_SPEED ? (CFG_TUH_MAX_SPEED & OPT_MODE_HIGH_SPEED) : TUP_RHPORT_HIGHSPEED) + + //--------------------------------------------------------------------+ // TODO move later //--------------------------------------------------------------------+ -- cgit v1.3.1 From bd1f7f86ce1b6e82c3942d545e984b74b050004e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Dec 2022 15:27:39 +0700 Subject: add common EPSIZE for bulk/iso in full and highspeed adding cdc host fifo tx/rx --- src/class/cdc/cdc_device.h | 1 - src/class/cdc/cdc_host.c | 71 ++++++++++++++++++++------------------------- src/class/cdc/cdc_host.h | 19 ++++++++++++ src/common/tusb_types.h | 10 ++++++- src/host/usbh_classdriver.h | 4 +++ 5 files changed, 64 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index fbc7162a3..f625a7554 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -27,7 +27,6 @@ #ifndef _TUSB_CDC_DEVICE_H_ #define _TUSB_CDC_DEVICE_H_ -#include "common/tusb_common.h" #include "cdc.h" //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 9678b756c..da8ad726b 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -37,7 +37,7 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { - // uint8_t daddr; + uint8_t daddr; uint8_t itf_num; uint8_t itf_protocol; @@ -49,7 +49,6 @@ typedef struct { // Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) // uint8_t line_state; -#if 0 // FIFO tu_fifo_t rx_ff; @@ -64,54 +63,48 @@ typedef struct { #endif // Endpoint Transfer buffer - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUH_CDC_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUH_CDC_EP_BUFSIZE]; -#endif + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUH_CDC_RX_EPSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUH_CDC_TX_EPSIZE]; } cdch_interface_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static cdch_interface_t cdch_data[CFG_TUH_DEVICE_MAX]; + +CFG_TUSB_MEM_SECTION +static cdch_interface_t cdch_data[CFG_TUH_CDC]; static inline cdch_interface_t* get_itf(uint8_t dev_addr) { - return &cdch_data[dev_addr-1]; -} + for(size_t i=0; iep_in && cdc->ep_out; + return NULL; } -bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid) +static cdch_interface_t* find_new_itf(void) { - if ( !tuh_cdc_mounted(dev_addr) ) return false; - - cdch_interface_t const * p_cdc = get_itf(dev_addr); - - switch (pipeid) + for(size_t i=0; iep_notif ); - - case CDC_PIPE_DATA_IN: - return usbh_edpt_busy(dev_addr, p_cdc->ep_in ); - - case CDC_PIPE_DATA_OUT: - return usbh_edpt_busy(dev_addr, p_cdc->ep_out ); - - default: - return false; + if (cdch_data[i].daddr == 0) return &cdch_data[i]; } + + return NULL; } //--------------------------------------------------------------------+ // APPLICATION API (parameter validation needed) //--------------------------------------------------------------------+ +bool tuh_cdc_mounted(uint8_t dev_addr) +{ + cdch_interface_t* p_cdc = get_itf(dev_addr); + return p_cdc != NULL; +} + uint32_t tuh_cdc_write(uint8_t dev_addr, void const* buffer, uint32_t bufsize) { (void) dev_addr; @@ -121,7 +114,6 @@ uint32_t tuh_cdc_write(uint8_t dev_addr, void const* buffer, uint32_t bufsize) return 0; } - bool tuh_cdc_serial_is_mounted(uint8_t dev_addr) { // TODO consider all AT Command as serial candidate @@ -156,6 +148,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb) { cdch_interface_t const * p_cdc = get_itf(dev_addr); + TU_VERIFY(p_cdc && p_cdc->acm_capability.support_line_request); tusb_control_request_t const request = { @@ -195,17 +188,13 @@ void cdch_init(void) void cdch_close(uint8_t dev_addr) { - TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); - cdch_interface_t * p_cdc = get_itf(dev_addr); + TU_VERIFY(p_cdc, ); // Invoke application callback if (tuh_cdc_umount_cb) { - if (p_cdc->ep_out || p_cdc->ep_in || p_cdc->ep_notif) - { - tuh_cdc_umount_cb(dev_addr); - } + tuh_cdc_umount_cb(dev_addr); } tu_memclr(p_cdc, sizeof(cdch_interface_t)); @@ -233,8 +222,10 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass && 0xFF != itf_desc->bInterfaceProtocol); - cdch_interface_t * p_cdc = get_itf(dev_addr); + cdch_interface_t * p_cdc = find_new_itf(); + TU_VERIFY(p_cdc); + p_cdc->daddr = dev_addr; p_cdc->itf_num = itf_desc->bInterfaceNumber; p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; @@ -302,9 +293,11 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num) { - (void) dev_addr; (void) itf_num; - if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(dev_addr); + + // notify usbh that driver enumeration is complete + usbh_driver_set_config_complete(dev_addr, itf_num); + return true; } diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index ce1f0f309..b2e75902d 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -37,6 +37,25 @@ // Class Driver Configuration //--------------------------------------------------------------------+ +// RX FIFO size +#ifndef CFG_TUH_CDC_RX_BUFSIZE +#define CFG_TUH_CDC_RX_BUFSIZE USBH_EPSIZE_BULK_MAX +#endif + +// RX Endpoint size +#ifndef CFG_TUH_CDC_RX_EPSIZE +#define CFG_TUH_CDC_RX_EPSIZE USBH_EPSIZE_BULK_MAX +#endif + +// TX FIFO size +#ifndef CFG_TUH_CDC_TX_BUFSIZE +#define CFG_TUH_CDC_TX_BUFSIZE USBH_EPSIZE_BULK_MAX +#endif + +// TX Endpoint size +#ifndef CFG_TUH_CDC_TX_EPSIZE +#define CFG_TUH_CDC_TX_EPSIZE USBH_EPSIZE_BULK_MAX +#endif //--------------------------------------------------------------------+ // Application API diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 1bfa7c7d1..c4c9d4133 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -69,6 +69,15 @@ typedef enum TUSB_DIR_IN_MASK = 0x80 }tusb_dir_t; +enum +{ + TUSB_EPSIZE_BULK_FS = 64, + TUSB_EPSIZE_BULK_HS= 512, + + TUSB_EPSIZE_ISO_FS_MAX = 1023, + TUSB_EPSIZE_ISO_HS_MAX = 1024, +}; + /// Isochronous End Point Attributes typedef enum { @@ -243,7 +252,6 @@ enum INTERFACE_INVALID_NUMBER = 0xff }; - typedef enum { MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00, diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index c156afea0..7f72560c3 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -34,6 +34,10 @@ extern "C" { #endif +enum { + USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) +}; + //--------------------------------------------------------------------+ // Class Driver API //--------------------------------------------------------------------+ -- cgit v1.3.1 From 4811b3463ff20fb6eee551b42d66a6e74b411746 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Dec 2022 17:16:19 +0700 Subject: stub --- src/class/cdc/cdc_host.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index da8ad726b..cb0794fa3 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -36,6 +36,14 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ + +//typedef struct { +// tu_fifo_t fifo; +// OSAL_MUTEX_DEF(ff_mutex); +// +// +//}usbh_edpt_stream_t; + typedef struct { uint8_t daddr; uint8_t itf_num; @@ -184,6 +192,13 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf void cdch_init(void) { tu_memclr(cdch_data, sizeof(cdch_data)); + +// for(size_t i=0; i Date: Fri, 16 Dec 2022 23:54:21 +0700 Subject: correct cdc usbh_driver_set_config_complete() --- src/class/cdc/cdc_host.c | 32 +++++++++++++++++++++----------- src/host/usbh.c | 3 ++- 2 files changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index cb0794fa3..482ccf4be 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -36,13 +36,24 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +#if 0 +typedef struct { + tu_fifo_t ff; + OSAL_MUTEX_DEF(ff_mutex); +}tu_edpt_stream_t; -//typedef struct { -// tu_fifo_t fifo; -// OSAL_MUTEX_DEF(ff_mutex); -// -// -//}usbh_edpt_stream_t; +uint32_t tud_cdc_read_available (void); +uint32_t tud_cdc_read (void *buffer, uint32_t bufsize); +void tud_cdc_read_flush (void); +bool tud_cdc_peek (uint8_t *ui8); + +uint32_t tud_cdc_write (void const *buffer, uint32_t bufsize); +uint32_t tud_cdc_write_flush (void); +uint32_t tud_cdc_write_available (void); + +//-------------------------------------------------------- +tu_edpt_stream_write() +#endif typedef struct { uint8_t daddr; @@ -65,10 +76,8 @@ typedef struct { uint8_t rx_ff_buf[CFG_TUH_CDC_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; -#if CFG_FIFO_MUTEX - osal_mutex_def_t rx_ff_mutex; - osal_mutex_def_t tx_ff_mutex; -#endif + OSAL_MUTEX_DEF(rx_ff_mutex); + OSAL_MUTEX_DEF(tx_ff_mutex); // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUH_CDC_RX_EPSIZE]; @@ -311,7 +320,8 @@ bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num) if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(dev_addr); // notify usbh that driver enumeration is complete - usbh_driver_set_config_complete(dev_addr, itf_num); + // itf_num+1 to account for data interface as well + usbh_driver_set_config_complete(dev_addr, itf_num+1); return true; } diff --git a/src/host/usbh.c b/src/host/usbh.c index b0cd62bac..4b278f2da 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1570,7 +1570,8 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) { // continue with next valid interface - // TODO skip IAD binding interface such as CDCs + // IAD binding interface such as CDCs should return itf_num + 1 when complete + // with usbh_driver_set_config_complete() uint8_t const drv_id = dev->itf2drv[itf_num]; if (drv_id != DRVID_INVALID) { -- cgit v1.3.1 From 7d76c172db2f45846c9db45ceed4d879be96296d Mon Sep 17 00:00:00 2001 From: tyustli <43946994+tyustli@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:18:47 +0800 Subject: [add] semaphore reset support for rt-thread add semaphore reset support for rt-thread --- src/osal/osal_rtthread.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index f8452bfb2..c0d6e91a1 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -63,7 +63,8 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t se } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { - // TODO: implement + rt_ubase_t value = 0; + rt_sem_control(sem_hdl, RT_IPC_CMD_RESET, &value); } //--------------------------------------------------------------------+ -- cgit v1.3.1 From e992ff46d24984a8e1143d6d6c1c5aba8c93266f Mon Sep 17 00:00:00 2001 From: tyustli <43946994+tyustli@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:25:35 +0800 Subject: Update osal_rtthread.h --- src/osal/osal_rtthread.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index c0d6e91a1..18eb9c693 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -63,8 +63,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t se } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { - rt_ubase_t value = 0; - rt_sem_control(sem_hdl, RT_IPC_CMD_RESET, &value); + rt_sem_control(sem_hdl, RT_IPC_CMD_RESET, 0); } //--------------------------------------------------------------------+ -- cgit v1.3.1 From a46ad8fcdfef8c742933843b9c237778fc5ea0a0 Mon Sep 17 00:00:00 2001 From: jbruneaux31 <96246761+jbruneaux31@users.noreply.github.com> Date: Mon, 19 Dec 2022 13:58:54 +0100 Subject: Update osal_freertos.h Fix FreeRTOS task switch even if not required (unitialized variable usage) --- src/osal/osal_freertos.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 327aa9970..9393d1f26 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -115,7 +115,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t se } else { - BaseType_t xHigherPriorityTaskWoken; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t res = xSemaphoreGiveFromISR(sem_hdl, &xHigherPriorityTaskWoken); #if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 @@ -189,7 +189,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void } else { - BaseType_t xHigherPriorityTaskWoken; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t res = xQueueSendToBackFromISR(qhdl, data, &xHigherPriorityTaskWoken); #if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 -- cgit v1.3.1 From 7004914d8c6c7d88908776eb153661b6b987e513 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 20 Dec 2022 12:06:59 +0700 Subject: fix hid host incorrect edpt release if failed to transmit add CDC_CONTROL_LINE_STATE_DTR/RTS, TUSB_INDEX_INVALID enum --- src/class/cdc/cdc.h | 10 ++++++++-- src/class/hid/hid_host.c | 2 +- src/common/tusb_types.h | 5 +++++ 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index c428af865..6a9669cf2 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -192,6 +192,12 @@ typedef enum CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60, }cdc_management_request_t; +enum +{ + CDC_CONTROL_LINE_STATE_DTR = 0x01, + CDC_CONTROL_LINE_STATE_RTS = 0x02, +}; + //--------------------------------------------------------------------+ // Management Element Notification (Notification Endpoint) //--------------------------------------------------------------------+ @@ -390,8 +396,8 @@ TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct"); typedef struct TU_ATTR_PACKED { - uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. - uint16_t half_duplex_carrier_control : 1; + uint16_t dtr : 1; + uint16_t rts : 1; uint16_t : 14; } cdc_line_control_state_t; diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 504ddca1e..42b5e2f4e 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -259,7 +259,7 @@ bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance) if ( !usbh_edpt_xfer(dev_addr, hid_itf->ep_in, hid_itf->epin_buf, hid_itf->epin_size) ) { - usbh_edpt_claim(dev_addr, hid_itf->ep_in); + usbh_edpt_release(dev_addr, hid_itf->ep_in); return false; } diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index c4c9d4133..32cdba450 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -273,6 +273,11 @@ enum CONTROL_STAGE_ACK }; +enum +{ + TUSB_INDEX_INVALID = 0xff +}; + //--------------------------------------------------------------------+ // USB Descriptors //--------------------------------------------------------------------+ -- cgit v1.3.1 From 854e5222aea570a2be2201d8c460f54b87c9108a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 00:26:46 +0700 Subject: finalizing cdc host, has a working read/write TODO: first character seems not to get echoed. set control line state seems to failed with LOG < 2 --- examples/host/cdc_msc_hid/src/main.c | 18 -- src/class/cdc/cdc_host.c | 458 +++++++++++++++++++++++++++-------- src/class/cdc/cdc_host.h | 84 +++++-- 3 files changed, 419 insertions(+), 141 deletions(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 465e457f7..b34810252 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -61,24 +61,6 @@ int main(void) return 0; } -//--------------------------------------------------------------------+ -// USB CDC -//--------------------------------------------------------------------+ -CFG_TUSB_MEM_SECTION static char serial_in_buffer[64] = { 0 }; - -// invoked ISR context -void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) -{ - (void) event; - (void) pipe_id; - (void) xferred_bytes; - - printf(serial_in_buffer); - tu_memclr(serial_in_buffer, sizeof(serial_in_buffer)); - - tuh_cdc_receive(dev_addr, serial_in_buffer, sizeof(serial_in_buffer), true); // waiting for next data -} - //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 482ccf4be..bdfbe3e74 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -36,52 +36,157 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#if 0 typedef struct { tu_fifo_t ff; + + // mutex: read if ep rx, write if e tx OSAL_MUTEX_DEF(ff_mutex); + + // TODO xfer_fifo can skip this buffer + uint8_t* ep_buf; + uint16_t ep_bufsize; + uint8_t ep_addr; }tu_edpt_stream_t; -uint32_t tud_cdc_read_available (void); -uint32_t tud_cdc_read (void *buffer, uint32_t bufsize); -void tud_cdc_read_flush (void); -bool tud_cdc_peek (uint8_t *ui8); +bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool use_wr_mutex, bool overwritable, + void* ff_buf, uint16_t ff_bufsize, + uint8_t* ep_buf, uint16_t ep_bufsize) +{ + osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutex); + (void) new_mutex; -uint32_t tud_cdc_write (void const *buffer, uint32_t bufsize); -uint32_t tud_cdc_write_flush (void); -uint32_t tud_cdc_write_available (void); + tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable); + tu_fifo_config_mutex(&s->ff, use_wr_mutex ? new_mutex : NULL, use_wr_mutex ? NULL : new_mutex); -//-------------------------------------------------------- -tu_edpt_stream_write() -#endif + s->ep_buf = ep_buf; + s->ep_bufsize = ep_bufsize; + + return true; +} + +bool tu_edpt_stream_clear(tu_edpt_stream_t* s) +{ + return tu_fifo_clear(&s->ff); +} + +uint32_t tud_edpt_stream_write_flush(uint8_t dev_addr, tu_edpt_stream_t* s) +{ + // No data to send + if ( !tu_fifo_count(&s->ff) ) return 0; + + // Claim the endpoint + // uint8_t const rhport = 0; + // TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); + TU_VERIFY( usbh_edpt_claim(dev_addr, s->ep_addr) ); + + // Pull data from FIFO -> EP buf + uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + + if ( count ) + { + //TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); + TU_ASSERT( usbh_edpt_xfer(dev_addr, s->ep_addr, s->ep_buf, count), 0 ); + return count; + }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); + + usbh_edpt_release(dev_addr, s->ep_addr); + return 0; + } +} + +uint32_t tu_edpt_stream_write(uint8_t daddr, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize) +{ + uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); + + // flush if queue more than packet size + uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + if ( (tu_fifo_count(&s->ff) >= bulk_packet_size) + /* || ((CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE) && tu_fifo_full(&p_cdc->tx_ff)) */ ) + { + tud_edpt_stream_write_flush(daddr, s); + } + + return ret; +} + +void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) +{ + tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); +} + +uint32_t tu_edpt_stream_read_xfer(uint8_t daddr, tu_edpt_stream_t* s) +{ + uint16_t available = tu_fifo_remaining(&s->ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + TU_VERIFY(available >= bulk_packet_size); + + // claim endpoint + TU_VERIFY(usbh_edpt_claim(daddr, s->ep_addr), 0); + + // fifo can be changed before endpoint is claimed + available = tu_fifo_remaining(&s->ff); + + if ( available >= bulk_packet_size ) + { + // multiple of packet size limit by ep bufsize + uint16_t count = (uint16_t) (available & (bulk_packet_size -1)); + count = tu_min16(count, s->ep_bufsize); + + TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, s->ep_buf, count), 0 ); + return count; + }else + { + // Release endpoint since we don't make any transfer + usbh_edpt_release(daddr, s->ep_addr); + return 0; + } +} + +uint32_t tu_edpt_stream_read(uint8_t daddr, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) +{ + uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize); + tu_edpt_stream_read_xfer(daddr, s); + return num_read; +} + +uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s) +{ + return (uint32_t) tu_fifo_count(&s->ff); +} typedef struct { uint8_t daddr; - uint8_t itf_num; - uint8_t itf_protocol; - - uint8_t ep_notif; - uint8_t ep_in; - uint8_t ep_out; + uint8_t bInterfaceNumber; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; cdc_acm_capability_t acm_capability; + uint8_t ep_notif; // Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) - // uint8_t line_state; + uint8_t line_state; - // FIFO - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; + tuh_xfer_cb_t user_control_cb; - uint8_t rx_ff_buf[CFG_TUH_CDC_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; + struct { + tu_edpt_stream_t tx; + tu_edpt_stream_t rx; - OSAL_MUTEX_DEF(rx_ff_mutex); - OSAL_MUTEX_DEF(tx_ff_mutex); + uint8_t tx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t tx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; - // Endpoint Transfer buffer - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUH_CDC_RX_EPSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUH_CDC_TX_EPSIZE]; + uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; + } stream; } cdch_interface_t; @@ -92,19 +197,33 @@ typedef struct { CFG_TUSB_MEM_SECTION static cdch_interface_t cdch_data[CFG_TUH_CDC]; -static inline cdch_interface_t* get_itf(uint8_t dev_addr) +static inline cdch_interface_t* get_itf(uint8_t idx) { - for(size_t i=0; idaddr != 0) ? p_cdc : NULL; +} + +static inline cdch_interface_t* get_itf_by_ep_addr(uint8_t daddr, uint8_t ep_addr) +{ + for(uint8_t i=0; idaddr == daddr) && + (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) + { + return p_cdc; + } } return NULL; } + static cdch_interface_t* find_new_itf(void) { - for(size_t i=0; idaddr == daddr && p_cdc->bInterfaceNumber == itf_num) return i; + } + + return TUSB_INDEX_INVALID; +} + +bool tuh_cdc_itf_get_info(uint8_t idx, tuh_cdc_itf_info_t* info) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc && info); + + info->daddr = p_cdc->daddr; + info->bInterfaceNumber = p_cdc->bInterfaceNumber; + info->bInterfaceSubClass = p_cdc->bInterfaceSubClass; + info->bInterfaceProtocol = p_cdc->bInterfaceProtocol; + + return true; +} + +bool tuh_cdc_mounted(uint8_t idx) +{ + cdch_interface_t* p_cdc = get_itf(idx); return p_cdc != NULL; } -uint32_t tuh_cdc_write(uint8_t dev_addr, void const* buffer, uint32_t bufsize) +bool tuh_cdc_get_dtr(uint8_t idx) { - (void) dev_addr; - (void) buffer; - (void) bufsize; + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); - return 0; + return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_DTR) ? true : false; } -bool tuh_cdc_serial_is_mounted(uint8_t dev_addr) +bool tuh_cdc_get_rts(uint8_t idx) { - // TODO consider all AT Command as serial candidate - return tuh_cdc_mounted(dev_addr) && - (cdch_data[dev_addr-1].itf_protocol <= CDC_COMM_PROTOCOL_ATCOMMAND_CDMA); + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); + + return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_RTS) ? true : false; } -bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify) +uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) { - (void) is_notify; - TU_VERIFY( tuh_cdc_mounted(dev_addr) ); - TU_VERIFY( p_data != NULL && length); + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); + + return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize); +} - uint8_t const ep_out = cdch_data[dev_addr-1].ep_out; - if ( usbh_edpt_busy(dev_addr, ep_out) ) return false; +uint32_t tuh_cdc_write_flush(uint8_t idx) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); - return usbh_edpt_xfer(dev_addr, ep_out, (void*)(uintptr_t) p_data, (uint16_t) length); + return tud_edpt_stream_write_flush(p_cdc->daddr, &p_cdc->stream.tx); } -bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify) +uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) { - (void) is_notify; - TU_VERIFY( tuh_cdc_mounted(dev_addr) ); - TU_VERIFY( p_buffer != NULL && length ); + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); - uint8_t const ep_in = cdch_data[dev_addr-1].ep_in; - if ( usbh_edpt_busy(dev_addr, ep_in) ) return false; + return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize); +} - return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, (uint16_t) length); +uint32_t tuh_cdc_read_available(uint8_t idx) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); + + return tu_edpt_stream_read_available(&p_cdc->stream.rx); } -bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb) +//--------------------------------------------------------------------+ +// Control Endpoint API +//--------------------------------------------------------------------+ + +// internal control complete to update state such as line state, encoding +static void cdch_internal_control_complete(tuh_xfer_t* xfer) { - cdch_interface_t const * p_cdc = get_itf(dev_addr); + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + uint8_t idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + TU_ASSERT(p_cdc, ); + + if (xfer->result == XFER_RESULT_SUCCESS) + { + switch(xfer->setup->bRequest) + { + case CDC_REQUEST_SET_CONTROL_LINE_STATE: + p_cdc->line_state = (uint8_t) tu_le16toh(xfer->setup->wValue); + break; + + default: break; + } + } + + xfer->complete_cb = p_cdc->user_control_cb; + xfer->complete_cb(xfer); +} + +bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) +{ + cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->acm_capability.support_line_request); tusb_control_request_t const request = @@ -176,19 +356,20 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf .direction = TUSB_DIR_OUT }, .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, - .wValue = tu_htole16((uint16_t) ((dtr ? 1u : 0u) | (rts ? 2u : 0u))), - .wIndex = tu_htole16(p_cdc->itf_num), + .wValue = tu_htole16(line_state), + .wIndex = tu_htole16(p_cdc->bInterfaceNumber), .wLength = 0 }; + p_cdc->user_control_cb = complete_cb; tuh_xfer_t xfer = { - .daddr = dev_addr, + .daddr = p_cdc->daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, - .complete_cb = complete_cb, - .user_data = 0 + .complete_cb = cdch_internal_control_complete, + .user_data = user_data }; return tuh_control_xfer(&xfer); @@ -202,32 +383,79 @@ void cdch_init(void) { tu_memclr(cdch_data, sizeof(cdch_data)); -// for(size_t i=0; istream.tx, true, false, + p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, + p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + + tu_edpt_stream_init(&p_cdc->stream.rx, false, false, + p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, + p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); + } } -void cdch_close(uint8_t dev_addr) +void cdch_close(uint8_t daddr) { - cdch_interface_t * p_cdc = get_itf(dev_addr); - TU_VERIFY(p_cdc, ); - - // Invoke application callback - if (tuh_cdc_umount_cb) + for(uint8_t idx=0; idxdaddr == daddr) + { + // Invoke application callback + if (tuh_cdc_umount_cb) tuh_cdc_umount_cb(idx); + + //tu_memclr(p_cdc, sizeof(cdch_interface_t)); + p_cdc->daddr = 0; + p_cdc->bInterfaceNumber = 0; + tu_edpt_stream_clear(&p_cdc->stream.tx); + tu_edpt_stream_clear(&p_cdc->stream.rx); + } } - - tu_memclr(p_cdc, sizeof(cdch_interface_t)); } -bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) +bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { - (void) ep_addr; - tuh_cdc_xfer_isr( dev_addr, event, 0, xferred_bytes ); + // TODO handle stall response, retry failed transfer ... + TU_ASSERT(event == XFER_RESULT_SUCCESS); + + cdch_interface_t * p_cdc = get_itf_by_ep_addr(daddr, ep_addr); + TU_ASSERT(p_cdc); + + if ( ep_addr == p_cdc->stream.tx.ep_addr ) + { + if ( 0 == tud_edpt_stream_write_flush(daddr, &p_cdc->stream.tx) ) + { + // If there is no data left, a ZLP should be sent if + // xferred_bytes is multiple of EP Packet size and not zero + uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + if ( !tu_fifo_count(&p_cdc->stream.tx.ff) && xferred_bytes && (0 == (xferred_bytes & (bulk_packet_size-1))) ) + { + if ( usbh_edpt_claim(daddr, p_cdc->stream.tx.ep_addr) ) + { + usbh_edpt_xfer(daddr, p_cdc->stream.tx.ep_addr, NULL, 0); + } + } + } + } + else if ( ep_addr == p_cdc->stream.rx.ep_addr ) + { + tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); + + // invoke receive callback + + // prepare for next transfer if needed + tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); + }else if ( ep_addr == p_cdc->ep_notif ) + { + // TODO handle notification endpoint + }else + { + TU_ASSERT(false); + } + return true; } @@ -238,7 +466,6 @@ bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; - (void) max_len; // Only support ACM subclass // Protocol 0xFF can be RNDIS device for windows XP @@ -246,19 +473,22 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass && 0xFF != itf_desc->bInterfaceProtocol); + uint8_t const * p_desc_end = ((uint8_t const*) itf_desc) + max_len; + cdch_interface_t * p_cdc = find_new_itf(); TU_VERIFY(p_cdc); - p_cdc->daddr = dev_addr; - p_cdc->itf_num = itf_desc->bInterfaceNumber; - p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; + p_cdc->daddr = dev_addr; + p_cdc->bInterfaceNumber = itf_desc->bInterfaceNumber; + p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; + p_cdc->bInterfaceProtocol = itf_desc->bInterfaceProtocol; + p_cdc->line_state = 0; //------------- Control Interface -------------// - uint16_t drv_len = tu_desc_len(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( (p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) ) { if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) { @@ -266,7 +496,6 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; } - drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } @@ -279,7 +508,6 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it TU_ASSERT( tuh_edpt_open(dev_addr, desc_ep) ); p_cdc->ep_notif = desc_ep->bEndpointAddress; - drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } @@ -288,42 +516,72 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it (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); // data endpoints expected to be in pairs for(uint32_t i=0; i<2; i++) { tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && + TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep)); if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) { - p_cdc->ep_in = desc_ep->bEndpointAddress; + p_cdc->stream.rx.ep_addr = desc_ep->bEndpointAddress; }else { - p_cdc->ep_out = desc_ep->bEndpointAddress; + p_cdc->stream.tx.ep_addr = desc_ep->bEndpointAddress; } - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next( p_desc ); + p_desc = tu_desc_next(p_desc); } } return true; } -bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num) +static void config_cdc_complete(uint8_t daddr, uint8_t itf_num) { - if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(dev_addr); + uint8_t const idx = tuh_cdc_itf_get_index(daddr, itf_num); + + if (idx != TUSB_INDEX_INVALID) + { + if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); + + // Prepare for incoming data + cdch_interface_t* p_cdc = get_itf(idx); + tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); + } // notify usbh that driver enumeration is complete // itf_num+1 to account for data interface as well - usbh_driver_set_config_complete(dev_addr, itf_num+1); + usbh_driver_set_config_complete(daddr, itf_num+1); +} + +#if CFG_TUH_CDC_SET_DTRRTS_ON_ENUM +static void config_set_dtr_rts_complete (tuh_xfer_t* xfer) +{ + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + config_cdc_complete(xfer->daddr, itf_num); +} + +bool cdch_set_config(uint8_t daddr, uint8_t itf_num) +{ + uint8_t const idx = tuh_cdc_itf_get_index(daddr, itf_num); + return tuh_cdc_set_control_line_state(idx, CFG_TUH_CDC_SET_DTRRTS_ON_ENUM, config_set_dtr_rts_complete, 0); +} + +#else + +bool cdch_set_config(uint8_t daddr, uint8_t itf_num) +{ + config_cdc_complete(daddr, itf_num); return true; } #endif + +#endif diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index b2e75902d..54e082e7d 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -37,6 +37,11 @@ // Class Driver Configuration //--------------------------------------------------------------------+ +// Set DTR ( bit 0), RTS (bit 1) on enumeration/mounted +#ifndef CFG_TUH_CDC_SET_DTRRTS_ON_ENUM +#define CFG_TUH_CDC_SET_DTRRTS_ON_ENUM 0 +#endif + // RX FIFO size #ifndef CFG_TUH_CDC_RX_BUFSIZE #define CFG_TUH_CDC_RX_BUFSIZE USBH_EPSIZE_BULK_MAX @@ -61,43 +66,76 @@ // Application API //--------------------------------------------------------------------+ -bool tuh_cdc_mounted(uint8_t dev_addr); +typedef struct +{ + uint8_t daddr; + uint8_t bInterfaceNumber; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; +} tuh_cdc_itf_info_t; + +// Get Interface index from device address + interface number +// return TUSB_INDEX_INVALID (0xFF) if not found +uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num); + +// Get Interface information +// return true if index is correct and interface is currently mounted +bool tuh_cdc_itf_get_info(uint8_t idx, tuh_cdc_itf_info_t* info); + +// Check if a interface is mounted +bool tuh_cdc_mounted(uint8_t idx); + +// Get current DTR status +bool tuh_cdc_get_dtr(uint8_t idx); + +// Get current RTS status +bool tuh_cdc_get_rts(uint8_t idx); + +// Check if interface is connected (DTR active) +TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) +{ + return tuh_cdc_get_dtr(idx); +} + +// Write to cdc interface +uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize); + +// Force sending data if possible, return number of forced bytes +uint32_t tuh_cdc_write_flush(uint8_t idx); + +// Read from cdc interface +uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize); -uint32_t tuh_cdc_write(uint8_t dev_addr, void const* buffer, uint32_t bufsize); -//uint32_t tuh_cdc_read(uint8_t dev_addr, void* buffer, uint32_t bufsize); +// Get the number of bytes available for reading +uint32_t tuh_cdc_read_available(uint8_t idx); //--------------------------------------------------------------------+ // Control Endpoint (Request) API //--------------------------------------------------------------------+ -// Set Control Line State (DTR, RTS) -bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb); +// Send control request to Set Control Line State: DTR (bit 0), RTS (bit 1) +bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_xfer_cb_t complete_cb) +// Connect by set both DTR, RTS +static inline bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return tuh_cdc_set_control_line_state(dev_addr, true, true, complete_cb); + return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data); } -static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_xfer_cb_t complete_cb) +// Disconnect by clear both DTR, RTS +static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return tuh_cdc_set_control_line_state(dev_addr, false, false, complete_cb); + return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data); } //------------- Application Callback -------------// // Invoked when a device with CDC interface is mounted -TU_ATTR_WEAK void tuh_cdc_mount_cb(uint8_t dev_addr); +// idx is index of cdc interface in the internal pool. +TU_ATTR_WEAK void tuh_cdc_mount_cb(uint8_t idx); // Invoked when a device with CDC interface is unmounted -TU_ATTR_WEAK void tuh_cdc_umount_cb(uint8_t dev_addr); - - -/** \brief Check if device support CDC Serial interface or not - * \param[in] dev_addr device address - * \retval true if device supports - * \retval false if device does not support or is not mounted - */ -bool tuh_cdc_serial_is_mounted(uint8_t dev_addr); +TU_ATTR_WEAK void tuh_cdc_umount_cb(uint8_t idx); /** \brief Check if the interface is currently busy or not * \param[in] dev_addr device address @@ -108,7 +146,7 @@ bool tuh_cdc_serial_is_mounted(uint8_t dev_addr); * can be scheduled. User needs to make sure the corresponding interface is mounted * (by \ref tuh_cdc_serial_is_mounted) before calling this function. */ -bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid); +// bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid); /** \brief Perform USB OUT transfer to device * \param[in] dev_addr device address @@ -121,7 +159,7 @@ bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid); * \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the * interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION. */ -bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify); +// bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify); /** \brief Perform USB IN transfer to get data from device * \param[in] dev_addr device address @@ -134,7 +172,7 @@ bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool i * \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the * interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION. */ -bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify); +// bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify); //--------------------------------------------------------------------+ // CDC APPLICATION CALLBACKS @@ -151,7 +189,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is * - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device. * \note */ -void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes); +// void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes); /// @} // group CDC_Serial_Host /// @} -- cgit v1.3.1 From 37529c41da3884c235ac4f582b7202331877142c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 10:46:47 +0700 Subject: fix ci --- src/class/cdc/cdc_host.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index bdfbe3e74..5aec41cbc 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -54,6 +54,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool use_wr_mutex, bool overwritab { osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutex); (void) new_mutex; + (void) use_wr_mutex; tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable); tu_fifo_config_mutex(&s->ff, use_wr_mutex ? new_mutex : NULL, use_wr_mutex ? NULL : new_mutex); -- cgit v1.3.1 From d1ea3844f70a5add6e073aa8fa6b562413db4929 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 11:04:57 +0700 Subject: rename TU_LOG_VAR to TU_LOG_PTR, print out setup of failed control transfer when LOG=1 --- src/common/tusb_debug.h | 18 +++++++++--------- src/host/usbh.c | 8 ++++++-- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index ac5bee6ec..65fd1920d 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -66,7 +66,7 @@ static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) #define TU_LOG(n, ...) TU_XSTRCAT(TU_LOG, n)(__VA_ARGS__) #define TU_LOG_MEM(n, ...) TU_XSTRCAT3(TU_LOG, n, _MEM)(__VA_ARGS__) #define TU_LOG_ARR(n, ...) TU_XSTRCAT3(TU_LOG, n, _ARR)(__VA_ARGS__) -#define TU_LOG_VAR(n, ...) TU_XSTRCAT3(TU_LOG, n, _VAR)(__VA_ARGS__) +#define TU_LOG_PTR(n, ...) TU_XSTRCAT3(TU_LOG, n, _PTR)(__VA_ARGS__) #define TU_LOG_INT(n, ...) TU_XSTRCAT3(TU_LOG, n, _INT)(__VA_ARGS__) #define TU_LOG_HEX(n, ...) TU_XSTRCAT3(TU_LOG, n, _HEX)(__VA_ARGS__) #define TU_LOG_LOCATION() tu_printf("%s: %d:\r\n", __PRETTY_FUNCTION__, __LINE__) @@ -76,7 +76,7 @@ static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) #define TU_LOG1 tu_printf #define TU_LOG1_MEM tu_print_mem #define TU_LOG1_ARR(_x, _n) tu_print_arr((uint8_t const*)(_x), _n) -#define TU_LOG1_VAR(_x) tu_print_arr((uint8_t const*)(_x), sizeof(*(_x))) +#define TU_LOG1_PTR(_x) tu_print_arr((uint8_t const*)(_x), sizeof(*(_x))) #define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) ) #define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) ) @@ -85,7 +85,7 @@ static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) #define TU_LOG2 TU_LOG1 #define TU_LOG2_MEM TU_LOG1_MEM #define TU_LOG2_ARR TU_LOG1_ARR - #define TU_LOG2_VAR TU_LOG1_VAR + #define TU_LOG2_PTR TU_LOG1_PTR #define TU_LOG2_INT TU_LOG1_INT #define TU_LOG2_HEX TU_LOG1_HEX #endif @@ -95,7 +95,7 @@ static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) #define TU_LOG3 TU_LOG1 #define TU_LOG3_MEM TU_LOG1_MEM #define TU_LOG3_ARR TU_LOG1_ARR - #define TU_LOG3_VAR TU_LOG1_VAR + #define TU_LOG3_PTR TU_LOG1_PTR #define TU_LOG3_INT TU_LOG1_INT #define TU_LOG3_HEX TU_LOG1_HEX #endif @@ -132,7 +132,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG #define TU_LOG(n, ...) #define TU_LOG_MEM(n, ...) - #define TU_LOG_VAR(n, ...) + #define TU_LOG_PTR(n, ...) #define TU_LOG_INT(n, ...) #define TU_LOG_HEX(n, ...) #define TU_LOG_LOCATION() @@ -143,14 +143,14 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #define TU_LOG0(...) #define TU_LOG0_MEM(...) -#define TU_LOG0_VAR(...) +#define TU_LOG0_PTR(...) #define TU_LOG0_INT(...) #define TU_LOG0_HEX(...) #ifndef TU_LOG1 #define TU_LOG1(...) #define TU_LOG1_MEM(...) - #define TU_LOG1_VAR(...) + #define TU_LOG1_PTR(...) #define TU_LOG1_INT(...) #define TU_LOG1_HEX(...) #endif @@ -158,7 +158,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG2 #define TU_LOG2(...) #define TU_LOG2_MEM(...) - #define TU_LOG2_VAR(...) + #define TU_LOG2_PTR(...) #define TU_LOG2_INT(...) #define TU_LOG2_HEX(...) #endif @@ -166,7 +166,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG3 #define TU_LOG3(...) #define TU_LOG3_MEM(...) - #define TU_LOG3_VAR(...) + #define TU_LOG3_PTR(...) #define TU_LOG3_INT(...) #define TU_LOG3_HEX(...) #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index 4b278f2da..59b1c3280 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -540,7 +540,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) const uint8_t rhport = usbh_get_rhport(daddr); TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request"); - TU_LOG2_VAR(xfer->setup); + TU_LOG2_PTR(xfer->setup); TU_LOG2("\r\n"); if (xfer->complete_cb) @@ -618,7 +618,11 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result if (XFER_RESULT_SUCCESS != result) { - TU_LOG1("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); + TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + #if CFG_TUSB_DEBUG == 1 + TU_LOG1_PTR(request); + TU_LOG1("\r\n"); + #endif // terminate transfer if any stage failed _xfer_complete(dev_addr, result); -- cgit v1.3.1 From cb2af4c0bc096e57c3486945eda43dbc26b3829a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 11:46:58 +0700 Subject: minor debug log --- src/class/cdc/cdc_host.c | 8 +++++ src/class/msc/msc_host.c | 13 +++++--- src/host/usbh.c | 85 ++++++++++++++++++++++++++---------------------- 3 files changed, 63 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 5aec41cbc..83c623884 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -33,6 +33,12 @@ #include "cdc_host.h" + +// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message +#define CDCH_DEBUG 2 + +#define TU_LOG_CDCH(...) TU_LOG(CDCH_DEBUG, __VA_ARGS__) + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -348,6 +354,8 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->acm_capability.support_line_request); + TU_LOG_CDCH("CDC Set Control Line State\r\n"); + tusb_control_request_t const request = { .bmRequestType_bit = diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 32f75a84b..6724e486c 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -33,6 +33,11 @@ #include "msc_host.h" +// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message +#define MSCH_DEBUG 2 + +#define TU_LOG_MSCH(...) TU_LOG(MSCH_DEBUG, __VA_ARGS__) + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -417,7 +422,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) p_msc->configured = true; //------------- Get Max Lun -------------// - TU_LOG2("MSC Get Max Lun\r\n"); + TU_LOG_MSCH("MSC Get Max Lun\r\n"); tusb_control_request_t const request = { .bmRequestType_bit = @@ -456,7 +461,7 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer) p_msc->max_lun++; // MAX LUN is minus 1 by specs // TODO multiple LUN support - TU_LOG2("SCSI Test Unit Ready\r\n"); + TU_LOG_MSCH("SCSI Test Unit Ready\r\n"); uint8_t const lun = 0; tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete, 0); } @@ -469,14 +474,14 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_d if (csw->status == 0) { // Unit is ready, read its capacity - TU_LOG2("SCSI Read Capacity\r\n"); + TU_LOG_MSCH("SCSI Read Capacity\r\n"); tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), config_read_capacity_complete, 0); }else { // Note: During enumeration, some device fails Test Unit Ready and require a few retries // with Request Sense to start working !! // TODO limit number of retries - TU_LOG2("SCSI Request Sense\r\n"); + TU_LOG_MSCH("SCSI Request Sense\r\n"); TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, _msch_buffer, config_request_sense_complete, 0)); } diff --git a/src/host/usbh.c b/src/host/usbh.c index 59b1c3280..36fc5fded 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -46,8 +46,10 @@ #define CFG_TUH_INTERFACE_MAX 8 #endif -// Debug level of USBD -#define USBH_DBG_LVL 2 +// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message +#define USBH_DEBUG 2 + +#define TU_LOG_USBH(...) TU_LOG(USBH_DEBUG, __VA_ARGS__) //--------------------------------------------------------------------+ // USBH-HCD common data structure @@ -324,11 +326,11 @@ bool tuh_init(uint8_t controller_id) // skip if already initialized if ( tuh_inited() ) return true; - TU_LOG2("USBH init on controller %u\r\n", controller_id); - TU_LOG2_INT(sizeof(usbh_device_t)); - TU_LOG2_INT(sizeof(hcd_event_t)); - TU_LOG2_INT(sizeof(_ctrl_xfer)); - TU_LOG2_INT(sizeof(tuh_xfer_t)); + TU_LOG_USBH("USBH init on controller %u\r\n", controller_id); + TU_LOG_INT(USBH_DEBUG, sizeof(usbh_device_t)); + TU_LOG_INT(USBH_DEBUG, sizeof(hcd_event_t)); + TU_LOG_INT(USBH_DEBUG, sizeof(_ctrl_xfer)); + TU_LOG_INT(USBH_DEBUG, sizeof(tuh_xfer_t)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -353,7 +355,7 @@ bool tuh_init(uint8_t controller_id) // Class drivers for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { - TU_LOG2("%s init\r\n", usbh_class_drivers[drv_id].name); + TU_LOG_USBH("%s init\r\n", usbh_class_drivers[drv_id].name); usbh_class_drivers[drv_id].init(); } @@ -401,12 +403,12 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) case HCD_EVENT_DEVICE_ATTACH: // TODO due to the shared _usbh_ctrl_buf, we must complete enumerating // one device before enumerating another one. - TU_LOG2("[%u:] USBH DEVICE ATTACH\r\n", event.rhport); + TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport); enum_new_device(&event); break; case HCD_EVENT_DEVICE_REMOVE: - TU_LOG2("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); + TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); process_device_unplugged(event.rhport, event.connection.hub_addr, event.connection.hub_port); #if CFG_TUH_HUB @@ -425,7 +427,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); - TU_LOG2("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len); + TU_LOG_USBH("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len); if (event.dev_addr == 0) { @@ -449,7 +451,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; if(drv_id < USBH_CLASS_DRIVER_COUNT) { - TU_LOG2("%s xfer callback\r\n", usbh_class_drivers[drv_id].name); + TU_LOG_USBH("%s xfer callback\r\n", usbh_class_drivers[drv_id].name); usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); } else @@ -539,9 +541,11 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) TU_VERIFY(is_idle); const uint8_t rhport = usbh_get_rhport(daddr); - TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request"); - TU_LOG2_PTR(xfer->setup); - TU_LOG2("\r\n"); + TU_LOG_USBH("[%u:%u] %s: ", rhport, daddr, + (xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ? + tu_str_std_request[xfer->setup->bRequest] : "Class Request"); + TU_LOG_PTR(USBH_DEBUG, xfer->setup); + TU_LOG_USBH("\r\n"); if (xfer->complete_cb) { @@ -585,7 +589,7 @@ TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) static void _xfer_complete(uint8_t daddr, xfer_result_t result) { - TU_LOG2("\r\n"); + TU_LOG_USBH("\r\n"); // duplicate xfer since user can execute control transfer within callback tusb_control_request_t const request = _ctrl_xfer.request; @@ -643,8 +647,8 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result case CONTROL_STAGE_DATA: if (request->wLength) { - TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2); + TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr); + TU_LOG_MEM(USBH_DEBUG, _ctrl_xfer.buffer, xferred_bytes, 2); } _ctrl_xfer.actual_len = (uint16_t) xferred_bytes; @@ -760,7 +764,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; - TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); + TU_LOG_USBH(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); // Attempt to transfer on a busy endpoint, sound like an race condition ! TU_ASSERT(ep_state->busy == 0); @@ -776,7 +780,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) { - TU_LOG2("OK\r\n"); + TU_LOG_USBH("OK\r\n"); return true; }else { @@ -791,7 +795,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) { - TU_LOG2("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size); + TU_LOG_USBH("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size); tusb_desc_endpoint_t ep0_desc = { @@ -960,7 +964,7 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_LOG2("HID Get Report Descriptor\r\n"); + TU_LOG_USBH("HID Get Report Descriptor\r\n"); tusb_control_request_t const request = { .bmRequestType_bit = @@ -999,7 +1003,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_LOG2("Set Configuration = %d\r\n", config_num); + TU_LOG_USBH("Set Configuration = %d\r\n", config_num); tusb_control_request_t const request = { @@ -1103,11 +1107,11 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h (hub_port == 0 || dev->hub_port == hub_port) && // hub_port = 0 means all devices of downstream hub dev->connected) { - TU_LOG2(" Address = %u\r\n", dev_addr); + TU_LOG_USBH(" Address = %u\r\n", dev_addr); if (is_hub_addr(dev_addr)) { - TU_LOG(USBH_DBG_LVL, "HUB address = %u is unmounted\r\n", dev_addr); + TU_LOG(USBH_DEBUG, "HUB address = %u is unmounted\r\n", dev_addr); // If the device itself is a usb hub, unplug downstream devices. // FIXME un-roll recursive calls to prevent potential stack overflow process_device_unplugged(rhport, dev_addr, 0); @@ -1120,7 +1124,7 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h // Close class driver for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { - TU_LOG2("%s close\r\n", usbh_class_drivers[drv_id].name); + TU_LOG_USBH("%s close\r\n", usbh_class_drivers[drv_id].name); usbh_class_drivers[drv_id].close(dev_addr); } @@ -1245,7 +1249,7 @@ static void process_enumeration(tuh_xfer_t* xfer) TU_ASSERT( usbh_edpt_control_open(addr0, 8), ); // Get first 8 bytes of device descriptor for Control Endpoint size - TU_LOG2("Get 8 byte of Device Descriptor\r\n"); + TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR), ); } break; @@ -1254,7 +1258,7 @@ static void process_enumeration(tuh_xfer_t* xfer) case ENUM_RESET_2: // TODO not used by now, but may be needed for some devices !? // Reset device again before Set Address - TU_LOG2("Port reset2 \r\n"); + TU_LOG_USBH("Port reset2 \r\n"); if (_dev0.hub_addr == 0) { // connected directly to roothub @@ -1294,7 +1298,7 @@ static void process_enumeration(tuh_xfer_t* xfer) TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size), ); // Get full device descriptor - TU_LOG2("Get Device Descriptor\r\n"); + TU_LOG_USBH("Get Device Descriptor\r\n"); TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC), ); } break; @@ -1315,7 +1319,7 @@ static void process_enumeration(tuh_xfer_t* xfer) // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; - TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); + TU_LOG_USBH("Get Configuration[0] Descriptor (9 bytes)\r\n"); TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); } break; @@ -1332,7 +1336,7 @@ static void process_enumeration(tuh_xfer_t* xfer) // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; - TU_LOG2("Get Configuration[0] Descriptor\r\n"); + TU_LOG_USBH("Get Configuration[0] Descriptor\r\n"); TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); } break; @@ -1347,7 +1351,7 @@ static void process_enumeration(tuh_xfer_t* xfer) case ENUM_CONFIG_DRIVER: { - TU_LOG2("Device configured\r\n"); + TU_LOG_USBH("Device configured\r\n"); usbh_device_t* dev = get_device(daddr); TU_ASSERT(dev, ); @@ -1387,7 +1391,7 @@ static bool enum_new_device(hcd_event_t* event) if ( !hcd_port_connect_status(_dev0.rhport) ) return true; _dev0.speed = hcd_port_speed_get(_dev0.rhport ); - TU_LOG2("%s Speed\r\n", tu_str_speed[_dev0.speed]); + TU_LOG_USBH("%s Speed\r\n", tu_str_speed[_dev0.speed]); // fake transfer to kick-off the enumeration process tuh_xfer_t xfer; @@ -1444,7 +1448,7 @@ static bool enum_request_set_addr(void) uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); TU_ASSERT(new_addr != 0); - TU_LOG2("Set Address = %d\r\n", new_addr); + TU_LOG_USBH("Set Address = %d\r\n", new_addr); usbh_device_t* new_dev = get_device(new_addr); @@ -1488,9 +1492,12 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur { usbh_device_t* dev = get_device(dev_addr); - uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); + uint16_t const total_len = tu_le16toh(desc_cfg->wTotalLength); + uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + total_len; uint8_t const* p_desc = tu_desc_next(desc_cfg); + TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len); + // parse each interfaces while( p_desc < desc_end ) { @@ -1535,7 +1542,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { // open successfully - TU_LOG2(" %s opened\r\n", driver->name); + TU_LOG_USBH(" %s opened\r\n", driver->name); // bind (associated) interfaces to found driver for(uint8_t i=0; i= USBH_CLASS_DRIVER_COUNT ) { - TU_LOG(USBH_DBG_LVL, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", + TU_LOG(USBH_DEBUG, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); } } @@ -1580,7 +1587,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) if (drv_id != DRVID_INVALID) { usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; - TU_LOG2("%s set config: itf = %u\r\n", driver->name, itf_num); + TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num); driver->set_config(dev_addr, itf_num); break; } @@ -1593,7 +1600,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) if (is_hub_addr(dev_addr)) { - TU_LOG(USBH_DBG_LVL, "HUB address = %u is mounted\r\n", dev_addr); + TU_LOG(USBH_DEBUG, "HUB address = %u is mounted\r\n", dev_addr); }else { // Invoke callback if available -- cgit v1.3.1 From 76021c7359fd330f547a1c22c5c00a23aa5c2bf0 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 11:49:28 +0700 Subject: rename tud_edpt_stream_write_xfer --- src/class/cdc/cdc_host.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 83c623884..79e29796c 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -76,7 +76,7 @@ bool tu_edpt_stream_clear(tu_edpt_stream_t* s) return tu_fifo_clear(&s->ff); } -uint32_t tud_edpt_stream_write_flush(uint8_t dev_addr, tu_edpt_stream_t* s) +uint32_t tud_edpt_stream_write_xfer(uint8_t dev_addr, tu_edpt_stream_t* s) { // No data to send if ( !tu_fifo_count(&s->ff) ) return 0; @@ -114,7 +114,7 @@ uint32_t tu_edpt_stream_write(uint8_t daddr, tu_edpt_stream_t* s, void const *bu if ( (tu_fifo_count(&s->ff) >= bulk_packet_size) /* || ((CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE) && tu_fifo_full(&p_cdc->tx_ff)) */ ) { - tud_edpt_stream_write_flush(daddr, s); + tud_edpt_stream_write_xfer(daddr, s); } return ret; @@ -302,7 +302,7 @@ uint32_t tuh_cdc_write_flush(uint8_t idx) cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tud_edpt_stream_write_flush(p_cdc->daddr, &p_cdc->stream.tx); + return tud_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); } uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) @@ -435,7 +435,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if ( ep_addr == p_cdc->stream.tx.ep_addr ) { - if ( 0 == tud_edpt_stream_write_flush(daddr, &p_cdc->stream.tx) ) + if ( 0 == tud_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP Packet size and not zero -- cgit v1.3.1 From 22b62f871263ae170965a037e4f677a8a8e49709 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 12:07:12 +0700 Subject: add tu_edpt_stream_write_zlp_if_needed() --- src/class/cdc/cdc_host.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 79e29796c..f8d996e17 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -76,15 +76,30 @@ bool tu_edpt_stream_clear(tu_edpt_stream_t* s) return tu_fifo_clear(&s->ff); } -uint32_t tud_edpt_stream_write_xfer(uint8_t dev_addr, tu_edpt_stream_t* s) +bool tu_edpt_stream_write_zlp_if_needed(uint8_t daddr, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { - // No data to send - if ( !tu_fifo_count(&s->ff) ) return 0; + uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + + // ZLP condition: no pending data, last transferred bytes is multiple of packet size + TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (bulk_packet_size-1))) ); + + if ( usbh_edpt_claim(daddr, s->ep_addr) ) + { + TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, NULL, 0) ); + } + + return true; +} + +uint32_t tu_edpt_stream_write_xfer(uint8_t daddr, tu_edpt_stream_t* s) +{ + // skip if no data + TU_VERIFY( tu_fifo_count(&s->ff), 0 ); // Claim the endpoint // uint8_t const rhport = 0; // TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); - TU_VERIFY( usbh_edpt_claim(dev_addr, s->ep_addr) ); + TU_VERIFY( usbh_edpt_claim(daddr, s->ep_addr) ); // Pull data from FIFO -> EP buf uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); @@ -92,7 +107,7 @@ uint32_t tud_edpt_stream_write_xfer(uint8_t dev_addr, tu_edpt_stream_t* s) if ( count ) { //TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); - TU_ASSERT( usbh_edpt_xfer(dev_addr, s->ep_addr, s->ep_buf, count), 0 ); + TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, s->ep_buf, count), 0 ); return count; }else { @@ -100,7 +115,7 @@ uint32_t tud_edpt_stream_write_xfer(uint8_t dev_addr, tu_edpt_stream_t* s) // Note: data is dropped if terminal is not connected //usbd_edpt_release(rhport, p_cdc->ep_in); - usbh_edpt_release(dev_addr, s->ep_addr); + usbh_edpt_release(daddr, s->ep_addr); return 0; } } @@ -114,7 +129,7 @@ uint32_t tu_edpt_stream_write(uint8_t daddr, tu_edpt_stream_t* s, void const *bu if ( (tu_fifo_count(&s->ff) >= bulk_packet_size) /* || ((CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE) && tu_fifo_full(&p_cdc->tx_ff)) */ ) { - tud_edpt_stream_write_xfer(daddr, s); + tu_edpt_stream_write_xfer(daddr, s); } return ret; @@ -302,7 +317,7 @@ uint32_t tuh_cdc_write_flush(uint8_t idx) cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tud_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); } uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) @@ -435,18 +450,11 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if ( ep_addr == p_cdc->stream.tx.ep_addr ) { - if ( 0 == tud_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) + if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) { - // If there is no data left, a ZLP should be sent if + // If there is no data left, a ZLP should be sent if needed // xferred_bytes is multiple of EP Packet size and not zero - uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; - if ( !tu_fifo_count(&p_cdc->stream.tx.ff) && xferred_bytes && (0 == (xferred_bytes & (bulk_packet_size-1))) ) - { - if ( usbh_edpt_claim(daddr, p_cdc->stream.tx.ep_addr) ) - { - usbh_edpt_xfer(daddr, p_cdc->stream.tx.ep_addr, NULL, 0); - } - } + tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); } } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) -- cgit v1.3.1 From badb30a6c3d0748b52d7c9db5a48b7bef21b4c1a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 12:25:13 +0700 Subject: correct cdc host app --- examples/host/cdc_msc_hid/src/cdc_app.c | 17 +++++++++++------ src/class/cdc/cdc_host.c | 3 ++- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index 123cb33f0..db652efde 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -52,26 +52,31 @@ size_t get_console_inputs(uint8_t* buf, size_t bufsize) void cdc_app_task(void) { uint8_t buf[64+1]; // +1 for extra null character - memset(buf, 0, sizeof(buf)); + uint32_t const bufsize = sizeof(buf)-1; - size_t count = get_console_inputs(buf, sizeof(buf)-1); + uint32_t console_count = get_console_inputs(buf, bufsize); + buf[console_count] = 0; // loop over all mounted interfaces - for(size_t idx=0; idx cdc interfaces - if (count) + if (console_count) { - tuh_cdc_write(idx, buf, count); + tuh_cdc_write(idx, buf, console_count); tuh_cdc_write_flush(idx); } // cdc interfaces -> console if ( tuh_cdc_read_available(idx) ) { - printf((char*) buf); + uint8_t buf_cdc[64+1]; + uint32_t cdc_count = tuh_cdc_read(idx, buf_cdc, sizeof(buf_cdc)-1); + buf_cdc[cdc_count] = 0; + + printf((char*) buf_cdc); } } } diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index f8d996e17..326567689 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -459,7 +459,8 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { - tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); + // skip if ZLP + if (xferred_bytes) tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); // invoke receive callback -- cgit v1.3.1 From edc559cb4d9c0c940387b514f2e66c4a2f3a9c1c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 12:29:51 +0700 Subject: fix ci --- src/device/usbd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index f9a7af21b..f652a878e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -39,13 +39,13 @@ // USBD Configuration //--------------------------------------------------------------------+ -// Debug level of USBD -#define USBD_DBG 2 - #ifndef CFG_TUD_TASK_QUEUE_SZ #define CFG_TUD_TASK_QUEUE_SZ 16 #endif +// Debug level of USBD +#define USBD_DBG 2 + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -506,7 +506,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) break; case DCD_EVENT_SETUP_RECEIVED: - TU_LOG_VAR(USBD_DBG, &event.setup_received); + TU_LOG_PTR(USBD_DBG, &event.setup_received); TU_LOG(USBD_DBG, "\r\n"); // Mark as connected after receiving 1st setup packet. -- cgit v1.3.1 From 84a483f5ea7446a5cc1a9fe957379dd1f0a6fd4c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 12:47:00 +0700 Subject: add more host cdc API tuh_cdc_write_available(), tuh_cdc_read_flush(), tuh_cdc_rx_cb() callback --- examples/host/cdc_msc_hid/src/cdc_app.c | 31 +++++++++-------- src/class/cdc/cdc_host.c | 34 ++++++++++++++++++ src/class/cdc/cdc_host.h | 62 +++++++++++---------------------- 3 files changed, 72 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index db652efde..23ea05b2b 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -54,8 +54,8 @@ void cdc_app_task(void) uint8_t buf[64+1]; // +1 for extra null character uint32_t const bufsize = sizeof(buf)-1; - uint32_t console_count = get_console_inputs(buf, bufsize); - buf[console_count] = 0; + uint32_t count = get_console_inputs(buf, bufsize); + buf[count] = 0; // loop over all mounted interfaces for(uint8_t idx=0; idx cdc interfaces - if (console_count) + if (count) { - tuh_cdc_write(idx, buf, console_count); + tuh_cdc_write(idx, buf, count); tuh_cdc_write_flush(idx); } - - // cdc interfaces -> console - if ( tuh_cdc_read_available(idx) ) - { - uint8_t buf_cdc[64+1]; - uint32_t cdc_count = tuh_cdc_read(idx, buf_cdc, sizeof(buf_cdc)-1); - buf_cdc[cdc_count] = 0; - - printf((char*) buf_cdc); - } } } } +// Invoked when received new data +void tuh_cdc_rx_cb(uint8_t idx) +{ + uint8_t buf[64+1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf)-1; + + // forward cdc interfaces -> console + uint32_t count = tuh_cdc_read(idx, buf, bufsize); + buf[count] = 0; + + printf((char*) buf); +} + void tuh_cdc_mount_cb(uint8_t idx) { tuh_cdc_itf_info_t itf_info; diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 326567689..ba2e9e1b7 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -185,6 +185,17 @@ uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s) return (uint32_t) tu_fifo_count(&s->ff); } +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) +{ + return (uint32_t) tu_fifo_remaining(&s->ff); +} + +void tu_edpt_stream_read_clear(uint8_t daddr, tu_edpt_stream_t* s) +{ + tu_fifo_clear(&s->ff); + tu_edpt_stream_read_xfer(daddr, s); +} + typedef struct { uint8_t daddr; uint8_t bInterfaceNumber; @@ -227,6 +238,12 @@ static inline cdch_interface_t* get_itf(uint8_t idx) return (p_cdc->daddr != 0) ? p_cdc : NULL; } +TU_ATTR_ALWAYS_INLINE +static inline uint8_t itf2idx(cdch_interface_t* p_cdc) +{ + return (uint8_t) (p_cdc - cdch_data); +} + static inline cdch_interface_t* get_itf_by_ep_addr(uint8_t daddr, uint8_t ep_addr) { for(uint8_t i=0; idaddr, &p_cdc->stream.tx); } +uint32_t tuh_cdc_write_available(uint8_t idx) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); + + return tu_edpt_stream_write_available(&p_cdc->stream.tx); +} + uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); @@ -336,6 +361,14 @@ uint32_t tuh_cdc_read_available(uint8_t idx) return tu_edpt_stream_read_available(&p_cdc->stream.rx); } +void tuh_cdc_read_flush (uint8_t idx) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc, ); + + tu_edpt_stream_read_clear(p_cdc->daddr, &p_cdc->stream.rx); +} + //--------------------------------------------------------------------+ // Control Endpoint API //--------------------------------------------------------------------+ @@ -463,6 +496,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if (xferred_bytes) tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); // invoke receive callback + if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(itf2idx(p_cdc)); // prepare for next transfer if needed tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 54e082e7d..dd8ae80ce 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -97,18 +97,32 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) return tuh_cdc_get_dtr(idx); } +//--------------------------------------------------------------------+ +// Write API +//--------------------------------------------------------------------+ + +// Get the number of bytes available for writing +uint32_t tuh_cdc_write_available(uint8_t idx); + // Write to cdc interface uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize); // Force sending data if possible, return number of forced bytes uint32_t tuh_cdc_write_flush(uint8_t idx); -// Read from cdc interface -uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize); +//--------------------------------------------------------------------+ +// Read API +//--------------------------------------------------------------------+ // Get the number of bytes available for reading uint32_t tuh_cdc_read_available(uint8_t idx); +// Read from cdc interface +uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize); + +// Clear the received FIFO +void tuh_cdc_read_flush (uint8_t idx); + //--------------------------------------------------------------------+ // Control Endpoint (Request) API //--------------------------------------------------------------------+ @@ -132,47 +146,13 @@ static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, ui // Invoked when a device with CDC interface is mounted // idx is index of cdc interface in the internal pool. -TU_ATTR_WEAK void tuh_cdc_mount_cb(uint8_t idx); +TU_ATTR_WEAK extern void tuh_cdc_mount_cb(uint8_t idx); // Invoked when a device with CDC interface is unmounted -TU_ATTR_WEAK void tuh_cdc_umount_cb(uint8_t idx); - -/** \brief Check if the interface is currently busy or not - * \param[in] dev_addr device address - * \param[in] pipeid value from \ref cdc_pipeid_t to indicate target pipe. - * \retval true if the interface is busy, meaning the stack is still transferring/waiting data from/to device - * \retval false if the interface is not busy, meaning the stack successfully transferred data from/to device - * \note This function is used to check if previous transfer is complete (success or error), so that the next transfer - * can be scheduled. User needs to make sure the corresponding interface is mounted - * (by \ref tuh_cdc_serial_is_mounted) before calling this function. - */ -// bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid); - -/** \brief Perform USB OUT transfer to device - * \param[in] dev_addr device address - * \param[in] p_data Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION) - * \param[in] length Number of bytes to be transferred via USB bus - * \retval TUSB_ERROR_NONE on success - * \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device - * \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request) - * \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct - * \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the - * interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION. - */ -// bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify); - -/** \brief Perform USB IN transfer to get data from device - * \param[in] dev_addr device address - * \param[in] p_buffer Buffer containing received data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION) - * \param[in] length Number of bytes to be transferred via USB bus - * \retval TUSB_ERROR_NONE on success - * \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device - * \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request) - * \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct - * \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the - * interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION. - */ -// bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify); +TU_ATTR_WEAK extern void tuh_cdc_umount_cb(uint8_t idx); + +// Invoked when received new data +TU_ATTR_WEAK extern void tuh_cdc_rx_cb(uint8_t idx); //--------------------------------------------------------------------+ // CDC APPLICATION CALLBACKS -- cgit v1.3.1 From cd9008e5a9c8da81d9736f7e0bf72c5ba409a7f1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 13:05:45 +0700 Subject: add tuh_cdc_tx_complete_cb() callback --- examples/host/cdc_msc_hid/src/cdc_app.c | 4 ++-- src/class/cdc/cdc_host.c | 20 +++++++++----------- src/class/cdc/cdc_host.h | 3 +++ 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index 23ea05b2b..dd3196146 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -87,7 +87,7 @@ void tuh_cdc_rx_cb(uint8_t idx) void tuh_cdc_mount_cb(uint8_t idx) { - tuh_cdc_itf_info_t itf_info; + tuh_cdc_itf_info_t itf_info = { 0 }; tuh_cdc_itf_get_info(idx, &itf_info); printf("CDC Interface is mounted: device address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber); @@ -95,7 +95,7 @@ void tuh_cdc_mount_cb(uint8_t idx) void tuh_cdc_umount_cb(uint8_t idx) { - tuh_cdc_itf_info_t itf_info; + tuh_cdc_itf_info_t itf_info = { 0 }; tuh_cdc_itf_get_info(idx, &itf_info); printf("CDC Interface is unmounted: device address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber); diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index ba2e9e1b7..ce0efe6e3 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -238,13 +238,7 @@ static inline cdch_interface_t* get_itf(uint8_t idx) return (p_cdc->daddr != 0) ? p_cdc : NULL; } -TU_ATTR_ALWAYS_INLINE -static inline uint8_t itf2idx(cdch_interface_t* p_cdc) -{ - return (uint8_t) (p_cdc - cdch_data); -} - -static inline cdch_interface_t* get_itf_by_ep_addr(uint8_t daddr, uint8_t ep_addr) +static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) { for(uint8_t i=0; idaddr == daddr) && (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) { - return p_cdc; + return i; } } - return NULL; + return TUSB_INDEX_INVALID; } @@ -478,11 +472,15 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // TODO handle stall response, retry failed transfer ... TU_ASSERT(event == XFER_RESULT_SUCCESS); - cdch_interface_t * p_cdc = get_itf_by_ep_addr(daddr, ep_addr); + uint8_t const idx = get_idx_by_ep_addr(daddr, ep_addr); + cdch_interface_t * p_cdc = get_itf(idx); TU_ASSERT(p_cdc); if ( ep_addr == p_cdc->stream.tx.ep_addr ) { + // invoke tx complete callback to possibly refill tx fifo + if (tuh_cdc_tx_complete_cb) tuh_cdc_tx_complete_cb(idx); + if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) { // If there is no data left, a ZLP should be sent if needed @@ -496,7 +494,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if (xferred_bytes) tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); // invoke receive callback - if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(itf2idx(p_cdc)); + if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(idx); // prepare for next transfer if needed tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index dd8ae80ce..476431cc5 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -154,6 +154,9 @@ TU_ATTR_WEAK extern void tuh_cdc_umount_cb(uint8_t idx); // Invoked when received new data TU_ATTR_WEAK extern void tuh_cdc_rx_cb(uint8_t idx); +// Invoked when a TX is complete and therefore space becomes available in TX buffer +TU_ATTR_WEAK extern void tuh_cdc_tx_complete_cb(uint8_t idx); + //--------------------------------------------------------------------+ // CDC APPLICATION CALLBACKS //--------------------------------------------------------------------+ -- cgit v1.3.1 From 9e8ea44925e80abd7189ed7a673762527ee3adfd Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 21 Dec 2022 17:46:11 +0700 Subject: add tuh_cdc_write_clear, rename read_flush() to read_clear() --- src/class/cdc/cdc_host.c | 24 +++++++++++++++++++----- src/class/cdc/cdc_host.h | 5 ++++- 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index ce0efe6e3..2f3406378 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -190,10 +190,16 @@ uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) return (uint32_t) tu_fifo_remaining(&s->ff); } -void tu_edpt_stream_read_clear(uint8_t daddr, tu_edpt_stream_t* s) +bool tu_edpt_stream_read_clear(uint8_t daddr, tu_edpt_stream_t* s) { - tu_fifo_clear(&s->ff); + bool ret = tu_fifo_clear(&s->ff); tu_edpt_stream_read_xfer(daddr, s); + return ret; +} + +bool tu_edpt_stream_write_clear(tu_edpt_stream_t* s) +{ + return tu_fifo_clear(&s->ff); } typedef struct { @@ -331,6 +337,14 @@ uint32_t tuh_cdc_write_flush(uint8_t idx) return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); } +bool tuh_cdc_write_clear(uint8_t idx) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); + + return tu_edpt_stream_write_clear(&p_cdc->stream.tx); +} + uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); @@ -355,12 +369,12 @@ uint32_t tuh_cdc_read_available(uint8_t idx) return tu_edpt_stream_read_available(&p_cdc->stream.rx); } -void tuh_cdc_read_flush (uint8_t idx) +bool tuh_cdc_read_clear (uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); - TU_VERIFY(p_cdc, ); + TU_VERIFY(p_cdc); - tu_edpt_stream_read_clear(p_cdc->daddr, &p_cdc->stream.rx); + return tu_edpt_stream_read_clear(p_cdc->daddr, &p_cdc->stream.rx); } //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 476431cc5..02ae69111 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -110,6 +110,9 @@ uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize); // Force sending data if possible, return number of forced bytes uint32_t tuh_cdc_write_flush(uint8_t idx); +// Clear the transmit FIFO +bool tuh_cdc_write_clear(uint8_t idx); + //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ @@ -121,7 +124,7 @@ uint32_t tuh_cdc_read_available(uint8_t idx); uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize); // Clear the received FIFO -void tuh_cdc_read_flush (uint8_t idx); +bool tuh_cdc_read_clear (uint8_t idx); //--------------------------------------------------------------------+ // Control Endpoint (Request) API -- cgit v1.3.1 From 8323e4b79a2052aee814ca8811e841bceb6a7a7d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 00:34:35 +0700 Subject: moving edpt_stream API into common tusb.c --- src/class/cdc/cdc_host.c | 179 ++++++++++---------------------------------- src/common/tusb_private.h | 92 ++++++++++++++++++++++- src/host/usbh.c | 1 - src/host/usbh_classdriver.h | 1 + src/tusb.c | 112 +++++++++++++++++++++++++-- 5 files changed, 239 insertions(+), 146 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 2f3406378..54d81dc0d 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -42,56 +42,23 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -typedef struct { - tu_fifo_t ff; - - // mutex: read if ep rx, write if e tx - OSAL_MUTEX_DEF(ff_mutex); - - // TODO xfer_fifo can skip this buffer - uint8_t* ep_buf; - uint16_t ep_bufsize; - uint8_t ep_addr; -}tu_edpt_stream_t; - -bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool use_wr_mutex, bool overwritable, - void* ff_buf, uint16_t ff_bufsize, - uint8_t* ep_buf, uint16_t ep_bufsize) -{ - osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutex); - (void) new_mutex; - (void) use_wr_mutex; - - tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable); - tu_fifo_config_mutex(&s->ff, use_wr_mutex ? new_mutex : NULL, use_wr_mutex ? NULL : new_mutex); - - s->ep_buf = ep_buf; - s->ep_bufsize = ep_bufsize; - - return true; -} - -bool tu_edpt_stream_clear(tu_edpt_stream_t* s) -{ - return tu_fifo_clear(&s->ff); -} -bool tu_edpt_stream_write_zlp_if_needed(uint8_t daddr, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) +bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { - uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + uint16_t const bulk_packet_size = (s->ep_speed == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; // ZLP condition: no pending data, last transferred bytes is multiple of packet size TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (bulk_packet_size-1))) ); - if ( usbh_edpt_claim(daddr, s->ep_addr) ) + if ( usbh_edpt_claim(s->daddr, s->ep_addr) ) { - TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, NULL, 0) ); + TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, NULL, 0) ); } return true; } -uint32_t tu_edpt_stream_write_xfer(uint8_t daddr, tu_edpt_stream_t* s) +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { // skip if no data TU_VERIFY( tu_fifo_count(&s->ff), 0 ); @@ -99,7 +66,7 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t daddr, tu_edpt_stream_t* s) // Claim the endpoint // uint8_t const rhport = 0; // TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); - TU_VERIFY( usbh_edpt_claim(daddr, s->ep_addr) ); + TU_VERIFY( usbh_edpt_claim(s->daddr, s->ep_addr) ); // Pull data from FIFO -> EP buf uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); @@ -107,7 +74,7 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t daddr, tu_edpt_stream_t* s) if ( count ) { //TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); - TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, s->ep_buf, count), 0 ); + TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 ); return count; }else { @@ -115,93 +82,28 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t daddr, tu_edpt_stream_t* s) // Note: data is dropped if terminal is not connected //usbd_edpt_release(rhport, p_cdc->ep_in); - usbh_edpt_release(daddr, s->ep_addr); + usbh_edpt_release(s->daddr, s->ep_addr); return 0; } } -uint32_t tu_edpt_stream_write(uint8_t daddr, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize) -{ - uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); - - // flush if queue more than packet size - uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; - if ( (tu_fifo_count(&s->ff) >= bulk_packet_size) - /* || ((CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE) && tu_fifo_full(&p_cdc->tx_ff)) */ ) - { - tu_edpt_stream_write_xfer(daddr, s); - } - - return ret; -} - -void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) -{ - tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); -} - -uint32_t tu_edpt_stream_read_xfer(uint8_t daddr, tu_edpt_stream_t* s) +uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize) { - uint16_t available = tu_fifo_remaining(&s->ff); + TU_VERIFY(bufsize); // TODO support ZLP - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; - TU_VERIFY(available >= bulk_packet_size); - - // claim endpoint - TU_VERIFY(usbh_edpt_claim(daddr, s->ep_addr), 0); - - // fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&s->ff); - - if ( available >= bulk_packet_size ) - { - // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & (bulk_packet_size -1)); - count = tu_min16(count, s->ep_bufsize); + uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); - TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, s->ep_buf, count), 0 ); - return count; - }else + // flush if fifo has more than packet size or + // in rare case: fifo depth is configured too small (which never reach packet size) + uint16_t const bulk_packet_size = (s->ep_speed == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + if ( (tu_fifo_count(&s->ff) >= bulk_packet_size) || ( tu_fifo_depth(&s->ff) < bulk_packet_size) ) { - // Release endpoint since we don't make any transfer - usbh_edpt_release(daddr, s->ep_addr); - return 0; + tu_edpt_stream_write_xfer(s); } -} - -uint32_t tu_edpt_stream_read(uint8_t daddr, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) -{ - uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize); - tu_edpt_stream_read_xfer(daddr, s); - return num_read; -} - -uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s) -{ - return (uint32_t) tu_fifo_count(&s->ff); -} - -uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) -{ - return (uint32_t) tu_fifo_remaining(&s->ff); -} -bool tu_edpt_stream_read_clear(uint8_t daddr, tu_edpt_stream_t* s) -{ - bool ret = tu_fifo_clear(&s->ff); - tu_edpt_stream_read_xfer(daddr, s); return ret; } -bool tu_edpt_stream_write_clear(tu_edpt_stream_t* s) -{ - return tu_fifo_clear(&s->ff); -} - typedef struct { uint8_t daddr; uint8_t bInterfaceNumber; @@ -326,7 +228,7 @@ uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize); + return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize); } uint32_t tuh_cdc_write_flush(uint8_t idx) @@ -334,7 +236,7 @@ uint32_t tuh_cdc_write_flush(uint8_t idx) cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); } bool tuh_cdc_write_clear(uint8_t idx) @@ -342,7 +244,7 @@ bool tuh_cdc_write_clear(uint8_t idx) cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_clear(&p_cdc->stream.tx); + return tu_edpt_stream_clear(&p_cdc->stream.tx); } uint32_t tuh_cdc_write_available(uint8_t idx) @@ -358,7 +260,7 @@ uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); } uint32_t tuh_cdc_read_available(uint8_t idx) @@ -374,7 +276,9 @@ bool tuh_cdc_read_clear (uint8_t idx) cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_read_clear(p_cdc->daddr, &p_cdc->stream.rx); + bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + return ret; } //--------------------------------------------------------------------+ @@ -452,13 +356,13 @@ void cdch_init(void) { cdch_interface_t* p_cdc = &cdch_data[i]; - tu_edpt_stream_init(&p_cdc->stream.tx, true, false, - p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, + p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, + p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); - tu_edpt_stream_init(&p_cdc->stream.rx, false, false, - p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); + tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, + p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, + p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); } } @@ -475,8 +379,6 @@ void cdch_close(uint8_t daddr) //tu_memclr(p_cdc, sizeof(cdch_interface_t)); p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; - tu_edpt_stream_clear(&p_cdc->stream.tx); - tu_edpt_stream_clear(&p_cdc->stream.rx); } } } @@ -495,23 +397,22 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // invoke tx complete callback to possibly refill tx fifo if (tuh_cdc_tx_complete_cb) tuh_cdc_tx_complete_cb(idx); - if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) + if ( 0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx) ) { // If there is no data left, a ZLP should be sent if needed // xferred_bytes is multiple of EP Packet size and not zero - tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); } } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { - // skip if ZLP - if (xferred_bytes) tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); + tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); // invoke receive callback if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(idx); // prepare for next transfer if needed - tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); + tu_edpt_stream_read_xfer(&p_cdc->stream.rx); }else if ( ep_addr == p_cdc->ep_notif ) { // TODO handle notification endpoint @@ -527,7 +428,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // Enumeration //--------------------------------------------------------------------+ -bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; @@ -542,7 +443,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it cdch_interface_t * p_cdc = find_new_itf(); TU_VERIFY(p_cdc); - p_cdc->daddr = dev_addr; + p_cdc->daddr = daddr; p_cdc->bInterfaceNumber = itf_desc->bInterfaceNumber; p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; p_cdc->bInterfaceProtocol = itf_desc->bInterfaceProtocol; @@ -569,7 +470,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)); tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT( tuh_edpt_open(dev_addr, desc_ep) ); + TU_ASSERT( tuh_edpt_open(daddr, desc_ep) ); p_cdc->ep_notif = desc_ep->bEndpointAddress; p_desc = tu_desc_next(p_desc); @@ -589,14 +490,14 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); - TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep)); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) { - p_cdc->stream.rx.ep_addr = desc_ep->bEndpointAddress; + tu_edpt_stream_open(&p_cdc->stream.rx, daddr, desc_ep); }else { - p_cdc->stream.tx.ep_addr = desc_ep->bEndpointAddress; + tu_edpt_stream_open(&p_cdc->stream.tx, daddr, desc_ep); } p_desc = tu_desc_next(p_desc); @@ -616,7 +517,7 @@ static void config_cdc_complete(uint8_t daddr, uint8_t itf_num) // Prepare for incoming data cdch_interface_t* p_cdc = get_itf(idx); - tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); + tu_edpt_stream_read_xfer(&p_cdc->stream.rx); } // notify usbh that driver enumeration is complete diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index b34506f65..01078eed3 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -28,6 +28,8 @@ #ifndef _TUSB_PRIVATE_H_ #define _TUSB_PRIVATE_H_ +// Internal Helper used by Host and Device Stack + #ifdef __cplusplus extern "C" { #endif @@ -39,8 +41,31 @@ typedef struct TU_ATTR_PACKED volatile uint8_t claimed : 1; }tu_edpt_state_t; +typedef struct { + bool is_host; // host or device most + union { + uint8_t daddr; + uint8_t rhport; + uint8_t hwid; + }; + uint8_t ep_addr; + uint8_t ep_speed; + + uint16_t ep_packetsize; + uint16_t ep_bufsize; + + // TODO xfer_fifo can skip this buffer + uint8_t* ep_buf; + + tu_fifo_t ff; + + // mutex: read if ep rx, write if e tx + OSAL_MUTEX_DEF(ff_mutex); + +}tu_edpt_stream_t; + //--------------------------------------------------------------------+ -// Internal Helper used by Host and Device Stack +// Endpoint //--------------------------------------------------------------------+ // Check if endpoint descriptor is valid per USB specs @@ -58,6 +83,71 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex); // Release an endpoint with provided mutex bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); +//--------------------------------------------------------------------+ +// Endpoint Stream +//--------------------------------------------------------------------+ + +// Init an stream, should only called once +bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, + void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize); + +// Open an stream for an endpoint +// hwid is either device address (host mode) or rhport (device mode) +TU_ATTR_ALWAYS_INLINE static inline +void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) +{ + tu_fifo_clear(&s->ff); + s->hwid = hwid; + s->ep_addr = desc_ep->bEndpointAddress; + s->ep_packetsize = tu_edpt_packet_size(desc_ep); +} + +// Clear fifo +TU_ATTR_ALWAYS_INLINE static inline +bool tu_edpt_stream_clear(tu_edpt_stream_t* s) +{ + return tu_fifo_clear(&s->ff); +} + +//------------- Write -------------// + +// Write to stream +uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); + +// Start an usb transfer if endpoint is not busy +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s); + +// Get the number of bytes available for writing +TU_ATTR_ALWAYS_INLINE static inline +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) +{ + return (uint32_t) tu_fifo_remaining(&s->ff); +} + + +//------------- Read -------------// + +// Read from stream +uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize); + +// Start an usb transfer if endpoint is not busy +uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s); + +// Must be called in the transfer complete callback +TU_ATTR_ALWAYS_INLINE static inline +void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) +{ + tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); +} + +// Get the number of bytes available for reading +TU_ATTR_ALWAYS_INLINE static inline +uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s) +{ + return (uint32_t) tu_fifo_count(&s->ff); +} + + #ifdef __cplusplus } #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index 36fc5fded..f0ca7be2e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -30,7 +30,6 @@ #include "host/hcd.h" #include "tusb.h" -#include "common/tusb_private.h" #include "host/usbh_classdriver.h" #include "hub.h" diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index 7f72560c3..be9811641 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -29,6 +29,7 @@ #include "osal/osal.h" #include "common/tusb_fifo.h" +#include "common/tusb_private.h" #ifdef __cplusplus extern "C" { diff --git a/src/tusb.c b/src/tusb.c index f4380f89c..05e0d4c1f 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -31,11 +31,18 @@ #include "tusb.h" #include "common/tusb_private.h" -// TODO clean up #if CFG_TUD_ENABLED #include "device/usbd_pvt.h" #endif +#if CFG_TUH_ENABLED +#include "host/usbh_classdriver.h" +#endif + +//--------------------------------------------------------------------+ +// Public API +//--------------------------------------------------------------------+ + bool tusb_init(void) { #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) @@ -67,7 +74,7 @@ bool tusb_inited(void) } //--------------------------------------------------------------------+ -// Internal Helper for both Host and Device stack +// Endpoint Helper for both Host and Device stack //--------------------------------------------------------------------+ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) @@ -196,9 +203,104 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, return len; } -/*------------------------------------------------------------------*/ -/* Debug - *------------------------------------------------------------------*/ +//--------------------------------------------------------------------+ +// Endpoint Stream Helper for both Host and Device stack +//--------------------------------------------------------------------+ + +bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, + void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) +{ + osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutex); + (void) new_mutex; + (void) is_tx; + + s->is_host = is_host; + tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable); + tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex); + + s->ep_buf = ep_buf; + s->ep_bufsize = ep_bufsize; + + return true; +} + +//------------- Stream Write -------------// + +//------------- Stream Read -------------// + +uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) +{ + uint16_t available = tu_fifo_remaining(&s->ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + TU_VERIFY(available >= s->ep_packetsize); + + // claim endpoint + if (s->is_host) + { + #if CFG_TUH_ENABLED + TU_VERIFY(usbh_edpt_claim(s->daddr, s->ep_addr), 0); + #endif + }else + { + #if CFG_TUD_ENABLED + TU_VERIFY(usbd_edpt_claim(s->rhport, s->ep_addr), 0); + #endif + } + + // get available again since fifo can be changed before endpoint is claimed + available = tu_fifo_remaining(&s->ff); + + if ( available >= s->ep_packetsize ) + { + // multiple of packet size limit by ep bufsize + uint16_t count = (uint16_t) (available & (s->ep_packetsize -1)); + count = tu_min16(count, s->ep_bufsize); + + if (s->is_host) + { + #if CFG_TUH_ENABLED + TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 ); + #endif + }else + { + #if CFG_TUD_ENABLED + TU_ASSERT( usbd_edpt_xfer(s->rhport, s->ep_addr, s->ep_buf, count), 0 ); + #endif + } + return count; + }else + { + // Release endpoint since we don't make any transfer + if (s->is_host) + { + #if CFG_TUH_ENABLED + usbh_edpt_release(s->daddr, s->ep_addr); + #endif + }else + { + #if CFG_TUD_ENABLED + usbd_edpt_release(s->rhport, s->ep_addr); + #endif + } + + return 0; + } +} + +uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) +{ + uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize); + tu_edpt_stream_read_xfer(s); + return num_read; +} + +//--------------------------------------------------------------------+ +// Debug +//--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG #include -- cgit v1.3.1 From e3c9d9450009f757b9ddf5f94a00f14e7cfb0471 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 11:16:39 +0700 Subject: fix stream read count computation --- src/class/cdc/cdc_host.c | 63 +------------------------------ src/common/tusb_private.h | 21 +++++++++-- src/tusb.c | 96 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 101 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 54d81dc0d..469725e72 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -43,67 +43,6 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) -{ - uint16_t const bulk_packet_size = (s->ep_speed == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; - - // ZLP condition: no pending data, last transferred bytes is multiple of packet size - TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (bulk_packet_size-1))) ); - - if ( usbh_edpt_claim(s->daddr, s->ep_addr) ) - { - TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, NULL, 0) ); - } - - return true; -} - -uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) -{ - // skip if no data - TU_VERIFY( tu_fifo_count(&s->ff), 0 ); - - // Claim the endpoint - // uint8_t const rhport = 0; - // TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); - TU_VERIFY( usbh_edpt_claim(s->daddr, s->ep_addr) ); - - // Pull data from FIFO -> EP buf - uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); - - if ( count ) - { - //TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); - TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 ); - return count; - }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); - - usbh_edpt_release(s->daddr, s->ep_addr); - return 0; - } -} - -uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize) -{ - TU_VERIFY(bufsize); // TODO support ZLP - - uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); - - // flush if fifo has more than packet size or - // in rare case: fifo depth is configured too small (which never reach packet size) - uint16_t const bulk_packet_size = (s->ep_speed == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; - if ( (tu_fifo_count(&s->ff) >= bulk_packet_size) || ( tu_fifo_depth(&s->ff) < bulk_packet_size) ) - { - tu_edpt_stream_write_xfer(s); - } - - return ret; -} - typedef struct { uint8_t daddr; uint8_t bInterfaceNumber; @@ -379,6 +318,8 @@ void cdch_close(uint8_t daddr) //tu_memclr(p_cdc, sizeof(cdch_interface_t)); p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; + tu_edpt_stream_close(&p_cdc->stream.tx); + tu_edpt_stream_close(&p_cdc->stream.rx); } } } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 01078eed3..d0c7a84fb 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -87,7 +87,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); // Endpoint Stream //--------------------------------------------------------------------+ -// Init an stream, should only called once +// Init an stream, should only be called once bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize); @@ -102,6 +102,13 @@ void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t s->ep_packetsize = tu_edpt_packet_size(desc_ep); } +TU_ATTR_ALWAYS_INLINE static inline +void tu_edpt_stream_close(tu_edpt_stream_t* s) +{ + s->hwid = 0; + s->ep_addr = 0; +} + // Clear fifo TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t* s) @@ -109,7 +116,9 @@ bool tu_edpt_stream_clear(tu_edpt_stream_t* s) return tu_fifo_clear(&s->ff); } -//------------- Write -------------// +//--------------------------------------------------------------------+ +// Stream Write +//--------------------------------------------------------------------+ // Write to stream uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); @@ -117,6 +126,9 @@ uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t // Start an usb transfer if endpoint is not busy uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s); +// Start an zero-length packet if needed +bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes); + // Get the number of bytes available for writing TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) @@ -124,8 +136,9 @@ uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) return (uint32_t) tu_fifo_remaining(&s->ff); } - -//------------- Read -------------// +//--------------------------------------------------------------------+ +// Stream Read +//--------------------------------------------------------------------+ // Read from stream uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize); diff --git a/src/tusb.c b/src/tusb.c index 05e0d4c1f..0d0e84a49 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -224,9 +224,86 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } -//------------- Stream Write -------------// +TU_ATTR_ALWAYS_INLINE static inline +bool stream_claim(tu_edpt_stream_t* s) +{ + if (s->is_host) + { + #if CFG_TUH_ENABLED + return usbh_edpt_claim(s->daddr, s->ep_addr); + #endif + }else + { + #if CFG_TUD_ENABLED + return usbd_edpt_claim(s->rhport, s->ep_addr); + #endif + } + + return false; +} -//------------- Stream Read -------------// + +//--------------------------------------------------------------------+ +// Stream Write +//--------------------------------------------------------------------+ + +bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) +{ + // ZLP condition: no pending data, last transferred bytes is multiple of packet size + TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize-1))) ); + + TU_VERIFY( stream_claim(s) ); + TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, NULL, 0) ); + + return true; +} + +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) +{ + // skip if no data + TU_VERIFY( tu_fifo_count(&s->ff), 0 ); + + // Claim the endpoint + TU_VERIFY( stream_claim(s), 0 ); + + // Pull data from FIFO -> EP buf + uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + + if ( count ) + { + //TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); + TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 ); + return count; + }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); + + usbh_edpt_release(s->daddr, s->ep_addr); + return 0; + } +} + +uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize) +{ + TU_VERIFY(bufsize); // TODO support ZLP + + uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); + + // flush if fifo has more than packet size or + // in rare case: fifo depth is configured too small (which never reach packet size) + if ( (tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize) ) + { + tu_edpt_stream_write_xfer(s); + } + + return ret; +} + +//--------------------------------------------------------------------+ +// Stream Read +//--------------------------------------------------------------------+ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { @@ -239,17 +316,7 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) TU_VERIFY(available >= s->ep_packetsize); // claim endpoint - if (s->is_host) - { - #if CFG_TUH_ENABLED - TU_VERIFY(usbh_edpt_claim(s->daddr, s->ep_addr), 0); - #endif - }else - { - #if CFG_TUD_ENABLED - TU_VERIFY(usbd_edpt_claim(s->rhport, s->ep_addr), 0); - #endif - } + TU_VERIFY(stream_claim(s), 0); // get available again since fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&s->ff); @@ -257,7 +324,7 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) if ( available >= s->ep_packetsize ) { // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & (s->ep_packetsize -1)); + uint16_t count = (uint16_t) (available & ~(s->ep_packetsize -1)); count = tu_min16(count, s->ep_bufsize); if (s->is_host) @@ -301,6 +368,7 @@ uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ + #if CFG_TUSB_DEBUG #include -- cgit v1.3.1 From 2d536123c8ff8dd233656f0a9d7c16aff606302d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 11:31:37 +0700 Subject: finish moving edpt stream to tusb.c --- src/class/cdc/cdc_host.c | 4 +-- src/tusb.c | 69 ++++++++++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 469725e72..de1466cb1 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -340,8 +340,8 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if ( 0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx) ) { - // If there is no data left, a ZLP should be sent if needed - // xferred_bytes is multiple of EP Packet size and not zero + // If there is no data left, a ZLP should be sent if: + // - xferred_bytes is multiple of EP Packet size and not zero tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); } } diff --git a/src/tusb.c b/src/tusb.c index 0d0e84a49..8f64f4acf 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -242,6 +242,41 @@ bool stream_claim(tu_edpt_stream_t* s) return false; } +TU_ATTR_ALWAYS_INLINE static inline +bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) +{ + if (s->is_host) + { + #if CFG_TUH_ENABLED + return usbh_edpt_xfer(s->daddr, s->ep_addr, count ? s->ep_buf : NULL, count); + #endif + }else + { + #if CFG_TUD_ENABLED + return usbd_edpt_xfer(s->rhport, s->ep_addr, cont ? s->ep_buf : NULL, count); + #endif + } + + return false; +} + +TU_ATTR_ALWAYS_INLINE static inline +bool stream_release(tu_edpt_stream_t* s) +{ + if (s->is_host) + { + #if CFG_TUH_ENABLED + return usbh_edpt_release(s->daddr, s->ep_addr); + #endif + }else + { + #if CFG_TUD_ENABLED + return usbd_edpt_release(s->rhport, s->ep_addr); + #endif + } + + return false; +} //--------------------------------------------------------------------+ // Stream Write @@ -253,7 +288,7 @@ bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferr TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize-1))) ); TU_VERIFY( stream_claim(s) ); - TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, NULL, 0) ); + TU_ASSERT( stream_xfer(s, 0) ); return true; } @@ -271,16 +306,13 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) if ( count ) { - //TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); - TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 ); + TU_ASSERT( stream_xfer(s, count), 0 ); return count; }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); - - usbh_edpt_release(s->daddr, s->ep_addr); + stream_release(s); return 0; } } @@ -327,32 +359,13 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) uint16_t count = (uint16_t) (available & ~(s->ep_packetsize -1)); count = tu_min16(count, s->ep_bufsize); - if (s->is_host) - { - #if CFG_TUH_ENABLED - TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 ); - #endif - }else - { - #if CFG_TUD_ENABLED - TU_ASSERT( usbd_edpt_xfer(s->rhport, s->ep_addr, s->ep_buf, count), 0 ); - #endif - } + TU_ASSERT( stream_xfer(s, count), 0 ); + return count; }else { // Release endpoint since we don't make any transfer - if (s->is_host) - { - #if CFG_TUH_ENABLED - usbh_edpt_release(s->daddr, s->ep_addr); - #endif - }else - { - #if CFG_TUD_ENABLED - usbd_edpt_release(s->rhport, s->ep_addr); - #endif - } + stream_release(s); return 0; } -- cgit v1.3.1 From c99af908f10103c0829c4adc1ef74832c3ca4482 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 11:41:27 +0700 Subject: fix typo --- src/tusb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/tusb.c b/src/tusb.c index 8f64f4acf..a5c820b8d 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -253,7 +253,7 @@ bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) }else { #if CFG_TUD_ENABLED - return usbd_edpt_xfer(s->rhport, s->ep_addr, cont ? s->ep_buf : NULL, count); + return usbd_edpt_xfer(s->rhport, s->ep_addr, count ? s->ep_buf : NULL, count); #endif } @@ -366,7 +366,6 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { // Release endpoint since we don't make any transfer stream_release(s); - return 0; } } -- cgit v1.3.1 From 11233e4d3e04ceab1ad6e33d37a166aa48c436de Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 11:43:57 +0700 Subject: minor clean up --- examples/host/cdc_msc_hid/src/tusb_config.h | 4 ++++ src/class/cdc/cdc_host.h | 28 +++++----------------------- 2 files changed, 9 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index c515405cb..e3d9356f6 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -108,6 +108,10 @@ #define CFG_TUH_HID_EPIN_BUFSIZE 64 #define CFG_TUH_HID_EPOUT_BUFSIZE 64 +//------------- CDC -------------// +// Set both DTR ( bit 0), RTS (bit 1) on enumeration/mounted +#define CFG_TUH_CDC_SET_DTRRTS_ON_ENUM 0x03 + #ifdef __cplusplus } #endif diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 02ae69111..5407c646d 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -49,7 +49,7 @@ // RX Endpoint size #ifndef CFG_TUH_CDC_RX_EPSIZE -#define CFG_TUH_CDC_RX_EPSIZE USBH_EPSIZE_BULK_MAX +#define CFG_TUH_CDC_RX_EPSIZE USBH_EPSIZE_BULK_MAX #endif // TX FIFO size @@ -59,7 +59,7 @@ // TX Endpoint size #ifndef CFG_TUH_CDC_TX_EPSIZE -#define CFG_TUH_CDC_TX_EPSIZE USBH_EPSIZE_BULK_MAX +#define CFG_TUH_CDC_TX_EPSIZE USBH_EPSIZE_BULK_MAX #endif //--------------------------------------------------------------------+ @@ -145,7 +145,9 @@ static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, ui return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data); } -//------------- Application Callback -------------// +//--------------------------------------------------------------------+ +// CDC APPLICATION CALLBACKS +//--------------------------------------------------------------------+ // Invoked when a device with CDC interface is mounted // idx is index of cdc interface in the internal pool. @@ -160,26 +162,6 @@ TU_ATTR_WEAK extern void tuh_cdc_rx_cb(uint8_t idx); // Invoked when a TX is complete and therefore space becomes available in TX buffer TU_ATTR_WEAK extern void tuh_cdc_tx_complete_cb(uint8_t idx); -//--------------------------------------------------------------------+ -// CDC APPLICATION CALLBACKS -//--------------------------------------------------------------------+ - -/** \brief Callback function that is invoked when an transferring event occurred - * \param[in] dev_addr Address of device - * \param[in] event an value from \ref xfer_result_t - * \param[in] pipe_id value from \ref cdc_pipeid_t indicate the pipe - * \param[in] xferred_bytes Number of bytes transferred via USB bus - * \note event can be one of following - * - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully. - * - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error. - * - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device. - * \note - */ -// void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes); - -/// @} // group CDC_Serial_Host -/// @} - //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -- cgit v1.3.1 From 05c119ce975668eff814c78d5306589fc2d24530 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 18:28:06 +0700 Subject: cdc host, add set line coding API --- examples/host/cdc_msc_hid/src/tusb_config.h | 11 ++- src/class/cdc/cdc.h | 28 ++++-- src/class/cdc/cdc_host.c | 129 +++++++++++++++++++++------- src/class/cdc/cdc_host.h | 16 +++- 4 files changed, 143 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index e3d9356f6..139a921d1 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -109,8 +109,15 @@ #define CFG_TUH_HID_EPOUT_BUFSIZE 64 //------------- CDC -------------// -// Set both DTR ( bit 0), RTS (bit 1) on enumeration/mounted -#define CFG_TUH_CDC_SET_DTRRTS_ON_ENUM 0x03 + +// Set Line Control state on enumeration/mounted: +// DTR ( bit 0), RTS (bit 1) +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 + +// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t +// bit rate = 115200, 1 stop bit, no parity, 8 bit data width +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } + #ifdef __cplusplus } diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index 6a9669cf2..9a3fc21ee 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -198,6 +198,22 @@ enum CDC_CONTROL_LINE_STATE_RTS = 0x02, }; +enum +{ + CDC_LINE_CONDING_STOP_BITS_1 = 0, // 1 bit + CDC_LINE_CONDING_STOP_BITS_1_5 = 1, // 1.5 bits + CDC_LINE_CONDING_STOP_BITS_2 = 2, // 2 bits +}; + +enum +{ + CDC_LINE_CODING_PARITY_NONE = 0, + CDC_LINE_CODING_PARITY_ODD = 1, + CDC_LINE_CODING_PARITY_EVEN = 2, + CDC_LINE_CODING_PARITY_MARK = 3, + CDC_LINE_CODING_PARITY_SPACE = 4, +}; + //--------------------------------------------------------------------+ // Management Element Notification (Notification Endpoint) //--------------------------------------------------------------------+ @@ -207,13 +223,13 @@ typedef enum { CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status. CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request. - CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, - CDC_NOTIF_RING_DETECT = 0x09, - CDC_NOTIF_SERIAL_STATE = 0x20, - CDC_NOTIF_CALL_STATE_CHANGE = 0x28, - CDC_NOTIF_LINE_STATE_CHANGE = 0x29, + CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08,///< CDC_NOTIF_AUX_JACK_HOOK_STATE + CDC_NOTIF_RING_DETECT = 0x09,///< CDC_NOTIF_RING_DETECT + CDC_NOTIF_SERIAL_STATE = 0x20,///< CDC_NOTIF_SERIAL_STATE + CDC_NOTIF_CALL_STATE_CHANGE = 0x28,///< CDC_NOTIF_CALL_STATE_CHANGE + CDC_NOTIF_LINE_STATE_CHANGE = 0x29,///< CDC_NOTIF_LINE_STATE_CHANGE CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred - CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40, + CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40,///< CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION }cdc_notification_request_t; //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index de1466cb1..fcabb922a 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -52,8 +52,8 @@ typedef struct { cdc_acm_capability_t acm_capability; uint8_t ep_notif; - // Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) - uint8_t line_state; + cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width + uint8_t line_state; // DTR (bit0), RTS (bit1) tuh_xfer_cb_t user_control_cb; @@ -240,6 +240,13 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) p_cdc->line_state = (uint8_t) tu_le16toh(xfer->setup->wValue); break; + case CDC_REQUEST_SET_LINE_CODING: + { + uint16_t const len = tu_min16(sizeof(cdc_line_coding_t), tu_le16toh(xfer->setup->wLength)); + memcpy(&p_cdc->line_coding, xfer->buffer, len); + } + break; + default: break; } } @@ -265,7 +272,7 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c }, .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, .wValue = tu_htole16(line_state), - .wIndex = tu_htole16(p_cdc->bInterfaceNumber), + .wIndex = tu_htole16((uint16_t) p_cdc->bInterfaceNumber), .wLength = 0 }; @@ -283,6 +290,46 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c return tuh_control_xfer(&xfer); } +bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc && p_cdc->acm_capability.support_line_request); + + TU_LOG_CDCH("CDC Set Line Conding\r\n"); + + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = CDC_REQUEST_SET_LINE_CODING, + .wValue = 0, + .wIndex = tu_htole16(p_cdc->bInterfaceNumber), + .wLength = tu_htole16(sizeof(cdc_line_coding_t)) + }; + + // use usbh enum buf to hold line coding since user line_coding variable may not live long enough + // for the transfer to complete + uint8_t* enum_buf = usbh_get_enum_buf(); + memcpy(enum_buf, line_coding, sizeof(cdc_line_coding_t)); + + p_cdc->user_control_cb = complete_cb; + tuh_xfer_t xfer = + { + .daddr = p_cdc->daddr, + .ep_addr = 0, + .setup = &request, + .buffer = enum_buf, + .complete_cb = cdch_internal_control_complete, + .user_data = user_data + }; + + return tuh_control_xfer(&xfer); +} + //--------------------------------------------------------------------+ // CLASS-USBH API //--------------------------------------------------------------------+ @@ -448,46 +495,70 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d return true; } -static void config_cdc_complete(uint8_t daddr, uint8_t itf_num) +enum { - uint8_t const idx = tuh_cdc_itf_get_index(daddr, itf_num); + CONFIG_SET_CONTROL_LINE_STATE, + CONFIG_SET_LINE_CODING, + CONFIG_COMPLETE +}; - if (idx != TUSB_INDEX_INVALID) +static void process_cdc_config(tuh_xfer_t* xfer) +{ + uintptr_t const state = xfer->user_data; + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + TU_ASSERT(idx != TUSB_INDEX_INVALID, ); + + switch(state) { - if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); + case CONFIG_SET_CONTROL_LINE_STATE: + #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM + TU_ASSERT( tuh_cdc_set_control_line_state(idx, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, process_cdc_config, CONFIG_SET_LINE_CODING), ); + break; + #endif + TU_ATTR_FALLTHROUGH; - // Prepare for incoming data - cdch_interface_t* p_cdc = get_itf(idx); - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); - } + case CONFIG_SET_LINE_CODING: + #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + { + cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; + TU_ASSERT( tuh_cdc_set_line_coding(idx, &line_coding, process_cdc_config, 0), ); + break; + } + #endif + TU_ATTR_FALLTHROUGH; - // notify usbh that driver enumeration is complete - // itf_num+1 to account for data interface as well - usbh_driver_set_config_complete(daddr, itf_num+1); -} + case CONFIG_COMPLETE: + if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); -#if CFG_TUH_CDC_SET_DTRRTS_ON_ENUM + // Prepare for incoming data + cdch_interface_t* p_cdc = get_itf(idx); + tu_edpt_stream_read_xfer(&p_cdc->stream.rx); -static void config_set_dtr_rts_complete (tuh_xfer_t* xfer) -{ - uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - config_cdc_complete(xfer->daddr, itf_num); + // notify usbh that driver enumeration is complete + // itf_num+1 to account for data interface as well + usbh_driver_set_config_complete(xfer->daddr, itf_num+1); + break; + + default: break; + } } bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { - uint8_t const idx = tuh_cdc_itf_get_index(daddr, itf_num); - return tuh_cdc_set_control_line_state(idx, CFG_TUH_CDC_SET_DTRRTS_ON_ENUM, config_set_dtr_rts_complete, 0); -} + // fake transfer to kick-off process + tusb_control_request_t request; + request.wIndex = tu_htole16((uint16_t) itf_num); -#else + tuh_xfer_t xfer; + xfer.daddr = daddr; + xfer.result = XFER_RESULT_SUCCESS; + xfer.setup = &request; + xfer.user_data = CONFIG_SET_CONTROL_LINE_STATE; + + process_cdc_config(&xfer); -bool cdch_set_config(uint8_t daddr, uint8_t itf_num) -{ - config_cdc_complete(daddr, itf_num); return true; } #endif - -#endif diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 5407c646d..9bf5af46c 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -37,11 +37,16 @@ // Class Driver Configuration //--------------------------------------------------------------------+ -// Set DTR ( bit 0), RTS (bit 1) on enumeration/mounted -#ifndef CFG_TUH_CDC_SET_DTRRTS_ON_ENUM -#define CFG_TUH_CDC_SET_DTRRTS_ON_ENUM 0 +// Set Line Control state on enumeration/mounted: DTR ( bit 0), RTS (bit 1) +#ifndef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0 #endif +// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t +//#ifndef CFG_TUH_CDC_LINE_CODING_ON_ENUM +//#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } +//#endif + // RX FIFO size #ifndef CFG_TUH_CDC_RX_BUFSIZE #define CFG_TUH_CDC_RX_BUFSIZE USBH_EPSIZE_BULK_MAX @@ -130,9 +135,12 @@ bool tuh_cdc_read_clear (uint8_t idx); // Control Endpoint (Request) API //--------------------------------------------------------------------+ -// Send control request to Set Control Line State: DTR (bit 0), RTS (bit 1) +// Request to Set Control Line State: DTR (bit 0), RTS (bit 1) bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +// Request to Set Line Coding +bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + // Connect by set both DTR, RTS static inline bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { -- cgit v1.3.1 From 14d45b580e0cd82e77e36ecb152f7c001d860ce7 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 19:17:09 +0700 Subject: correct host cdc enum --- src/class/cdc/cdc_host.c | 2 +- src/host/usbh.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index fcabb922a..05e0bdfc7 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -522,7 +522,7 @@ static void process_cdc_config(tuh_xfer_t* xfer) #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM { cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; - TU_ASSERT( tuh_cdc_set_line_coding(idx, &line_coding, process_cdc_config, 0), ); + TU_ASSERT( tuh_cdc_set_line_coding(idx, &line_coding, process_cdc_config, CONFIG_COMPLETE), ); break; } #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index f0ca7be2e..af1e67d4d 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -330,6 +330,8 @@ bool tuh_init(uint8_t controller_id) TU_LOG_INT(USBH_DEBUG, sizeof(hcd_event_t)); TU_LOG_INT(USBH_DEBUG, sizeof(_ctrl_xfer)); TU_LOG_INT(USBH_DEBUG, sizeof(tuh_xfer_t)); + TU_LOG_INT(USBH_DEBUG, sizeof(tu_fifo_t)); + TU_LOG_INT(USBH_DEBUG, sizeof(tu_edpt_stream_t)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -1275,7 +1277,7 @@ static void process_enumeration(tuh_xfer_t* xfer) break; } #endif - __attribute__((fallthrough)); + TU_ATTR_FALLTHROUGH; #endif case ENUM_SET_ADDR: -- cgit v1.3.1 From f33883c308959aa2ca08ef55282c82c54f929226 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 19:41:39 +0700 Subject: add tuh_cdc_get_local_line_coding() --- examples/host/cdc_msc_hid/src/cdc_app.c | 15 +++++++++++++-- src/class/cdc/cdc_host.c | 22 ++++++++++++++++++++-- src/class/cdc/cdc_host.h | 12 ++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index dd3196146..b1b137e0e 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -90,7 +90,18 @@ void tuh_cdc_mount_cb(uint8_t idx) tuh_cdc_itf_info_t itf_info = { 0 }; tuh_cdc_itf_get_info(idx, &itf_info); - printf("CDC Interface is mounted: device address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber); + printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber); + +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration + // 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(" Parity : %u, Data Width: %u\r\n", line_coding.parity , line_coding.data_bits); + } +#endif } void tuh_cdc_umount_cb(uint8_t idx) @@ -98,5 +109,5 @@ void tuh_cdc_umount_cb(uint8_t idx) tuh_cdc_itf_info_t itf_info = { 0 }; tuh_cdc_itf_get_info(idx, &itf_info); - printf("CDC Interface is unmounted: device address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber); + printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber); } diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 05e0bdfc7..17dc877f8 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -52,8 +52,8 @@ typedef struct { cdc_acm_capability_t acm_capability; uint8_t ep_notif; - cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width - uint8_t line_state; // DTR (bit0), RTS (bit1) + cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width + uint8_t line_state; // DTR (bit0), RTS (bit1) tuh_xfer_cb_t user_control_cb; @@ -162,6 +162,20 @@ bool tuh_cdc_get_rts(uint8_t idx) return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_RTS) ? true : false; } +bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); + + *line_coding = p_cdc->line_coding; + + return true; +} + +//--------------------------------------------------------------------+ +// Write +//--------------------------------------------------------------------+ + uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); @@ -194,6 +208,10 @@ uint32_t tuh_cdc_write_available(uint8_t idx) return tu_edpt_stream_write_available(&p_cdc->stream.tx); } +//--------------------------------------------------------------------+ +// Read +//--------------------------------------------------------------------+ + uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 9bf5af46c..502ad430d 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -102,6 +102,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) return tuh_cdc_get_dtr(idx); } +// Get local (saved/cached) version of line coding. +// This function should return correct values if tuh_cdc_set_line_coding() / tuh_cdc_get_line_coding() +// are invoked previously or CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined. +// NOTE: This function does not make any USB transfer request to device. +bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding); + //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ @@ -133,6 +139,7 @@ bool tuh_cdc_read_clear (uint8_t idx); //--------------------------------------------------------------------+ // Control Endpoint (Request) API +// Each Function will make a USB transfer request to/from device //--------------------------------------------------------------------+ // Request to Set Control Line State: DTR (bit 0), RTS (bit 1) @@ -141,6 +148,11 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c // Request to Set Line Coding bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +// Request to Get Line Coding +// Should only use if tuh_cdc_set_line_coding() / tuh_cdc_get_line_coding() never got invoked and +// CFG_TUH_CDC_LINE_CODING_ON_ENUM is not defined +// bool tuh_cdc_get_line_coding(uint8_t idx, cdc_line_coding_t* coding); + // Connect by set both DTR, RTS static inline bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { -- cgit v1.3.1 From 396716cc2c29b151556d554c560307afcadd7252 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 20:26:32 +0700 Subject: clean up --- examples/host/cdc_msc_hid/CMakeLists.txt | 2 +- src/class/cdc/cdc.h | 22 ++++++---------------- 2 files changed, 7 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index 2e89817a5..7af6b738e 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -15,8 +15,8 @@ add_executable(${PROJECT}) # Example source target_sources(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c ) diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index 9a3fc21ee..2fecde3ca 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -41,16 +41,6 @@ /** \defgroup ClassDriver_CDC_Common Common Definitions * @{ */ -// TODO remove -/// CDC Pipe ID, used to indicate which pipe the API is addressing to (Notification, Out, In) -typedef enum -{ - CDC_PIPE_NOTIFICATION , ///< Notification pipe - CDC_PIPE_DATA_IN , ///< Data in pipe - CDC_PIPE_DATA_OUT , ///< Data out pipe - CDC_PIPE_ERROR , ///< Invalid Pipe ID -}cdc_pipeid_t; - //--------------------------------------------------------------------+ // CDC Communication Interface Class //--------------------------------------------------------------------+ @@ -223,13 +213,13 @@ typedef enum { CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status. CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request. - CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08,///< CDC_NOTIF_AUX_JACK_HOOK_STATE - CDC_NOTIF_RING_DETECT = 0x09,///< CDC_NOTIF_RING_DETECT - CDC_NOTIF_SERIAL_STATE = 0x20,///< CDC_NOTIF_SERIAL_STATE - CDC_NOTIF_CALL_STATE_CHANGE = 0x28,///< CDC_NOTIF_CALL_STATE_CHANGE - CDC_NOTIF_LINE_STATE_CHANGE = 0x29,///< CDC_NOTIF_LINE_STATE_CHANGE + CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, + CDC_NOTIF_RING_DETECT = 0x09, + CDC_NOTIF_SERIAL_STATE = 0x20, + CDC_NOTIF_CALL_STATE_CHANGE = 0x28, + CDC_NOTIF_LINE_STATE_CHANGE = 0x29, CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred - CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40,///< CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION + CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40, }cdc_notification_request_t; //--------------------------------------------------------------------+ -- cgit v1.3.1 From 15a02d04df33afdeddc751453bbaefd4bc895939 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Dec 2022 21:35:55 +0700 Subject: fix incorrect rx buf in cdc --- src/class/cdc/cdc_device.c | 2 +- src/class/cdc/cdc_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 0bbbaaa83..8d10a416c 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -432,7 +432,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Received new data if ( ep_addr == p_cdc->ep_out ) { - tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, (uint16_t) xferred_bytes); + 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) ) diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index f625a7554..a7d25bd32 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -134,7 +134,7 @@ 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 space becomes available in TX buffer +// 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 -- cgit v1.3.1 From 48d4a67ec5468f9fd7c073acd599a1271b9e877f Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 24 Dec 2022 01:11:13 +0700 Subject: add tuh_cdc_peek() --- src/class/cdc/cdc_device.h | 2 +- src/class/cdc/cdc_host.c | 8 ++++++++ src/class/cdc/cdc_host.h | 3 +++ src/common/tusb_fifo.c | 2 -- src/common/tusb_private.h | 5 +++++ 5 files changed, 17 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index a7d25bd32..f8a004df4 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -80,7 +80,7 @@ int32_t tud_cdc_n_read_char (uint8_t itf); // Clear the received FIFO void tud_cdc_n_read_flush (uint8_t itf); -// Get a byte from FIFO at the specified position without removing it +// Get a byte from FIFO without removing it 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 diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 17dc877f8..e9c3d34cb 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -228,6 +228,14 @@ uint32_t tuh_cdc_read_available(uint8_t idx) return tu_edpt_stream_read_available(&p_cdc->stream.rx); } +bool tuh_cdc_peek(uint8_t idx, uint8_t* ch) +{ + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc); + + return tu_edpt_stream_peek(&p_cdc->stream.rx, ch); +} + bool tuh_cdc_read_clear (uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 502ad430d..c759527e6 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -134,6 +134,9 @@ uint32_t tuh_cdc_read_available(uint8_t idx); // Read from cdc interface uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize); +// Get a byte from RX FIFO without removing it +bool tuh_cdc_peek(uint8_t idx, uint8_t* ch); + // Clear the received FIFO bool tuh_cdc_read_clear (uint8_t idx); diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index b857c6444..d45ca09ed 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -682,8 +682,6 @@ uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint1 @param[in] f Pointer to the FIFO buffer to manipulate - @param[in] offset - Position to read from in the FIFO buffer with respect to read pointer @param[in] p_buffer Pointer to the place holder for data read from the buffer diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index d0c7a84fb..d5541856c 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -160,6 +160,11 @@ uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s) return (uint32_t) tu_fifo_count(&s->ff); } +TU_ATTR_ALWAYS_INLINE static inline +bool tu_edpt_stream_peek(tu_edpt_stream_t* s, uint8_t* ch) +{ + return tu_fifo_peek(&s->ff, ch); +} #ifdef __cplusplus } -- cgit v1.3.1 From d0ca6ca8f728fadcc12053c24ada23e328f2180a Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 27 Dec 2022 18:21:56 +0700 Subject: fix ncm warning --- src/class/net/ncm_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 00892b49c..1cbc0ce01 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -392,7 +392,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t if (NCM_GET_NTB_PARAMETERS == request->bRequest) { - tud_control_xfer(rhport, request, (void*)&ntb_parameters, sizeof(ntb_parameters)); + tud_control_xfer(rhport, request, (void*)(uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); } break; -- cgit v1.3.1 From 95ba158a1070635551b01d921cb4c5eeb7734989 Mon Sep 17 00:00:00 2001 From: Staacks Date: Tue, 27 Dec 2022 23:02:33 +0100 Subject: Fix UVC probe and commit on MacOS --- src/class/video/video_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index a6d2724c1..e17d0a90f 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -917,7 +917,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(sizeof(video_probe_and_commit_control_t) == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(sizeof(video_probe_and_commit_control_t) >= request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { @@ -973,7 +973,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(sizeof(video_probe_and_commit_control_t) == request->wLength, VIDEO_ERROR_UNKNOWN); + TU_VERIFY(sizeof(video_probe_and_commit_control_t) >= request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); -- cgit v1.3.1 From 82f105e32b3b299509daa1dc24d6aa94f5ce63fb Mon Sep 17 00:00:00 2001 From: Mengsk Date: Mon, 2 Jan 2023 17:12:03 +0100 Subject: Fix IAR warning: Warning[Pe381]: extra ";" ignored --- src/class/usbtmc/usbtmc_device.c | 6 ++++-- src/osal/osal.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 07c7c28a6..ba38bfca8 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -157,8 +157,10 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack static uint8_t termChar; static uint8_t termCharRequested = false; -OSAL_MUTEX_DEF(usbtmcLockBuffer); -static osal_mutex_t usbtmcLock; +#if OSAL_MUTEX_REQUIRED +static OSAL_MUTEX_DEF(usbtmcLockBuffer); +#endif +osal_mutex_t usbtmcLock; // Our own private lock, mostly for the state variable. #define criticalEnter() do { (void) osal_mutex_lock(usbtmcLock,OSAL_TIMEOUT_WAIT_FOREVER); } while (0) diff --git a/src/osal/osal.h b/src/osal/osal.h index 9cdab2882..afa3826fc 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -44,7 +44,7 @@ typedef void (*osal_task_func_t)( void * ); // Mutex is required when using a preempted RTOS or MCU has multiple cores #if (CFG_TUSB_OS == OPT_OS_NONE) && !TUP_MCU_MULTIPLE_CORE #define OSAL_MUTEX_REQUIRED 0 - #define OSAL_MUTEX_DEF(_name) + #define OSAL_MUTEX_DEF(_name) uint8_t :0 #else #define OSAL_MUTEX_REQUIRED 1 #define OSAL_MUTEX_DEF(_name) osal_mutex_def_t _name -- cgit v1.3.1 From f5cffeedec863c1efd59688fa79a8455046e8377 Mon Sep 17 00:00:00 2001 From: pete-pjb Date: Tue, 3 Jan 2023 10:33:36 +0000 Subject: Fix typo in audio.h. Specifiy _ctrl_xfer struct in CFG_TUSB_MEM_SECTION Add NULL check to loop in list_remove_qhd_by_addr() function in ehci.c --- src/class/audio/audio.h | 2 ++ src/host/usbh.c | 8 ++++---- src/portable/ehci/ehci.c | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 6f9c1a6b5..ba497906b 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -721,11 +721,13 @@ typedef struct TU_ATTR_PACKED uint8_t bLength ; ///< Size of this descriptor, in bytes: 17. uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL. + uint8_t bTerminalID ; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this terminal. uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. See: audio_terminal_type_t for USB streaming and audio_terminal_input_type_t for other input types. uint8_t bAssocTerminal ; ///< ID of the Output Terminal to which this Input Terminal is associated. uint8_t bCSourceID ; ///< ID of the Clock Entity to which this Input Terminal is connected. uint8_t bNrChannels ; ///< Number of logical output channels in the Terminal’s output audio channel cluster. uint32_t bmChannelConfig ; ///< Describes the spatial location of the logical channels. See:audio_channel_config_t. + uint8_t iChannelNames ; ///< Index of a string descriptor, describing the name of the first logical channel. uint16_t bmControls ; ///< See: audio_terminal_input_control_pos_t. uint8_t iTerminal ; ///< Index of a string descriptor, describing the Input Terminal. } audio_desc_input_terminal_t; diff --git a/src/host/usbh.c b/src/host/usbh.c index af1e67d4d..5ac9e9cca 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -229,10 +229,10 @@ static osal_queue_t _usbh_q; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; -// Control transfer: since most controller does not support multiple control transfer -// on multiple devices concurrently. And control transfer is not used much except enumeration -// We will only execute control transfer one at a time. -struct +// Control transfers: since most controllers do not support multiple control transfers +// on multiple devices concurrently and control transfers are not used much except for +// enumeration, we will only execute control transfers one at a time. +CFG_TUSB_MEM_SECTION struct { tusb_control_request_t request TU_ATTR_ALIGNED(4); uint8_t* buffer; diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 80f616478..7140897a1 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -188,7 +188,7 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) { for(ehci_link_t* prev = list_head; - !prev->terminate && (tu_align32(prev->address) != (uint32_t) list_head); + !prev->terminate && (tu_align32(prev->address) != (uint32_t) list_head) && prev != NULL; prev = list_next(prev) ) { // TODO check type for ISO iTD and siTD -- cgit v1.3.1 From 8c591e2c45f80f41d2704ae3b3ce5bde8550ecb9 Mon Sep 17 00:00:00 2001 From: Mengsk Date: Wed, 4 Jan 2023 10:19:34 +0100 Subject: More warning fixes --- src/class/usbtmc/usbtmc_device.c | 73 +++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index ba38bfca8..0cf0743a7 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -364,7 +364,7 @@ bool tud_usbtmc_start_bus_read() case STATE_RCV: break; default: - TU_VERIFY(false); + return false; } TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, (uint16_t)usbtmc_state.ep_bulk_out_wMaxPacketSize)); return true; @@ -466,53 +466,52 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint switch(usbtmc_state.state) { case STATE_IDLE: - TU_VERIFY(xferred_bytes >= sizeof(usbtmc_msg_generic_t)); - msg = (usbtmc_msg_generic_t*)(usbtmc_state.ep_bulk_out_buf); - uint8_t invInvTag = (uint8_t)~(msg->header.bTagInverse); - TU_VERIFY(msg->header.bTag == invInvTag); - TU_VERIFY(msg->header.bTag != 0x00); - - switch(msg->header.MsgID) { - case USBTMC_MSGID_DEV_DEP_MSG_OUT: - if(!handle_devMsgOutStart(rhport, msg, xferred_bytes)) - { - usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); - TU_VERIFY(false); - } - break; + { + TU_VERIFY(xferred_bytes >= sizeof(usbtmc_msg_generic_t)); + msg = (usbtmc_msg_generic_t*)(usbtmc_state.ep_bulk_out_buf); + uint8_t invInvTag = (uint8_t)~(msg->header.bTagInverse); + TU_VERIFY(msg->header.bTag == invInvTag); + TU_VERIFY(msg->header.bTag != 0x00); + + switch(msg->header.MsgID) { + case USBTMC_MSGID_DEV_DEP_MSG_OUT: + if(!handle_devMsgOutStart(rhport, msg, xferred_bytes)) + { + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + return false; + } + break; - case USBTMC_MSGID_DEV_DEP_MSG_IN: - TU_VERIFY(handle_devMsgIn(msg, xferred_bytes)); - break; + case USBTMC_MSGID_DEV_DEP_MSG_IN: + TU_VERIFY(handle_devMsgIn(msg, xferred_bytes)); + break; #if (CFG_TUD_USBTMC_ENABLE_488) - case USBTMC_MSGID_USB488_TRIGGER: - // Spec says we halt the EP if we didn't declare we support it. - TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger); - TU_VERIFY(tud_usbtmc_msg_trigger_cb(msg)); + case USBTMC_MSGID_USB488_TRIGGER: + // Spec says we halt the EP if we didn't declare we support it. + TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger); + TU_VERIFY(tud_usbtmc_msg_trigger_cb(msg)); - break; + break; #endif - case USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT: - case USBTMC_MSGID_VENDOR_SPECIFIC_IN: - default: - usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); - TU_VERIFY(false); - return false; + case USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT: + case USBTMC_MSGID_VENDOR_SPECIFIC_IN: + default: + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + return false; + } + return true; } - return true; - case STATE_RCV: if(!handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes, xferred_bytes)) { usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); - TU_VERIFY(false); + return false; } return true; case STATE_ABORTING_BULK_OUT: - TU_VERIFY(false); - return false; // Should be stalled by now, shouldn't have received a packet. + return false; case STATE_TX_REQUESTED: case STATE_TX_INITIATED: @@ -520,7 +519,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_ABORTING_BULK_IN_SHORTED: case STATE_ABORTING_BULK_IN_ABORTED: default: - TU_VERIFY(false); + return false; } } else if(ep_addr == usbtmc_state.ep_bulk_in) @@ -569,7 +568,6 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint default: TU_ASSERT(false); - return false; } } else if (ep_addr == usbtmc_state.ep_int_in) { @@ -873,16 +871,13 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request case USB488_bREQUEST_LOCAL_LOCKOUT: { TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - TU_VERIFY(false); return false; } #endif default: - TU_VERIFY(false); return false; } - TU_VERIFY(false); } #endif /* CFG_TUD_TSMC */ -- cgit v1.3.1 From 9c73c1a532649630de5e55400632bcca90ebea06 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Jan 2023 10:56:19 +0700 Subject: minor clean up --- src/common/tusb_fifo.c | 4 ++-- src/common/tusb_fifo.h | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 6862a6f43..d3875a7d4 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -39,12 +39,12 @@ // implement mutex lock and unlock #if CFG_FIFO_MUTEX -static inline void _ff_lock(tu_fifo_mutex_t mutex) +static inline void _ff_lock(osal_mutex_t mutex) { if (mutex) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); } -static inline void _ff_unlock(tu_fifo_mutex_t mutex) +static inline void _ff_unlock(osal_mutex_t mutex) { if (mutex) osal_mutex_unlock(mutex); } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index f1810e39c..f72ff295b 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -44,8 +44,6 @@ extern "C" { #include "common/tusb_common.h" #include "osal/osal.h" -#define tu_fifo_mutex_t osal_mutex_t - // mutex is only needed for RTOS // for OS None, we don't get preempted #define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED @@ -121,8 +119,8 @@ typedef struct volatile uint16_t rd_idx ; ///< read index #if OSAL_MUTEX_REQUIRED - tu_fifo_mutex_t mutex_wr; - tu_fifo_mutex_t mutex_rd; + osal_mutex_t mutex_wr; + osal_mutex_t mutex_rd; #endif } tu_fifo_t; @@ -155,7 +153,7 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si #if OSAL_MUTEX_REQUIRED TU_ATTR_ALWAYS_INLINE static inline -void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t wr_mutex, tu_fifo_mutex_t rd_mutex) +void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) { f->mutex_wr = wr_mutex; f->mutex_rd = rd_mutex; -- cgit v1.3.1 From 2a1b81e3c50f5e37530c8318b7fb7767ba771979 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Jan 2023 11:51:17 +0700 Subject: minimize tu_fifo size to 16 - remove non_used_index_space - packed overwritable with item_size --- src/common/tusb_fifo.c | 37 ++++++++++++++++++------------------- src/common/tusb_fifo.h | 40 +++++++++++++++++++--------------------- src/device/usbd.c | 2 ++ 3 files changed, 39 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index d3875a7d4..4dfe7bd81 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -68,22 +68,19 @@ typedef enum bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) { - if (depth > 0x8000) return false; // Maximum depth is 2^15 items + // Limit index space to 2*depth - this allows for a fast "modulo" calculation + // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable + // only if overflow happens once (important for unsupervised DMA applications) + if (depth > 0x8000) return false; _ff_lock(f->mutex_wr); _ff_lock(f->mutex_rd); - f->buffer = (uint8_t*) buffer; - f->depth = depth; - f->item_size = item_size; + f->buffer = (uint8_t*) buffer; + f->depth = depth; + f->item_size = (uint16_t) (item_size & 0x7FFF); f->overwritable = overwritable; - // Limit index space to 2*depth - this allows for a fast "modulo" calculation - // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable - // only if overflow happens once (important for unsupervised DMA applications) - //f->max_pointer_idx = (uint16_t) (2*depth - 1); - f->non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1)); - f->rd_idx = f->wr_idx = 0; _ff_unlock(f->mutex_wr); @@ -331,7 +328,8 @@ static uint16_t advance_pointer(tu_fifo_t* f, uint16_t idx, uint16_t offset) uint16_t next_p = (uint16_t) (idx + offset); if ( (idx > next_p) || (next_p >= 2*f->depth) ) { - next_p = (uint16_t) (next_p + f->non_used_index_space); + uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1)); + next_p = (uint16_t) (next_p + non_used_index_space); } return next_p; @@ -346,7 +344,8 @@ static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) uint16_t new_p = (uint16_t) (p - offset); if ( (p < new_p) || (new_p >= 2*f->depth) ) { - new_p = (uint16_t) (new_p - f->non_used_index_space); + uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1)); + new_p = (uint16_t) (new_p - non_used_index_space); } return new_p; @@ -363,13 +362,15 @@ static inline uint16_t idx2ptr(uint16_t idx, uint16_t depth) // Works on local copies of w and r - return only the difference and as such can be used to determine an overflow static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) { - uint16_t cnt = (uint16_t) (wr_idx-rd_idx); + uint16_t cnt; // In case we have non-power of two depth we need a further modification - if (rd_idx > wr_idx) + if (wr_idx >= rd_idx) + { + cnt = (uint16_t) (wr_idx - rd_idx); + } else { - // 2*f->depth - (rd_idx - wr_idx); - cnt = (uint16_t) (cnt - f->non_used_index_space); + cnt = (uint16_t) (2*f->depth - (rd_idx - wr_idx)); } return cnt; @@ -395,7 +396,7 @@ static inline bool _tu_fifo_full(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) // use DMAs, write functions do not allow such an error. static inline bool _tu_fifo_overflowed(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) { - return (_tu_fifo_count(f, wr_idx, rd_idx) > f->depth); + return _tu_fifo_count(f, wr_idx, rd_idx) > f->depth; } // Works on local copies of w @@ -868,8 +869,6 @@ bool tu_fifo_clear(tu_fifo_t *f) _ff_lock(f->mutex_rd); f->rd_idx = f->wr_idx = 0; - //f->max_pointer_idx = (uint16_t) (2*f->depth-1); - f->non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1)); _ff_unlock(f->mutex_wr); _ff_unlock(f->mutex_rd); diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index f72ff295b..2f60ec2f4 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -69,8 +69,8 @@ extern "C" { * | 0 | 1 | W | 3 | 4 | R | * * - Number of items in the fifo can be determined in either cases: - * - case W > R: Count = W - R - * - case W < R: Count = 2*depth - (R - W) + * - case W >= R: Count = W - R + * - case W < R: Count = 2*depth - (R - W) * * In non-overwritable mode, computed Count (in above 2 cases) is at most equal to depth. * However, in over-writable mode, write index can be repeatedly increased and count can be @@ -82,10 +82,10 @@ extern "C" { * ------------------------- * | R | 1 | 2 | 3 | W | 5 | * - * - Double Overflowed i.e index is out of allowed range [0,2*depth) e.g: + * - Double Overflowed i.e index is out of allowed range [0,2*depth) + * This occurs when we continue to write after 1st overflowed to 2nd overflowed. e.g: * write(3), write(1), write(2) - * Continue to write after overflowed to 2nd overflowed. - * We must prevent 2nd overflowed since it will cause incorrect computed of count, in above example + * This must be prevented since it will cause unrecoverable state, in above example * if not handled the fifo will be empty instead of continue-to-be full. Since we must not modify * read index in write() function, which cause race condition. We will re-position write index so that * after data is written it is a full fifo i.e W = depth - R @@ -106,17 +106,16 @@ extern "C" { */ typedef struct { - uint8_t* buffer ; ///< buffer pointer - uint16_t depth ; ///< max items - uint16_t item_size ; ///< size of each item + uint8_t* buffer ; // buffer pointer + uint16_t depth ; // max items - bool overwritable ; + struct TU_ATTR_PACKED { + uint16_t item_size : 15; // size of each item + bool overwritable : 1 ; // ovwerwritable when full + }; - uint16_t non_used_index_space ; ///< required for non-power-of-two buffer length - //uint16_t max_pointer_idx ; ///< maximum absolute pointer index - - volatile uint16_t wr_idx ; ///< write index - volatile uint16_t rd_idx ; ///< read index + volatile uint16_t wr_idx ; // write index + volatile uint16_t rd_idx ; // read index #if OSAL_MUTEX_REQUIRED osal_mutex_t mutex_wr; @@ -133,13 +132,12 @@ typedef struct void * ptr_wrap ; ///< wrapped part start pointer } tu_fifo_buffer_info_t; -#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ -{ \ - .buffer = _buffer, \ - .depth = _depth, \ - .item_size = sizeof(_type), \ - .overwritable = _overwritable, \ - .non_used_index_space = (uint16_t)(UINT16_MAX - (2*(_depth)-1)), \ +#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ +{ \ + .buffer = _buffer, \ + .depth = _depth, \ + .item_size = sizeof(_type), \ + .overwritable = _overwritable, \ } #define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \ diff --git a/src/device/usbd.c b/src/device/usbd.c index f652a878e..6e0c6710d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -388,6 +388,8 @@ bool tud_init (uint8_t rhport) TU_LOG(USBD_DBG, "USBD init on controller %u\r\n", rhport); TU_LOG_INT(USBD_DBG, sizeof(usbd_device_t)); + TU_LOG_INT(USBD_DBG, sizeof(tu_fifo_t)); + TU_LOG_INT(USBD_DBG, sizeof(tu_edpt_stream_t)); tu_varclr(&_usbd_dev); -- cgit v1.3.1 From 82457519fa050b2efd1b462ba88f7f258047c715 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Jan 2023 12:11:55 +0700 Subject: minor clean up --- src/common/tusb_fifo.c | 68 ++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 4dfe7bd81..f72c8a12f 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -28,16 +28,15 @@ #include "osal/osal.h" #include "tusb_fifo.h" +#define TU_FIFO_DBG 0 + // Suppress IAR warning // Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement #if defined(__ICCARM__) #pragma diag_suppress = Pa082 #endif -#define TU_FIFO_DBG 0 - -// implement mutex lock and unlock -#if CFG_FIFO_MUTEX +#if OSAL_MUTEX_REQUIRED static inline void _ff_lock(osal_mutex_t mutex) { @@ -80,8 +79,8 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si f->depth = depth; f->item_size = (uint16_t) (item_size & 0x7FFF); f->overwritable = overwritable; - - f->rd_idx = f->wr_idx = 0; + f->rd_idx = 0; + f->wr_idx = 0; _ff_unlock(f->mutex_wr); _ff_unlock(f->mutex_rd); @@ -142,13 +141,13 @@ static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t } } -// send one item to FIFO WITHOUT updating write pointer +// send one item to fifo WITHOUT updating write pointer static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) { memcpy(f->buffer + (rel * f->item_size), app_buf, f->item_size); } -// send n items to FIFO WITHOUT updating write pointer +// send n items to fifo WITHOUT updating write pointer static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t rel, tu_fifo_copy_mode_t copy_mode) { uint16_t const nLin = f->depth - rel; @@ -227,13 +226,13 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t } } -// get one item from FIFO WITHOUT updating read pointer +// get one item from fifo WITHOUT updating read pointer static inline void _ff_pull(tu_fifo_t* f, void * app_buf, uint16_t rel) { memcpy(app_buf, f->buffer + (rel * f->item_size), f->item_size); } -// get n items from FIFO WITHOUT updating read pointer +// get n items from fifo WITHOUT updating read pointer static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu_fifo_copy_mode_t copy_mode) { uint16_t const nLin = f->depth - rel; @@ -475,14 +474,14 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu uint16_t rd_idx = f->rd_idx; uint8_t const* buf8 = (uint8_t const*) data; - uint16_t overflowable_count = _tu_fifo_count(f, wr_idx, rd_idx); - uint16_t const remain = _tu_fifo_remaining(f, wr_idx, rd_idx); - TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", rd_idx, wr_idx, _tu_fifo_count(f, wr_idx, rd_idx), remain, n); + TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", + rd_idx, wr_idx, _tu_fifo_count(f, wr_idx, rd_idx), _tu_fifo_remaining(f, wr_idx, rd_idx), n); if ( !f->overwritable ) { // limit up to full + uint16_t const remain = _tu_fifo_remaining(f, wr_idx, rd_idx); n = tu_min16(n, remain); } else @@ -508,23 +507,27 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu // We start writing at the read pointer's position since we fill the whole buffer wr_idx = rd_idx; } - else if (overflowable_count + n >= 2*f->depth) - { - // Double overflowed - // Index is bigger than the allowed range [0,2*depth) - // re-position write index to have a full fifo after pushed - wr_idx = advance_pointer(f, rd_idx, f->depth - n); - - // TODO we should also shift out n bytes from read index since we avoid changing rd index !! - // However memmove() is expensive due to actual copying + wrapping consideration. - // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory - // currently deliberately not implemented --> result in incorrect data read back - }else + else { - // normal + single overflowed: - // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read() - // Therefore we just increase write index - // we will correct (re-position) read index later on in fifo_read() function + uint16_t const overflowable_count = _tu_fifo_count(f, wr_idx, rd_idx); + if (overflowable_count + n >= 2*f->depth) + { + // Double overflowed + // Index is bigger than the allowed range [0,2*depth) + // re-position write index to have a full fifo after pushed + wr_idx = advance_pointer(f, rd_idx, f->depth - n); + + // TODO we should also shift out n bytes from read index since we avoid changing rd index !! + // However memmove() is expensive due to actual copying + wrapping consideration. + // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory + // currently deliberately not implemented --> result in incorrect data read back + }else + { + // normal + single overflowed: + // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read() + // Therefore we just increase write index + // we will correct (re-position) read index later on in fifo_read() function + } } } @@ -868,7 +871,8 @@ bool tu_fifo_clear(tu_fifo_t *f) _ff_lock(f->mutex_wr); _ff_lock(f->mutex_rd); - f->rd_idx = f->wr_idx = 0; + f->rd_idx = 0; + f->wr_idx = 0; _ff_unlock(f->mutex_wr); _ff_unlock(f->mutex_rd); @@ -1031,9 +1035,9 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) if (remain == 0) { - info->len_lin = 0; + info->len_lin = 0; info->len_wrap = 0; - info->ptr_lin = NULL; + info->ptr_lin = NULL; info->ptr_wrap = NULL; return; } -- cgit v1.3.1 From a804a1ac09c34a4f69c0d2873a552a2a505d0492 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Jan 2023 16:48:07 +0700 Subject: simplify and remove _tu_fifo_empty, _tu_fifo_full. Also correct full condition check --- src/common/tusb_fifo.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index f72c8a12f..4b27bc589 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -38,12 +38,12 @@ #if OSAL_MUTEX_REQUIRED -static inline void _ff_lock(osal_mutex_t mutex) +TU_ATTR_ALWAYS_INLINE static inline void _ff_lock(osal_mutex_t mutex) { if (mutex) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); } -static inline void _ff_unlock(osal_mutex_t mutex) +TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) { if (mutex) osal_mutex_unlock(mutex); } @@ -361,30 +361,14 @@ static inline uint16_t idx2ptr(uint16_t idx, uint16_t depth) // Works on local copies of w and r - return only the difference and as such can be used to determine an overflow static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) { - uint16_t cnt; - // In case we have non-power of two depth we need a further modification if (wr_idx >= rd_idx) { - cnt = (uint16_t) (wr_idx - rd_idx); + return (uint16_t) (wr_idx - rd_idx); } else { - cnt = (uint16_t) (2*f->depth - (rd_idx - wr_idx)); + return (uint16_t) (2*f->depth - (rd_idx - wr_idx)); } - - return cnt; -} - -// Works on local copies of w and r -static inline bool _tu_fifo_empty(uint16_t wr_idx, uint16_t rd_idx) -{ - return wr_idx == rd_idx; -} - -// Works on local copies of w and r -static inline bool _tu_fifo_full(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs) -{ - return _tu_fifo_count(f, wAbs, rAbs) == f->depth; } // Works on local copies of w and r @@ -601,7 +585,7 @@ uint16_t tu_fifo_count(tu_fifo_t* f) /******************************************************************************/ bool tu_fifo_empty(tu_fifo_t* f) { - return _tu_fifo_empty(f->wr_idx, f->rd_idx); + return f->wr_idx == f->rd_idx; } /******************************************************************************/ @@ -619,7 +603,7 @@ bool tu_fifo_empty(tu_fifo_t* f) /******************************************************************************/ bool tu_fifo_full(tu_fifo_t* f) { - return _tu_fifo_full(f, f->wr_idx, f->rd_idx); + return _tu_fifo_count(f, f->wr_idx, f->rd_idx) >= f->depth; } /******************************************************************************/ @@ -798,7 +782,7 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data) bool ret; uint16_t const wr_idx = f->wr_idx; - if ( _tu_fifo_full(f, wr_idx, f->rd_idx) && !f->overwritable ) + if ( tu_fifo_full(f) && !f->overwritable ) { ret = false; }else -- cgit v1.3.1 From 507d5b10b049d865e5bb24f99038eed07d092e8f Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Jan 2023 17:14:17 +0700 Subject: simplify _tu_fifo_count() and _tu_fifo_remaining(), also rename to _ff_count() and _ff_remaining() --- src/common/tusb_fifo.c | 57 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 4b27bc589..cdb0df73f 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -358,8 +358,9 @@ static inline uint16_t idx2ptr(uint16_t idx, uint16_t depth) return idx; } -// Works on local copies of w and r - return only the difference and as such can be used to determine an overflow -static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) +// return only the index difference and as such can be used to determine an overflow i.e overflowable count +TU_ATTR_ALWAYS_INLINE static inline +uint16_t _ff_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) { // In case we have non-power of two depth we need a further modification if (wr_idx >= rd_idx) @@ -367,24 +368,33 @@ static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd return (uint16_t) (wr_idx - rd_idx); } else { - return (uint16_t) (2*f->depth - (rd_idx - wr_idx)); + return (uint16_t) (2*depth - (rd_idx - wr_idx)); } } -// Works on local copies of w and r // BE AWARE - THIS FUNCTION MIGHT NOT GIVE A CORRECT ANSWERE IN CASE WRITE POINTER "OVERFLOWS" // Only one overflow is allowed for this function to work e.g. if depth = 100, you must not // write more than 2*depth-1 items in one rush without updating write pointer. Otherwise // write pointer wraps and you pointer states are messed up. This can only happen if you // use DMAs, write functions do not allow such an error. -static inline bool _tu_fifo_overflowed(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) +TU_ATTR_ALWAYS_INLINE static inline +bool _ff_overflowed(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) +{ + return _ff_count(depth, wr_idx, rd_idx) > depth; +} + +// return remaining slot in fifo +TU_ATTR_ALWAYS_INLINE static inline +uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) { - return _tu_fifo_count(f, wr_idx, rd_idx) > f->depth; + uint16_t const count = _ff_count(depth, wr_idx, rd_idx); + return (depth > count) ? (depth - count) : 0; } // Works on local copies of w // For more details see _tu_fifo_overflow()! -static inline void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wAbs) +TU_ATTR_ALWAYS_INLINE static inline +void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wAbs) { f->rd_idx = backward_pointer(f, wAbs, f->depth); } @@ -393,7 +403,7 @@ static inline void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wAbs) // Must be protected by mutexes since in case of an overflow read pointer gets modified static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16_t rd_idx) { - uint16_t cnt = _tu_fifo_count(f, wr_idx, rd_idx); + uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); // Check overflow and correct if required if (cnt > f->depth) @@ -417,7 +427,7 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16 // Must be protected by mutexes since in case of an overflow read pointer gets modified static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, tu_fifo_copy_mode_t copy_mode) { - uint16_t cnt = _tu_fifo_count(f, wr_idx, rd_idx); + uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); // Check overflow and correct if required if (cnt > f->depth) @@ -441,13 +451,6 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1 return n; } -// Works on local copies of w and r -static inline uint16_t _tu_fifo_remaining(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx) -{ - uint16_t const count = _tu_fifo_count(f, wr_idx, rd_idx); - return (f->depth > count) ? (f->depth - count) : 0; -} - static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu_fifo_copy_mode_t copy_mode) { if ( n == 0 ) return 0; @@ -460,12 +463,12 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu uint8_t const* buf8 = (uint8_t const*) data; TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", - rd_idx, wr_idx, _tu_fifo_count(f, wr_idx, rd_idx), _tu_fifo_remaining(f, wr_idx, rd_idx), n); + rd_idx, wr_idx, _ff_count(f->depth, wr_idx, rd_idx), _ff_remaining(f->depth, wr_idx, rd_idx), n); if ( !f->overwritable ) { // limit up to full - uint16_t const remain = _tu_fifo_remaining(f, wr_idx, rd_idx); + uint16_t const remain = _ff_remaining(f->depth, wr_idx, rd_idx); n = tu_min16(n, remain); } else @@ -493,7 +496,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu } else { - uint16_t const overflowable_count = _tu_fifo_count(f, wr_idx, rd_idx); + uint16_t const overflowable_count = _ff_count(f->depth, wr_idx, rd_idx); if (overflowable_count + n >= 2*f->depth) { // Double overflowed @@ -550,6 +553,10 @@ static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo return n; } +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + /******************************************************************************/ /*! @brief Get number of items in FIFO. @@ -567,7 +574,7 @@ static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo /******************************************************************************/ uint16_t tu_fifo_count(tu_fifo_t* f) { - return tu_min16(_tu_fifo_count(f, f->wr_idx, f->rd_idx), f->depth); + return tu_min16(_ff_count(f->depth, f->wr_idx, f->rd_idx), f->depth); } /******************************************************************************/ @@ -603,7 +610,7 @@ bool tu_fifo_empty(tu_fifo_t* f) /******************************************************************************/ bool tu_fifo_full(tu_fifo_t* f) { - return _tu_fifo_count(f, f->wr_idx, f->rd_idx) >= f->depth; + return _ff_count(f->depth, f->wr_idx, f->rd_idx) >= f->depth; } /******************************************************************************/ @@ -621,7 +628,7 @@ bool tu_fifo_full(tu_fifo_t* f) /******************************************************************************/ uint16_t tu_fifo_remaining(tu_fifo_t* f) { - return _tu_fifo_remaining(f, f->wr_idx, f->rd_idx); + return _ff_remaining(f->depth, f->wr_idx, f->rd_idx); } /******************************************************************************/ @@ -647,7 +654,7 @@ uint16_t tu_fifo_remaining(tu_fifo_t* f) /******************************************************************************/ bool tu_fifo_overflowed(tu_fifo_t* f) { - return _tu_fifo_overflowed(f, f->wr_idx, f->rd_idx); + return _ff_overflowed(f->depth, f->wr_idx, f->rd_idx); } // Only use in case tu_fifo_overflow() returned true! @@ -949,7 +956,7 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; - uint16_t cnt = _tu_fifo_count(f, wr_idx, rd_idx); + uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); // Check overflow and correct if required - may happen in case a DMA wrote too fast if (cnt > f->depth) @@ -1015,7 +1022,7 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; - uint16_t remain = _tu_fifo_remaining(f, wr_idx, rd_idx); + uint16_t remain = _ff_remaining(f->depth, wr_idx, rd_idx); if (remain == 0) { -- cgit v1.3.1 From 24bd1c95623377a81286f9d516da57c34451c515 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Jan 2023 17:27:26 +0700 Subject: update advance_pointer/backward_pointer to use depth instead of fifo, also rename to advance/backward_index --- src/common/tusb_fifo.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index cdb0df73f..8de58c4a4 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -319,35 +319,35 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu // Advance an absolute index // "absolute" index is only in the range of [0..2*depth) -static uint16_t advance_pointer(tu_fifo_t* f, uint16_t idx, uint16_t offset) +static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index - uint16_t next_p = (uint16_t) (idx + offset); - if ( (idx > next_p) || (next_p >= 2*f->depth) ) + uint16_t new_idx = (uint16_t) (idx + offset); + if ( (idx > new_idx) || (new_idx >= 2*depth) ) { - uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1)); - next_p = (uint16_t) (next_p + non_used_index_space); + uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*depth-1)); + new_idx = (uint16_t) (new_idx + non_used_index_space); } - return next_p; + return new_idx; } -// Backward an absolute pointer -static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) +// Backward an absolute index +static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index - uint16_t new_p = (uint16_t) (p - offset); - if ( (p < new_p) || (new_p >= 2*f->depth) ) + uint16_t new_idx = (uint16_t) (idx - offset); + if ( (idx < new_idx) || (new_idx >= 2*depth) ) { - uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1)); - new_p = (uint16_t) (new_p - non_used_index_space); + uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*depth-1)); + new_idx = (uint16_t) (new_idx - non_used_index_space); } - return new_p; + return new_idx; } // index to pointer, simply an modulo with minus. @@ -394,9 +394,9 @@ uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) // Works on local copies of w // For more details see _tu_fifo_overflow()! TU_ATTR_ALWAYS_INLINE static inline -void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wAbs) +void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wr_idx) { - f->rd_idx = backward_pointer(f, wAbs, f->depth); + f->rd_idx = backward_index(f->depth, wr_idx, f->depth); } // Works on local copies of w and r @@ -502,7 +502,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu // Double overflowed // Index is bigger than the allowed range [0,2*depth) // re-position write index to have a full fifo after pushed - wr_idx = advance_pointer(f, rd_idx, f->depth - n); + wr_idx = advance_index(f->depth, rd_idx, f->depth - n); // TODO we should also shift out n bytes from read index since we avoid changing rd index !! // However memmove() is expensive due to actual copying + wrapping consideration. @@ -528,7 +528,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu _ff_push_n(f, buf8, n, wr_ptr, copy_mode); // Advance index - f->wr_idx = advance_pointer(f, wr_idx, n); + f->wr_idx = advance_index(f->depth, wr_idx, n); TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\n", f->wr_idx); } @@ -547,7 +547,7 @@ static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo n = _tu_fifo_peek_n(f, buffer, n, f->wr_idx, f->rd_idx, copy_mode); // Advance read pointer - f->rd_idx = advance_pointer(f, f->rd_idx, n); + f->rd_idx = advance_index(f->depth, f->rd_idx, n); _ff_unlock(f->mutex_rd); return n; @@ -690,7 +690,7 @@ bool tu_fifo_read(tu_fifo_t* f, void * buffer) bool ret = _tu_fifo_peek(f, buffer, f->wr_idx, f->rd_idx); // Advance pointer - f->rd_idx = advance_pointer(f, f->rd_idx, ret); + f->rd_idx = advance_index(f->depth, f->rd_idx, ret); _ff_unlock(f->mutex_rd); return ret; @@ -800,7 +800,7 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data) _ff_push(f, data, wr_ptr); // Advance pointer - f->wr_idx = advance_pointer(f, wr_idx, 1); + f->wr_idx = advance_index(f->depth, wr_idx, 1); ret = true; } @@ -911,7 +911,7 @@ bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) /******************************************************************************/ void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n) { - f->wr_idx = advance_pointer(f, f->wr_idx, n); + f->wr_idx = advance_index(f->depth, f->wr_idx, n); } /******************************************************************************/ @@ -932,7 +932,7 @@ void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n) /******************************************************************************/ void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) { - f->rd_idx = advance_pointer(f, f->rd_idx, n); + f->rd_idx = advance_index(f->depth, f->rd_idx, n); } /******************************************************************************/ -- cgit v1.3.1 From 248025bb6cdf361e93603204d89cbf58e9e3b0af Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Jan 2023 17:29:43 +0700 Subject: reverse idx2ptr() arguments to be consistent --- src/common/tusb_fifo.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 8de58c4a4..a0ce73ba0 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -351,7 +351,8 @@ static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset) } // index to pointer, simply an modulo with minus. -static inline uint16_t idx2ptr(uint16_t idx, uint16_t depth) +TU_ATTR_ALWAYS_INLINE static inline +uint16_t idx2ptr(uint16_t depth, uint16_t idx) { // Only run at most 3 times since index is limit in the range of [0..2*depth) while ( idx >= depth ) idx -= depth; @@ -415,7 +416,7 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16 // Skip beginning of buffer if (cnt == 0) return false; - uint16_t rd_ptr = idx2ptr(rd_idx, f->depth); + uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Peek data _ff_pull(f, p_buffer, rd_ptr); @@ -443,7 +444,7 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1 // Check if we can read something at and after offset - if too less is available we read what remains if (cnt < n) n = cnt; - uint16_t rd_ptr = idx2ptr(rd_idx, f->depth); + uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Peek data _ff_pull_n(f, p_buffer, n, rd_ptr, copy_mode); @@ -520,7 +521,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu if (n) { - uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); + uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr); @@ -794,7 +795,7 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data) ret = false; }else { - uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); + uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); // Write data _ff_push(f, data, wr_ptr); @@ -980,8 +981,8 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) } // Get relative pointers - uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); - uint16_t rd_ptr = idx2ptr(rd_idx, f->depth); + uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); + uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Copy pointer to buffer to start reading from info->ptr_lin = &f->buffer[rd_ptr]; @@ -1034,8 +1035,8 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) } // Get relative pointers - uint16_t wr_ptr = idx2ptr(wr_idx, f->depth); - uint16_t rd_ptr = idx2ptr(rd_idx, f->depth); + uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); + uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Copy pointer to buffer to start writing to info->ptr_lin = &f->buffer[wr_ptr]; -- cgit v1.3.1 From c29b7643a59f4baa266d13ef0a7bed864ad83eb2 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Jan 2023 18:50:19 +0700 Subject: simplify _ff_correct_read_index() --- src/common/tusb_fifo.c | 107 ++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index a0ce73ba0..22d6e8e55 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -314,7 +314,44 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu } //--------------------------------------------------------------------+ -// Index (free-running and real buffer pointer) +// Helper +//--------------------------------------------------------------------+ + +// return only the index difference and as such can be used to determine an overflow i.e overflowable count +TU_ATTR_ALWAYS_INLINE static inline +uint16_t _ff_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) +{ + // In case we have non-power of two depth we need a further modification + if (wr_idx >= rd_idx) + { + return (uint16_t) (wr_idx - rd_idx); + } else + { + return (uint16_t) (2*depth - (rd_idx - wr_idx)); + } +} + +// BE AWARE - THIS FUNCTION MIGHT NOT GIVE A CORRECT ANSWERE IN CASE WRITE POINTER "OVERFLOWS" +// Only one overflow is allowed for this function to work e.g. if depth = 100, you must not +// write more than 2*depth-1 items in one rush without updating write pointer. Otherwise +// write pointer wraps and you pointer states are messed up. This can only happen if you +// use DMAs, write functions do not allow such an error. +TU_ATTR_ALWAYS_INLINE static inline +bool _ff_overflowed(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) +{ + return _ff_count(depth, wr_idx, rd_idx) > depth; +} + +// return remaining slot in fifo +TU_ATTR_ALWAYS_INLINE static inline +uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) +{ + uint16_t const count = _ff_count(depth, wr_idx, rd_idx); + return (depth > count) ? (depth - count) : 0; +} + +//--------------------------------------------------------------------+ +// Index Helper //--------------------------------------------------------------------+ // Advance an absolute index @@ -334,6 +371,7 @@ static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) return new_idx; } +#if 0 // not used but // Backward an absolute index static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset) { @@ -349,6 +387,7 @@ static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset) return new_idx; } +#endif // index to pointer, simply an modulo with minus. TU_ATTR_ALWAYS_INLINE static inline @@ -359,45 +398,24 @@ uint16_t idx2ptr(uint16_t depth, uint16_t idx) return idx; } -// return only the index difference and as such can be used to determine an overflow i.e overflowable count +// Works on local copies of w +// When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms +// an full fifo i.e _ff_count() = depth TU_ATTR_ALWAYS_INLINE static inline -uint16_t _ff_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) +uint16_t _ff_correct_read_index(tu_fifo_t* f, uint16_t wr_idx) { - // In case we have non-power of two depth we need a further modification - if (wr_idx >= rd_idx) + uint16_t rd_idx; + if ( wr_idx >= f->depth ) { - return (uint16_t) (wr_idx - rd_idx); - } else + rd_idx = wr_idx - f->depth; + }else { - return (uint16_t) (2*depth - (rd_idx - wr_idx)); + rd_idx = wr_idx + f->depth; } -} -// BE AWARE - THIS FUNCTION MIGHT NOT GIVE A CORRECT ANSWERE IN CASE WRITE POINTER "OVERFLOWS" -// Only one overflow is allowed for this function to work e.g. if depth = 100, you must not -// write more than 2*depth-1 items in one rush without updating write pointer. Otherwise -// write pointer wraps and you pointer states are messed up. This can only happen if you -// use DMAs, write functions do not allow such an error. -TU_ATTR_ALWAYS_INLINE static inline -bool _ff_overflowed(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) -{ - return _ff_count(depth, wr_idx, rd_idx) > depth; -} + f->rd_idx = rd_idx; -// return remaining slot in fifo -TU_ATTR_ALWAYS_INLINE static inline -uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) -{ - uint16_t const count = _ff_count(depth, wr_idx, rd_idx); - return (depth > count) ? (depth - count) : 0; -} - -// Works on local copies of w -// For more details see _tu_fifo_overflow()! -TU_ATTR_ALWAYS_INLINE static inline -void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wr_idx) -{ - f->rd_idx = backward_index(f->depth, wr_idx, f->depth); + return rd_idx; } // Works on local copies of w and r @@ -407,14 +425,14 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16 uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); // Check overflow and correct if required - if (cnt > f->depth) + if ( cnt > f->depth ) { - _tu_fifo_correct_read_pointer(f, wr_idx); + rd_idx = _ff_correct_read_index(f, wr_idx); cnt = f->depth; } // Skip beginning of buffer - if (cnt == 0) return false; + if ( cnt == 0 ) return false; uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); @@ -431,18 +449,17 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1 uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); // Check overflow and correct if required - if (cnt > f->depth) + if ( cnt > f->depth ) { - _tu_fifo_correct_read_pointer(f, wr_idx); - rd_idx = f->rd_idx; + rd_idx = _ff_correct_read_index(f, wr_idx); cnt = f->depth; } // Skip beginning of buffer - if (cnt == 0) return 0; + if ( cnt == 0 ) return 0; // Check if we can read something at and after offset - if too less is available we read what remains - if (cnt < n) n = cnt; + if ( cnt < n ) n = cnt; uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); @@ -662,7 +679,7 @@ bool tu_fifo_overflowed(tu_fifo_t* f) void tu_fifo_correct_read_pointer(tu_fifo_t* f) { _ff_lock(f->mutex_rd); - _tu_fifo_correct_read_pointer(f, f->wr_idx); + _ff_correct_read_index(f, f->wr_idx); _ff_unlock(f->mutex_rd); } @@ -963,10 +980,9 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) if (cnt > f->depth) { _ff_lock(f->mutex_rd); - _tu_fifo_correct_read_pointer(f, wr_idx); + rd_idx = _ff_correct_read_index(f, wr_idx); _ff_unlock(f->mutex_rd); - rd_idx = f->rd_idx; cnt = f->depth; } @@ -988,7 +1004,8 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) info->ptr_lin = &f->buffer[rd_ptr]; // Check if there is a wrap around necessary - if (wr_ptr > rd_ptr) { + if (wr_ptr > rd_ptr) + { // Non wrapping case info->len_lin = cnt; -- cgit v1.3.1 From 9e551c9f5cda2bd2bb1f53e34c5010babc534eb9 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Jan 2023 19:00:04 +0700 Subject: remove _ff_overflowed() due to lack of use --- src/common/tusb_fifo.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 22d6e8e55..d5eea83f7 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -331,17 +331,6 @@ uint16_t _ff_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) } } -// BE AWARE - THIS FUNCTION MIGHT NOT GIVE A CORRECT ANSWERE IN CASE WRITE POINTER "OVERFLOWS" -// Only one overflow is allowed for this function to work e.g. if depth = 100, you must not -// write more than 2*depth-1 items in one rush without updating write pointer. Otherwise -// write pointer wraps and you pointer states are messed up. This can only happen if you -// use DMAs, write functions do not allow such an error. -TU_ATTR_ALWAYS_INLINE static inline -bool _ff_overflowed(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) -{ - return _ff_count(depth, wr_idx, rd_idx) > depth; -} - // return remaining slot in fifo TU_ATTR_ALWAYS_INLINE static inline uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) @@ -672,7 +661,7 @@ uint16_t tu_fifo_remaining(tu_fifo_t* f) /******************************************************************************/ bool tu_fifo_overflowed(tu_fifo_t* f) { - return _ff_overflowed(f->depth, f->wr_idx, f->rd_idx); + return _ff_count(f->depth, f->wr_idx, f->rd_idx) > f->depth; } // Only use in case tu_fifo_overflow() returned true! -- cgit v1.3.1 From c84de8f06bb42de78fec22dec8026f3a0c0899cc Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Jan 2023 19:40:06 +0700 Subject: minor clean up --- src/common/tusb_fifo.c | 100 +++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index d5eea83f7..a52c92267 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -97,13 +97,13 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si // TODO generalize with configurable 1 byte or 4 byte each read static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t len) { - volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; + volatile const uint32_t * reg_rx = (volatile const uint32_t *) app_buf; // Reading full available 32 bit words from const app address uint16_t full_words = len >> 2; while(full_words--) { - tu_unaligned_write32(ff_buf, *rx_fifo); + tu_unaligned_write32(ff_buf, *reg_rx); ff_buf += 4; } @@ -111,7 +111,7 @@ static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t uint8_t const bytes_rem = len & 0x03; if ( bytes_rem ) { - uint32_t tmp32 = *rx_fifo; + uint32_t tmp32 = *reg_rx; memcpy(ff_buf, &tmp32, bytes_rem); } } @@ -120,24 +120,24 @@ static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t // where all data is written to a constant address in full word copies static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t len) { - volatile uint32_t * tx_fifo = (volatile uint32_t *) app_buf; + volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf; - // Pushing full available 32 bit words to const app address + // Write full available 32 bit words to const address uint16_t full_words = len >> 2; while(full_words--) { - *tx_fifo = tu_unaligned_read32(ff_buf); + *reg_tx = tu_unaligned_read32(ff_buf); ff_buf += 4; } - // Write the remaining 1-3 bytes into const app address + // Write the remaining 1-3 bytes into const address uint8_t const bytes_rem = len & 0x03; if ( bytes_rem ) { uint32_t tmp32 = 0; memcpy(&tmp32, ff_buf, bytes_rem); - *tx_fifo = tmp32; + *reg_tx = tmp32; } } @@ -148,21 +148,21 @@ static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) } // send n items to fifo WITHOUT updating write pointer -static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t rel, tu_fifo_copy_mode_t copy_mode) +static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t wr_ptr, tu_fifo_copy_mode_t copy_mode) { - uint16_t const nLin = f->depth - rel; - uint16_t const nWrap = n - nLin; + uint16_t const lin_count = f->depth - wr_ptr; + uint16_t const wrap_count = n - lin_count; - uint16_t nLin_bytes = nLin * f->item_size; - uint16_t nWrap_bytes = nWrap * f->item_size; + uint16_t lin_bytes = lin_count * f->item_size; + uint16_t wrap_bytes = wrap_count * f->item_size; // current buffer of fifo - uint8_t* ff_buf = f->buffer + (rel * f->item_size); + uint8_t* ff_buf = f->buffer + (wr_ptr * f->item_size); switch (copy_mode) { case TU_FIFO_COPY_INC: - if(n <= nLin) + if(n <= lin_count) { // Linear only memcpy(ff_buf, app_buf, n*f->item_size); @@ -172,17 +172,17 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t // Wrap around // Write data to linear part of buffer - memcpy(ff_buf, app_buf, nLin_bytes); + memcpy(ff_buf, app_buf, lin_bytes); // Write data wrapped around // TU_ASSERT(nWrap_bytes <= f->depth, ); - memcpy(f->buffer, ((uint8_t const*) app_buf) + nLin_bytes, nWrap_bytes); + memcpy(f->buffer, ((uint8_t const*) app_buf) + lin_bytes, wrap_bytes); } break; case TU_FIFO_COPY_CST_FULL_WORDS: // Intended for hardware buffers from which it can be read word by word only - if(n <= nLin) + if(n <= lin_count) { // Linear only _ff_push_const_addr(ff_buf, app_buf, n*f->item_size); @@ -192,17 +192,18 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t // Wrap around case // Write full words to linear part of buffer - uint16_t nLin_4n_bytes = nLin_bytes & 0xFFFC; + uint16_t nLin_4n_bytes = lin_bytes & 0xFFFC; _ff_push_const_addr(ff_buf, app_buf, nLin_4n_bytes); ff_buf += nLin_4n_bytes; // There could be odd 1-3 bytes before the wrap-around boundary - volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; - uint8_t rem = nLin_bytes & 0x03; + uint8_t rem = lin_bytes & 0x03; if (rem > 0) { - uint8_t remrem = (uint8_t) tu_min16(nWrap_bytes, 4-rem); - nWrap_bytes -= remrem; + volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; + + uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); + wrap_bytes -= remrem; uint32_t tmp32 = *rx_fifo; uint8_t * src_u8 = ((uint8_t *) &tmp32); @@ -220,7 +221,7 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t } // Write data wrapped part - if (nWrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, nWrap_bytes); + if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes); } break; } @@ -233,21 +234,21 @@ static inline void _ff_pull(tu_fifo_t* f, void * app_buf, uint16_t rel) } // get n items from fifo WITHOUT updating read pointer -static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu_fifo_copy_mode_t copy_mode) +static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, tu_fifo_copy_mode_t copy_mode) { - uint16_t const nLin = f->depth - rel; - uint16_t const nWrap = n - nLin; // only used if wrapped + uint16_t const lin_count = f->depth - rd_ptr; + uint16_t const wrap_count = n - lin_count; // only used if wrapped - uint16_t nLin_bytes = nLin * f->item_size; - uint16_t nWrap_bytes = nWrap * f->item_size; + uint16_t lin_bytes = lin_count * f->item_size; + uint16_t wrap_bytes = wrap_count * f->item_size; // current buffer of fifo - uint8_t* ff_buf = f->buffer + (rel * f->item_size); + uint8_t* ff_buf = f->buffer + (rd_ptr * f->item_size); switch (copy_mode) { case TU_FIFO_COPY_INC: - if ( n <= nLin ) + if ( n <= lin_count ) { // Linear only memcpy(app_buf, ff_buf, n*f->item_size); @@ -257,15 +258,15 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu // Wrap around // Read data from linear part of buffer - memcpy(app_buf, ff_buf, nLin_bytes); + memcpy(app_buf, ff_buf, lin_bytes); // Read data wrapped part - memcpy((uint8_t*) app_buf + nLin_bytes, f->buffer, nWrap_bytes); + memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes); } break; case TU_FIFO_COPY_CST_FULL_WORDS: - if ( n <= nLin ) + if ( n <= lin_count ) { // Linear only _ff_pull_const_addr(app_buf, ff_buf, n*f->item_size); @@ -275,17 +276,18 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu // Wrap around case // Read full words from linear part of buffer - uint16_t nLin_4n_bytes = nLin_bytes & 0xFFFC; - _ff_pull_const_addr(app_buf, ff_buf, nLin_4n_bytes); - ff_buf += nLin_4n_bytes; + uint16_t lin_4n_bytes = lin_bytes & 0xFFFC; + _ff_pull_const_addr(app_buf, ff_buf, lin_4n_bytes); + ff_buf += lin_4n_bytes; // There could be odd 1-3 bytes before the wrap-around boundary - volatile uint32_t * tx_fifo = (volatile uint32_t *) app_buf; - uint8_t rem = nLin_bytes & 0x03; + uint8_t rem = lin_bytes & 0x03; if (rem > 0) { - uint8_t remrem = (uint8_t) tu_min16(nWrap_bytes, 4-rem); - nWrap_bytes -= remrem; + volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf; + + uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); + wrap_bytes -= remrem; uint32_t tmp32=0; uint8_t * dst_u8 = (uint8_t *)&tmp32; @@ -297,7 +299,7 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu ff_buf = f->buffer; while(remrem--) *dst_u8++ = *ff_buf++; - *tx_fifo = tmp32; + *reg_tx = tmp32; } else { @@ -305,7 +307,7 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu } // Read data wrapped part - if (nWrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, nWrap_bytes); + if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes); } break; @@ -413,6 +415,9 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16 { uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); + // nothing to peek + if ( cnt == 0 ) return false; + // Check overflow and correct if required if ( cnt > f->depth ) { @@ -420,9 +425,6 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16 cnt = f->depth; } - // Skip beginning of buffer - if ( cnt == 0 ) return false; - uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Peek data @@ -437,6 +439,9 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1 { uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); + // nothing to peek + if ( cnt == 0 ) return 0; + // Check overflow and correct if required if ( cnt > f->depth ) { @@ -444,9 +449,6 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1 cnt = f->depth; } - // Skip beginning of buffer - if ( cnt == 0 ) return 0; - // Check if we can read something at and after offset - if too less is available we read what remains if ( cnt < n ) n = cnt; -- cgit v1.3.1 From 57de6016f9470904228f7b8d6dbe467251922757 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Sun, 8 Jan 2023 11:20:15 +0100 Subject: ip3511 : Fix IAR build. --- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 9b490c48c..124656307 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -139,7 +139,7 @@ typedef union TU_ATTR_PACKED uint32_t stall : 1 ; uint32_t disable : 1 ; uint32_t active : 1 ; - }; + } cmd_sts; }ep_cmd_sts_t; TU_VERIFY_STATIC( sizeof(ep_cmd_sts_t) == 4, "size is not correct" ); @@ -329,7 +329,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) // TODO cannot able to STALL Control OUT endpoint !!!!! FIXME try some walk-around uint8_t const ep_id = ep_addr2id(ep_addr); - _dcd.ep[ep_id][0].stall = 1; + _dcd.ep[ep_id][0].cmd_sts.stall = 1; } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) @@ -338,9 +338,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const ep_id = ep_addr2id(ep_addr); - _dcd.ep[ep_id][0].stall = 0; - _dcd.ep[ep_id][0].toggle_reset = 1; - _dcd.ep[ep_id][0].toggle_mode = 0; + _dcd.ep[ep_id][0].cmd_sts.stall = 0; + _dcd.ep[ep_id][0].cmd_sts.toggle_reset = 1; + _dcd.ep[ep_id][0].cmd_sts.toggle_mode = 0; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) @@ -349,10 +349,10 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) uint8_t ep_id = ep_addr2id(p_endpoint_desc->bEndpointAddress); // Check if endpoint is available - TU_ASSERT( _dcd.ep[ep_id][0].disable && _dcd.ep[ep_id][1].disable ); + TU_ASSERT( _dcd.ep[ep_id][0].cmd_sts.disable && _dcd.ep[ep_id][1].cmd_sts.disable ); edpt_reset(rhport, ep_id); - _dcd.ep[ep_id][0].is_iso = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + _dcd.ep[ep_id][0].cmd_sts.is_iso = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); // Enable EP interrupt dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; @@ -365,8 +365,8 @@ void dcd_edpt_close_all (uint8_t rhport) { for (uint8_t ep_id = 0; ep_id < 2*_dcd_controller[rhport].ep_pairs; ++ep_id) { - _dcd.ep[ep_id][0].active = _dcd.ep[ep_id][0].active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) - _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; + _dcd.ep[ep_id][0].cmd_sts.active = _dcd.ep[ep_id][0].cmd_sts.active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) + _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } } @@ -375,8 +375,8 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) (void) rhport; uint8_t ep_id = ep_addr2id(ep_addr); - _dcd.ep[ep_id][0].active = _dcd.ep[ep_id][0].active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) - _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; + _dcd.ep[ep_id][0].cmd_sts.active = _dcd.ep[ep_id][0].cmd_sts.active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) + _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) @@ -385,7 +385,7 @@ static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) { - nbytes = tu_min16(total_bytes, _dcd.ep[ep_id][0].is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX); + nbytes = tu_min16(total_bytes, _dcd.ep[ep_id][0].cmd_sts.is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX); _dcd.ep[ep_id][0].buffer_fs.offset = buf_offset; _dcd.ep[ep_id][0].buffer_fs.nbytes = nbytes; }else @@ -397,7 +397,7 @@ static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, _dcd.dma[ep_id].nbytes = nbytes; - _dcd.ep[ep_id][0].active = 1; + _dcd.ep[ep_id][0].cmd_sts.active = 1; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) @@ -431,7 +431,7 @@ static void bus_reset(uint8_t rhport) // disable all endpoints as specified by LPC55S69 UM Table 778 for(uint8_t ep_id = 0; ep_id < 2*MAX_EP_PAIRS; ep_id++) { - _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; + _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; @@ -459,7 +459,7 @@ static void process_xfer_isr(uint8_t rhport, uint32_t int_status) if ( ep_id == 0 || ep_id == 1) { // For control endpoint, we need to manually clear Active bit - ep_cs->active = 0; + ep_cs->cmd_sts.active = 0; } uint16_t buf_offset; @@ -556,8 +556,8 @@ void dcd_int_handler(uint8_t rhport) if ( tu_bit_test(int_status, 0) && (cmd_stat & CMDSTAT_SETUP_RECEIVED_MASK) ) { // Follow UM flowchart to clear Active & Stall on both Control IN/OUT endpoints - _dcd.ep[0][0].active = _dcd.ep[1][0].active = 0; - _dcd.ep[0][0].stall = _dcd.ep[1][0].stall = 0; + _dcd.ep[0][0].cmd_sts.active = _dcd.ep[1][0].cmd_sts.active = 0; + _dcd.ep[0][0].cmd_sts.stall = _dcd.ep[1][0].cmd_sts.stall = 0; dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK; -- cgit v1.3.1 From 9d19ed940e303ea01a685ebba986b24713f5febd Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Wed, 11 Jan 2023 18:49:15 +0100 Subject: dwc2: fix IAR warnings. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 9 ++++++--- src/portable/synopsys/dwc2/dwc2_stm32.h | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index b53735a5e..c6132a1f5 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -529,8 +529,10 @@ void dcd_init (uint8_t rhport) dwc2->dcfg |= DCFG_NZLSOHSK; // Clear all interrupts - dwc2->gintsts |= dwc2->gintsts; - dwc2->gotgint |= dwc2->gotgint; + uint32_t int_mask = dwc2->gintsts; + dwc2->gintsts |= int_mask; + int_mask = dwc2->gotgint; + dwc2->gotgint |= int_mask; // Required as part of core initialization. // TODO: How should mode mismatch be handled? It will cause @@ -1219,7 +1221,8 @@ void dcd_int_handler(uint8_t rhport) { dwc2_regs_t *dwc2 = DWC2_REG(rhport); - uint32_t const int_status = dwc2->gintsts & dwc2->gintmsk; + uint32_t const int_mask = dwc2->gintmsk; + uint32_t const int_status = dwc2->gintsts & int_mask; if(int_status & GINTSTS_USBRST) { diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index b63d1fcd0..cb455bd90 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -122,13 +122,13 @@ static const dwc2_controller_t _dwc2_controller[] = TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { - NVIC_EnableIRQ(_dwc2_controller[rhport].irqnum); + NVIC_EnableIRQ((IRQn_Type)_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { - NVIC_DisableIRQ(_dwc2_controller[rhport].irqnum); + NVIC_DisableIRQ((IRQn_Type)_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE -- cgit v1.3.1 From 3cc6cece0783e893d9fadc868f7fb58c81625fe0 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Jan 2023 10:25:48 +0700 Subject: add note for openocd with wch, also add wch-riscv.cfg --- hw/bsp/ch32v307/family.mk | 18 +++++++++++++++--- hw/bsp/ch32v307/wch-riscv.cfg | 15 +++++++++++++++ src/portable/wch/ch32v307/usb_dc_usbhs.c | 4 ++-- 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 hw/bsp/ch32v307/wch-riscv.cfg (limited to 'src') diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 12565016d..58542041f 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -30,7 +30,7 @@ CFLAGS += \ -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ -Xlinker --gc-sections \ - -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED # caused by extra void USART_Printf_Init() in debug_uart.h and EVT/EXAME/SRC/DEBUG/debug.h CFLAGS += -Wno-error=redundant-decls @@ -51,7 +51,6 @@ SRC_S += \ INC += \ src/portable/wch/ch32v307 \ - $(TOP)/$(BOARD_PATH)/.. \ $(TOP)/$(BOARD_PATH) \ $(CH32V307_SDK_SRC_TOP)/Peripheral/inc \ $(CH32V307_SDK_SRC_TOP)/Debug \ @@ -60,6 +59,19 @@ INC += \ # For freeRTOS port source FREERTOS_PORT = RISC-V +# wch-link is not supported yet in official openOCD yet. We need to either use +# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or +# 2. compiled from modified source https://github.com/kprasadvnsi/riscv-openocd-wch +# +# Note: For Linux, somehow openocd in mounriver studio does not seem to have wch-link enable, +# therefore we need to compile it from source as follows: +# git clone https://github.com/kprasadvnsi/riscv-openocd-wch +# cd riscv-openocd-wch +# ./bootstrap +# ./configure CFLAGS="-Wno-error" --enable-wlink +# make +# openocd binaries will be generated in riscv-openocd-wch/src + # flash target ROM bootloader flash: $(BUILD)/$(PROJECT).elf - openocd -f wch-riscv.cfg -c init -c halt -c "program $< 0x08000000" -c reset -c exit + openocd -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "program $<" -c reset -c exit diff --git a/hw/bsp/ch32v307/wch-riscv.cfg b/hw/bsp/ch32v307/wch-riscv.cfg new file mode 100644 index 000000000..0d24d16ca --- /dev/null +++ b/hw/bsp/ch32v307/wch-riscv.cfg @@ -0,0 +1,15 @@ +#interface wlink +adapter driver wlink +wlink_set +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" diff --git a/src/portable/wch/ch32v307/usb_dc_usbhs.c b/src/portable/wch/ch32v307/usb_dc_usbhs.c index e647389ee..39fd41392 100644 --- a/src/portable/wch/ch32v307/usb_dc_usbhs.c +++ b/src/portable/wch/ch32v307/usb_dc_usbhs.c @@ -70,7 +70,7 @@ void dcd_init(uint8_t rhport) { USBHSD->CONTROL = 0; -#if (BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_HIGH_SPEED) +#if TUD_OPT_HIGH_SPEED USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; #else #error OPT_MODE_FULL_SPEED not currently supported on CH32V307 @@ -383,4 +383,4 @@ void dcd_int_handler(uint8_t rhport) { } } -#endif \ No newline at end of file +#endif -- cgit v1.3.1 From e61d4aefe6b9fbab862e7c440ff9ff25ebb5092c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Jan 2023 12:08:56 +0700 Subject: rename driver with dcd_ to be consitent with other ports --- hw/bsp/ch32v307/family.mk | 22 +- src/portable/wch/ch32v307/ch32_usbhs_reg.h | 345 ++++++++++++++++++++++ src/portable/wch/ch32v307/dcd_usbhs.c | 386 +++++++++++++++++++++++++ src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h | 345 ---------------------- src/portable/wch/ch32v307/usb_dc_usbhs.c | 386 ------------------------- 5 files changed, 740 insertions(+), 744 deletions(-) create mode 100644 src/portable/wch/ch32v307/ch32_usbhs_reg.h create mode 100644 src/portable/wch/ch32v307/dcd_usbhs.c delete mode 100644 src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h delete mode 100644 src/portable/wch/ch32v307/usb_dc_usbhs.c (limited to 'src') diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 58542041f..ffc992f21 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -10,8 +10,6 @@ DEPS_SUBMODULES += $(CH32V307_SDK) # WCH-SDK paths CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC -CH32V307_SDK_SRC_TOP = $(TOP)/$(CH32V307_SDK_SRC) -CH32V307_STARTUP_ASM = $(CH32V307_SDK_SRC)/Startup include $(TOP)/$(BOARD_PATH)/board.mk @@ -39,22 +37,20 @@ LDFLAGS += \ -Xlinker --gc-sections --specs=nano.specs --specs=nosys.specs SRC_C += \ - src/portable/wch/ch32v307/usb_dc_usbhs.c \ - $(CH32V307_SDK_SRC_TOP)/Core/core_riscv.c \ - $(CH32V307_SDK_SRC_TOP)/Peripheral/src/ch32v30x_gpio.c \ - $(CH32V307_SDK_SRC_TOP)/Peripheral/src/ch32v30x_misc.c \ - $(CH32V307_SDK_SRC_TOP)/Peripheral/src/ch32v30x_rcc.c \ - $(CH32V307_SDK_SRC_TOP)/Peripheral/src/ch32v30x_usart.c + src/portable/wch/ch32v307/dcd_usbhs.c \ + $(CH32V307_SDK_SRC)/Core/core_riscv.c \ + $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_gpio.c \ + $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_misc.c \ + $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_rcc.c \ + $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_usart.c SRC_S += \ - $(CH32V307_STARTUP_ASM)/startup_ch32v30x_D8C.S + $(CH32V307_SDK_SRC)/Startup/startup_ch32v30x_D8C.S INC += \ - src/portable/wch/ch32v307 \ $(TOP)/$(BOARD_PATH) \ - $(CH32V307_SDK_SRC_TOP)/Peripheral/inc \ - $(CH32V307_SDK_SRC_TOP)/Debug \ - $(CH32V307_SDK_SRC_TOP) + $(TOP)/$(CH32V307_SDK_SRC)/Peripheral/inc \ + $(TOP)/$(CH32V307_SDK_SRC)/Debug # For freeRTOS port source FREERTOS_PORT = RISC-V diff --git a/src/portable/wch/ch32v307/ch32_usbhs_reg.h b/src/portable/wch/ch32v307/ch32_usbhs_reg.h new file mode 100644 index 000000000..5a2c1fbc9 --- /dev/null +++ b/src/portable/wch/ch32v307/ch32_usbhs_reg.h @@ -0,0 +1,345 @@ +#ifndef _USB_CH32_USBHS_REG_H +#define _USB_CH32_USBHS_REG_H + +#include + +/******************* GLOBAL ******************/ + +// USB CONTROL +#define USBHS_CONTROL_OFFSET 0x00 +#define USBHS_DMA_EN (1 << 0) +#define USBHS_ALL_CLR (1 << 1) +#define USBHS_FORCE_RST (1 << 2) +#define USBHS_INT_BUSY_EN (1 << 3) +#define USBHS_DEV_PU_EN (1 << 4) +#define USBHS_SPEED_MASK (3 << 5) +#define USBHS_FULL_SPEED (0 << 5) +#define USBHS_HIGH_SPEED (1 << 5) +#define USBHS_LOW_SPEED (2 << 5) +#define USBHS_HOST_MODE (1 << 7) + +// USB_INT_EN +#define USBHS_INT_EN_OFFSET 0x02 +#define USBHS_BUS_RST_EN (1 << 0) +#define USBHS_DETECT_EN (1 << 0) +#define USBHS_TRANSFER_EN (1 << 1) +#define USBHS_SUSPEND_EN (1 << 2) +#define USBHS_SOF_ACT_EN (1 << 3) +#define USBHS_FIFO_OV_EN (1 << 4) +#define USBHS_SETUP_ACT_EN (1 << 5) +#define USBHS_ISO_ACT_EN (1 << 6) +#define USBHS_DEV_NAK_EN (1 << 7) + +// USB DEV AD +#define USBHS_DEV_AD_OFFSET 0x03 +// USB FRAME_NO +#define USBHS_FRAME_NO_OFFSET 0x04 +// USB SUSPEND +#define USBHS_SUSPEND_OFFSET 0x06 +#define USBHS_DEV_REMOTE_WAKEUP (1 << 2) +#define USBHS_LINESTATE_MASK (2 << 4) /* Read Only */ + +// RESERVED0 + +// USB SPEED TYPE +#define USBHS_SPEED_TYPE_OFFSET 0x08 +#define USBSPEED_MASK (0x03) + +// USB_MIS_ST +#define USBHS_MIS_ST_OFFSET 0x09 +#define USBHS_SPLIT_CAN (1 << 0) +#define USBHS_ATTACH (1 << 1) +#define USBHS_SUSPEND (1 << 2) +#define USBHS_BUS_RESET (1 << 3) +#define USBHS_R_FIFO_RDY (1 << 4) +#define USBHS_SIE_FREE (1 << 5) +#define USBHS_SOF_ACT (1 << 6) +#define USBHS_SOF_PRES (1 << 7) + +// INT_FLAG +#define USBHS_INT_FLAG_OFFSET 0x0A +#define USBHS_BUS_RST_FLAG (1 << 0) +#define USBHS_DETECT_FLAG (1 << 0) +#define USBHS_TRANSFER_FLAG (1 << 1) +#define USBHS_SUSPEND_FLAG (1 << 2) +#define USBHS_HST_SOF_FLAG (1 << 3) +#define USBHS_FIFO_OV_FLAG (1 << 4) +#define USBHS_SETUP_FLAG (1 << 5) +#define USBHS_ISO_ACT_FLAG (1 << 6) + +// INT_ST +#define USBHS_INT_ST_OFFSET 0x0B +#define USBHS_DEV_UIS_IS_NAK (1 << 7) +#define USBHS_DEV_UIS_TOG_OK (1 << 6) +#define MASK_UIS_TOKEN (3 << 4) +#define MASK_UIS_ENDP (0x0F) +#define MASK_UIS_H_RES (0x0F) + +#define USBHS_TOGGLE_OK (0x40) +#define USBHS_HOST_RES (0x0f) + +//USB_RX_LEN +#define USBHS_RX_LEN_OFFSET 0x0C +/******************* DEVICE ******************/ + +//UEP_CONFIG +#define USBHS_UEP_CONFIG_OFFSET 0x10 +#define USBHS_EP0_T_EN (1 << 0) +#define USBHS_EP0_R_EN (1 << 16) + +#define USBHS_EP1_T_EN (1 << 1) +#define USBHS_EP1_R_EN (1 << 17) + +#define USBHS_EP2_T_EN (1 << 2) +#define USBHS_EP2_R_EN (1 << 18) + +#define USBHS_EP3_T_EN (1 << 3) +#define USBHS_EP3_R_EN (1 << 19) + +#define USBHS_EP4_T_EN (1 << 4) +#define USBHS_EP4_R_EN (1 << 20) + +#define USBHS_EP5_T_EN (1 << 5) +#define USBHS_EP5_R_EN (1 << 21) + +#define USBHS_EP6_T_EN (1 << 6) +#define USBHS_EP6_R_EN (1 << 22) + +#define USBHS_EP7_T_EN (1 << 7) +#define USBHS_EP7_R_EN (1 << 23) + +#define USBHS_EP8_T_EN (1 << 8) +#define USBHS_EP8_R_EN (1 << 24) + +#define USBHS_EP9_T_EN (1 << 9) +#define USBHS_EP9_R_EN (1 << 25) + +#define USBHS_EP10_T_EN (1 << 10) +#define USBHS_EP10_R_EN (1 << 26) + +#define USBHS_EP11_T_EN (1 << 11) +#define USBHS_EP11_R_EN (1 << 27) + +#define USBHS_EP12_T_EN (1 << 12) +#define USBHS_EP12_R_EN (1 << 28) + +#define USBHS_EP13_T_EN (1 << 13) +#define USBHS_EP13_R_EN (1 << 29) + +#define USBHS_EP14_T_EN (1 << 14) +#define USBHS_EP14_R_EN (1 << 30) + +#define USBHS_EP15_T_EN (1 << 15) +#define USBHS_EP15_R_EN (1 << 31) + +//UEP_TYPE +#define USBHS_UEP_TYPE_OFFSET 0x14 +#define USBHS_EP0_T_TYP (1 << 0) +#define USBHS_EP0_R_TYP (1 << 16) + +#define USBHS_EP1_T_TYP (1 << 1) +#define USBHS_EP1_R_TYP (1 << 17) + +#define USBHS_EP2_T_TYP (1 << 2) +#define USBHS_EP2_R_TYP (1 << 18) + +#define USBHS_EP3_T_TYP (1 << 3) +#define USBHS_EP3_R_TYP (1 << 19) + +#define USBHS_EP4_T_TYP (1 << 4) +#define USBHS_EP4_R_TYP (1 << 20) + +#define USBHS_EP5_T_TYP (1 << 5) +#define USBHS_EP5_R_TYP (1 << 21) + +#define USBHS_EP6_T_TYP (1 << 6) +#define USBHS_EP6_R_TYP (1 << 22) + +#define USBHS_EP7_T_TYP (1 << 7) +#define USBHS_EP7_R_TYP (1 << 23) + +#define USBHS_EP8_T_TYP (1 << 8) +#define USBHS_EP8_R_TYP (1 << 24) + +#define USBHS_EP9_T_TYP (1 << 8) +#define USBHS_EP9_R_TYP (1 << 25) + +#define USBHS_EP10_T_TYP (1 << 10) +#define USBHS_EP10_R_TYP (1 << 26) + +#define USBHS_EP11_T_TYP (1 << 11) +#define USBHS_EP11_R_TYP (1 << 27) + +#define USBHS_EP12_T_TYP (1 << 12) +#define USBHS_EP12_R_TYP (1 << 28) + +#define USBHS_EP13_T_TYP (1 << 13) +#define USBHS_EP13_R_TYP (1 << 29) + +#define USBHS_EP14_T_TYP (1 << 14) +#define USBHS_EP14_R_TYP (1 << 30) + +#define USBHS_EP15_T_TYP (1 << 15) +#define USBHS_EP15_R_TYP (1 << 31) + +/* BUF_MOD UEP1~15 */ +#define USBHS_BUF_MOD_OFFSET 0x18 +#define USBHS_EP0_BUF_MOD (1 << 0) +#define USBHS_EP0_ISO_BUF_MOD (1 << 16) + +#define USBHS_EP1_BUF_MOD (1 << 1) +#define USBHS_EP1_ISO_BUF_MOD (1 << 17) + +#define USBHS_EP2_BUF_MOD (1 << 2) +#define USBHS_EP2_ISO_BUF_MOD (1 << 18) + +#define USBHS_EP3_BUF_MOD (1 << 3) +#define USBHS_EP3_ISO_BUF_MOD (1 << 19) + +#define USBHS_EP4_BUF_MOD (1 << 4) +#define USBHS_EP4_ISO_BUF_MOD (1 << 20) + +#define USBHS_EP5_BUF_MOD (1 << 5) +#define USBHS_EP5_ISO_BUF_MOD (1 << 21) + +#define USBHS_EP6_BUF_MOD (1 << 6) +#define USBHS_EP6_ISO_BUF_MOD (1 << 22) + +#define USBHS_EP7_BUF_MOD (1 << 7) +#define USBHS_EP7_ISO_BUF_MOD (1 << 23) + +#define USBHS_EP8_BUF_MOD (1 << 8) +#define USBHS_EP8_ISO_BUF_MOD (1 << 24) + +#define USBHS_EP9_BUF_MOD (1 << 9) +#define USBHS_EP9_ISO_BUF_MOD (1 << 25) + +#define USBHS_EP10_BUF_MOD (1 << 10) +#define USBHS_EP10_ISO_BUF_MOD (1 << 26) + +#define USBHS_EP11_BUF_MOD (1 << 11) +#define USBHS_EP11_ISO_BUF_MOD (1 << 27) + +#define USBHS_EP12_BUF_MOD (1 << 12) +#define USBHS_EP12_ISO_BUF_MOD (1 << 28) + +#define USBHS_EP13_BUF_MOD (1 << 13) +#define USBHS_EP13_ISO_BUF_MOD (1 << 29) + +#define USBHS_EP14_BUF_MOD (1 << 14) +#define USBHS_EP14_ISO_BUF_MOD (1 << 30) + +#define USBHS_EP15_BUF_MOD (1 << 15) +#define USBHS_EP15_ISO_BUF_MOD (1 << 31) +//USBHS_EPn_T_EN USBHS_EPn_R_EN USBHS_EPn_BUF_MOD Description: Arrange from low to high with UEPn_DMA as the starting address +// 0 0 x The endpoint is disabled and the UEPn_*_DMA buffers are not used. +// 1 0 0 The first address of the receive (OUT) buffer is UEPn_RX_DMA +// 1 0 1 RB_UEPn_RX_TOG[0]=0, use buffer UEPn_RX_DMA RB_UEPn_RX_TOG[0]=1, use buffer UEPn_TX_DMA +// 0 1 0 The first address of the transmit (IN) buffer is UEPn_TX_DMA. +// 0 1 1 RB_UEPn_TX_TOG[0]=0, use buffer UEPn_TX_DMA RB_UEPn_TX_TOG[0]=1, use buffer UEPn_RX_DMA + +/* USB0_DMA */ +#define USBHS_UEP0_DMA_OFFSET(n) (0x1C) // endpoint 0 DMA buffer address + +/* USBX_RX_DMA */ +#define USBHS_UEPx_RX_DMA_OFFSET(n) (0x1C + 4 * (n)) // endpoint x DMA buffer address + +#define USBHS_UEPx_TX_DMA_OFFSET(n) (0x58 + 4 * (n)) // endpoint x DMA buffer address + +#define USBHS_UEPx_MAX_LEN_OFFSET(n) (0x98 + 4 * (n)) // endpoint x DMA buffer address + +#define USBHS_UEPx_T_LEN_OFFSET(n) (0xD8 + 4 * (n)) // endpoint x DMA buffer address +#define USBHS_UEPx_TX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 2) // endpoint x DMA buffer address +#define USBHS_UEPx_RX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 3) // endpoint x DMA buffer address + +// UEPn_T_LEN +#define USBHS_EP_T_LEN_MASK (0x7FF) + +//UEPn_TX_CTRL +#define USBHS_EP_T_RES_MASK (3 << 0) +#define USBHS_EP_T_RES_ACK (0 << 0) +#define USBHS_EP_T_RES_NYET (1 << 0) +#define USBHS_EP_T_RES_NAK (2 << 0) +#define USBHS_EP_T_RES_STALL (3 << 0) + +#define USBHS_EP_T_TOG_MASK (3 << 3) +#define USBHS_EP_T_TOG_0 (0 << 3) +#define USBHS_EP_T_TOG_1 (1 << 3) +#define USBHS_EP_T_TOG_2 (2 << 3) +#define USBHS_EP_T_TOG_M (3 << 3) + +#define USBHS_EP_T_AUTOTOG (1 << 5) + +//UEPn_RX_CTRL +#define USBHS_EP_R_RES_MASK (3 << 0) +#define USBHS_EP_R_RES_ACK (0 << 0) +#define USBHS_EP_R_RES_NYET (1 << 0) +#define USBHS_EP_R_RES_NAK (2 << 0) +#define USBHS_EP_R_RES_STALL (3 << 0) + +#define USBHS_EP_R_TOG_MASK (3 << 3) +#define USBHS_EP_R_TOG_0 (0 << 3) +#define USBHS_EP_R_TOG_1 (1 << 3) +#define USBHS_EP_R_TOG_2 (2 << 3) +#define USBHS_EP_R_TOG_M (3 << 3) + +#define USBHS_EP_R_AUTOTOG (1 << 5) + +#define USBHS_TOG_MATCH (1 << 6) + +/******************* HOST ******************/ +// USB HOST_CTRL +#define USBHS_SEND_BUS_RESET (1 << 0) +#define USBHS_SEND_BUS_SUSPEND (1 << 1) +#define USBHS_SEND_BUS_RESUME (1 << 2) +#define USBHS_REMOTE_WAKE (1 << 3) +#define USBHS_PHY_SUSPENDM (1 << 4) +#define USBHS_UH_SOFT_FREE (1 << 6) +#define USBHS_SEND_SOF_EN (1 << 7) + +//UH_CONFIG +#define USBHS_HOST_TX_EN (1 << 3) +#define USBHS_HOST_RX_EN (1 << 18) + +// HOST_EP_TYPE +#define USBHS_ENDP_TX_ISO (1 << 3) +#define USBHS_ENDP_RX_ISO (1 << (16 + 2)) + +// R32_UH_EP_PID +#define USBHS_HOST_MASK_TOKEN (0x0f) +#define USBHS_HOST_MASK_ENDP (0x0f << 4) + +//R8_UH_RX_CTRL +#define USBHS_EP_R_RES_MASK (3 << 0) +#define USBHS_EP_R_RES_ACK (0 << 0) +#define USBHS_EP_R_RES_NYET (1 << 0) +#define USBHS_EP_R_RES_NAK (2 << 0) +#define USBHS_EP_R_RES_STALL (3 << 0) + +#define USBHS_UH_R_RES_NO (1 << 2) +#define USBHS_UH_R_TOG_1 (1 << 3) +#define USBHS_UH_R_TOG_2 (2 << 3) +#define USBHS_UH_R_TOG_3 (3 << 3) +#define USBHS_UH_R_TOG_AUTO (1 << 5) +#define USBHS_UH_R_DATA_NO (1 << 6) +//R8_UH_TX_CTRL +#define USBHS_UH_T_RES_MASK (3 << 0) +#define USBHS_UH_T_RES_ACK (0 << 0) +#define USBHS_UH_T_RES_NYET (1 << 0) +#define USBHS_UH_T_RES_NAK (2 << 0) +#define USBHS_UH_T_RES_STALL (3 << 0) + +#define USBHS_UH_T_RES_NO (1 << 2) +#define USBHS_UH_T_TOG_1 (1 << 3) +#define USBHS_UH_T_TOG_2 (2 << 3) +#define USBHS_UH_T_TOG_3 (3 << 3) +#define USBHS_UH_T_TOG_AUTO (1 << 5) +#define USBHS_UH_T_DATA_NO (1 << 6) + +// 00: OUT, 01:SOF, 10:IN, 11:SETUP +#define PID_OUT 0 +#define PID_SOF 1 +#define PID_IN 2 +#define PID_SETUP 3 + +#endif diff --git a/src/portable/wch/ch32v307/dcd_usbhs.c b/src/portable/wch/ch32v307/dcd_usbhs.c new file mode 100644 index 000000000..7a0dcfc23 --- /dev/null +++ b/src/portable/wch/ch32v307/dcd_usbhs.c @@ -0,0 +1,386 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Greg Davill + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V307) +#include "device/dcd.h" + +#include "ch32_usbhs_reg.h" +#include "core_riscv.h" + +// Max number of bi-directional endpoints including EP0 +#define EP_MAX 16 + +typedef struct { + uint8_t *buffer; + // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API + uint16_t total_len; + uint16_t queued_len; + uint16_t max_size; + bool short_packet; +} xfer_ctl_t; + +#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] +static xfer_ctl_t xfer_status[EP_MAX][2]; + +#define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep)*2) +#define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep)*4) +#define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep)*4) +#define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep)*2) + +#define EP_TX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_TX_DMA) + (ep - 1)) +#define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) + +/* Endpoint Buffer */ +TU_ATTR_ALIGNED(4) uint8_t EP0_DatabufHD[64]; // ep0(64) + +volatile uint8_t USBHS_Dev_Endp0_Tog = 0x01; + +void dcd_init(uint8_t rhport) { + (void)rhport; + + memset(&xfer_status, 0, sizeof(xfer_status)); + + USBHSD->HOST_CTRL = 0x00; + USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; + + USBHSD->CONTROL = 0; + +#if TUD_OPT_HIGH_SPEED + USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; +#else + #error OPT_MODE_FULL_SPEED not currently supported on CH32V307 + USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; +#endif + + USBHSD->INT_EN = 0; + USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN; + + /* ALL endpoint enable */ + USBHSD->ENDP_CONFIG = 0xffffffff; + + USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; + USBHSD->ENDP_TYPE = 0x00; + USBHSD->BUF_MODE = 0x00; + + USBHSD->UEP0_MAX_LEN = 64; + + USBHSD->UEP0_DMA = (uint32_t)EP0_DatabufHD; + + USBHSD->UEP0_TX_LEN = 0; + USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_NAK; + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; + + for (int ep = 1; ep < EP_MAX; ep++) { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + + EP_RX_MAX_LEN(ep) = 512; + } + + USBHSD->DEV_AD = 0; + USBHSD->CONTROL |= USBHS_DEV_PU_EN; +} + +void dcd_int_enable(uint8_t rhport) { + (void)rhport; + + NVIC_EnableIRQ(USBHS_IRQn); +} + +void dcd_int_disable(uint8_t rhport) { + (void)rhport; + + NVIC_DisableIRQ(USBHS_IRQn); +} + +void dcd_edpt_close_all(uint8_t rhport) { + (void)rhport; +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void)dev_addr; + + // Response with zlp status + dcd_edpt_xfer(rhport, 0x80, NULL, 0); +} + +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { + (void)rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBHSD->DEV_AD = (uint8_t)request->wValue; + } + + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { + (void)rhport; + + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + TU_ASSERT(epnum < EP_MAX); + + xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); + + if (epnum != 0) { + if (tu_edpt_dir(desc_edpt->bEndpointAddress) == TUSB_DIR_OUT) { + EP_RX_CTRL(epnum) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK; + } else { + EP_TX_LEN(epnum) = 0; + EP_TX_CTRL(epnum) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + } + } + + return true; +} + +int usbd_ep_close(const uint8_t ep) { + (void)ep; + + return 0; +} +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (epnum == 0) { + if (dir == TUSB_DIR_OUT) { + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_STALL; + } else { + USBHSD->UEP0_TX_LEN = 0; + USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_STALL; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL; + + } else { + EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (epnum == 0) { + if (dir == TUSB_DIR_OUT) { + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; + } else { + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~(USBHS_EP_R_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_ACK; + + } else { + EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_NAK; + } + } +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void)rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->short_packet = false; + + // uint16_t num_packets = (total_bytes / xfer->max_size); + uint16_t short_packet_size = total_bytes % (xfer->max_size + 1); + + // Zero-size packet is special case. + if (short_packet_size == 0 || (total_bytes == 0)) { + xfer->short_packet = true; + } + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + if (!total_bytes) { + xfer->short_packet = true; + if (epnum == 0) { + USBHSD->UEP0_TX_LEN = 0; + USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); + USBHS_Dev_Endp0_Tog ^= 1; + } else { + EP_TX_LEN(epnum) = 0; + EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; + } + } else { + if (epnum == 0) { + xfer->queued_len += short_packet_size; + memcpy(&EP0_DatabufHD[0], buffer, short_packet_size); + + USBHSD->UEP0_TX_LEN = short_packet_size; + USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); + USBHS_Dev_Endp0_Tog ^= 1; + } else { + xfer->queued_len += short_packet_size; + + EP_TX_DMA_ADDR(epnum) = (uint32_t)buffer; + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << epnum); + EP_TX_LEN(epnum) = short_packet_size; + EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; + } + } + } else { /* TUSB_DIR_OUT */ + if (epnum == 0) { + uint32_t read_count = USBHSD->RX_LEN; + read_count = TU_MIN(read_count, total_bytes); + + if ((total_bytes == 8)) { + read_count = 8; + memcpy(buffer, &EP0_DatabufHD[0], 8); + } else { + memcpy(buffer, &EP0_DatabufHD[0], read_count); + } + } else { + EP_RX_DMA_ADDR(epnum) = (uint32_t)xfer->buffer; + USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << epnum); + } + + // usbd_ep_read(ep_addr, buffer, total_bytes, &ret_bytes); + } + return true; +} + + +static void receive_packet(xfer_ctl_t *xfer, uint16_t xfer_size) { + // xfer->queued_len = xfer->total_len - remaining; + + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t to_recv_size; + + if (remaining <= xfer->max_size) { + // Avoid buffer overflow. + to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; + } else { + // Room for full packet, choose recv_size based on what the microcontroller + // claims. + to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; + } + + if (to_recv_size) { + } + + xfer->queued_len += xfer_size; + + // Per USB spec, a short OUT packet (including length 0) is always + // indicative of the end of a transfer (at least for ctl, bulk, int). + xfer->short_packet = (xfer_size < xfer->max_size); +} + +void dcd_int_handler(uint8_t rhport) { + (void)rhport; + + uint32_t end_num, rx_token; + uint8_t intflag = 0; + + intflag = USBHSD->INT_FG; + + if (intflag & USBHS_TRANSFER_FLAG) { + + end_num = (USBHSD->INT_ST) & MASK_UIS_ENDP; + rx_token = (((USBHSD->INT_ST) & MASK_UIS_TOKEN) >> 4) & 0x03; + + uint8_t endp = end_num | (rx_token == PID_IN ? TUSB_DIR_IN_MASK : 0); + + xfer_ctl_t *xfer = XFER_CTL_BASE(end_num, tu_edpt_dir(endp)); + + if (rx_token == PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + receive_packet(xfer, rx_len); + + if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { + xfer->short_packet = false; + + dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } + + if (end_num == 0) { + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + } + + } else if (rx_token == PID_IN) { + if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { + xfer->short_packet = false; + xfer->total_len = 0; + dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); + + EP_TX_CTRL(end_num) = (EP_TX_CTRL(end_num) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_NAK; + + if (end_num == 0) { + } + } else { + dcd_edpt_xfer(0, endp, xfer->buffer + xfer->queued_len, xfer->total_len - xfer->queued_len); + } + } + + USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ + } else if (intflag & USBHS_SETUP_FLAG) { + USBHS_Dev_Endp0_Tog = 1; + dcd_event_setup_received(0, EP0_DatabufHD, true); + + USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ + } else if (intflag & USBHS_DETECT_FLAG) { + USBHS_Dev_Endp0_Tog = 1; + + xfer_status[0][TUSB_DIR_OUT].max_size = 64; + xfer_status[0][TUSB_DIR_IN].max_size = 64; + + dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); + + USBHSD->DEV_AD = 0; + USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + + USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ + } else if (intflag & USBHS_SUSPEND_FLAG) { + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; + dcd_event_handler(&event, true); + + USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ + } +} + +#endif diff --git a/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h b/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h deleted file mode 100644 index 5a2c1fbc9..000000000 --- a/src/portable/wch/ch32v307/usb_ch32_usbhs_reg.h +++ /dev/null @@ -1,345 +0,0 @@ -#ifndef _USB_CH32_USBHS_REG_H -#define _USB_CH32_USBHS_REG_H - -#include - -/******************* GLOBAL ******************/ - -// USB CONTROL -#define USBHS_CONTROL_OFFSET 0x00 -#define USBHS_DMA_EN (1 << 0) -#define USBHS_ALL_CLR (1 << 1) -#define USBHS_FORCE_RST (1 << 2) -#define USBHS_INT_BUSY_EN (1 << 3) -#define USBHS_DEV_PU_EN (1 << 4) -#define USBHS_SPEED_MASK (3 << 5) -#define USBHS_FULL_SPEED (0 << 5) -#define USBHS_HIGH_SPEED (1 << 5) -#define USBHS_LOW_SPEED (2 << 5) -#define USBHS_HOST_MODE (1 << 7) - -// USB_INT_EN -#define USBHS_INT_EN_OFFSET 0x02 -#define USBHS_BUS_RST_EN (1 << 0) -#define USBHS_DETECT_EN (1 << 0) -#define USBHS_TRANSFER_EN (1 << 1) -#define USBHS_SUSPEND_EN (1 << 2) -#define USBHS_SOF_ACT_EN (1 << 3) -#define USBHS_FIFO_OV_EN (1 << 4) -#define USBHS_SETUP_ACT_EN (1 << 5) -#define USBHS_ISO_ACT_EN (1 << 6) -#define USBHS_DEV_NAK_EN (1 << 7) - -// USB DEV AD -#define USBHS_DEV_AD_OFFSET 0x03 -// USB FRAME_NO -#define USBHS_FRAME_NO_OFFSET 0x04 -// USB SUSPEND -#define USBHS_SUSPEND_OFFSET 0x06 -#define USBHS_DEV_REMOTE_WAKEUP (1 << 2) -#define USBHS_LINESTATE_MASK (2 << 4) /* Read Only */ - -// RESERVED0 - -// USB SPEED TYPE -#define USBHS_SPEED_TYPE_OFFSET 0x08 -#define USBSPEED_MASK (0x03) - -// USB_MIS_ST -#define USBHS_MIS_ST_OFFSET 0x09 -#define USBHS_SPLIT_CAN (1 << 0) -#define USBHS_ATTACH (1 << 1) -#define USBHS_SUSPEND (1 << 2) -#define USBHS_BUS_RESET (1 << 3) -#define USBHS_R_FIFO_RDY (1 << 4) -#define USBHS_SIE_FREE (1 << 5) -#define USBHS_SOF_ACT (1 << 6) -#define USBHS_SOF_PRES (1 << 7) - -// INT_FLAG -#define USBHS_INT_FLAG_OFFSET 0x0A -#define USBHS_BUS_RST_FLAG (1 << 0) -#define USBHS_DETECT_FLAG (1 << 0) -#define USBHS_TRANSFER_FLAG (1 << 1) -#define USBHS_SUSPEND_FLAG (1 << 2) -#define USBHS_HST_SOF_FLAG (1 << 3) -#define USBHS_FIFO_OV_FLAG (1 << 4) -#define USBHS_SETUP_FLAG (1 << 5) -#define USBHS_ISO_ACT_FLAG (1 << 6) - -// INT_ST -#define USBHS_INT_ST_OFFSET 0x0B -#define USBHS_DEV_UIS_IS_NAK (1 << 7) -#define USBHS_DEV_UIS_TOG_OK (1 << 6) -#define MASK_UIS_TOKEN (3 << 4) -#define MASK_UIS_ENDP (0x0F) -#define MASK_UIS_H_RES (0x0F) - -#define USBHS_TOGGLE_OK (0x40) -#define USBHS_HOST_RES (0x0f) - -//USB_RX_LEN -#define USBHS_RX_LEN_OFFSET 0x0C -/******************* DEVICE ******************/ - -//UEP_CONFIG -#define USBHS_UEP_CONFIG_OFFSET 0x10 -#define USBHS_EP0_T_EN (1 << 0) -#define USBHS_EP0_R_EN (1 << 16) - -#define USBHS_EP1_T_EN (1 << 1) -#define USBHS_EP1_R_EN (1 << 17) - -#define USBHS_EP2_T_EN (1 << 2) -#define USBHS_EP2_R_EN (1 << 18) - -#define USBHS_EP3_T_EN (1 << 3) -#define USBHS_EP3_R_EN (1 << 19) - -#define USBHS_EP4_T_EN (1 << 4) -#define USBHS_EP4_R_EN (1 << 20) - -#define USBHS_EP5_T_EN (1 << 5) -#define USBHS_EP5_R_EN (1 << 21) - -#define USBHS_EP6_T_EN (1 << 6) -#define USBHS_EP6_R_EN (1 << 22) - -#define USBHS_EP7_T_EN (1 << 7) -#define USBHS_EP7_R_EN (1 << 23) - -#define USBHS_EP8_T_EN (1 << 8) -#define USBHS_EP8_R_EN (1 << 24) - -#define USBHS_EP9_T_EN (1 << 9) -#define USBHS_EP9_R_EN (1 << 25) - -#define USBHS_EP10_T_EN (1 << 10) -#define USBHS_EP10_R_EN (1 << 26) - -#define USBHS_EP11_T_EN (1 << 11) -#define USBHS_EP11_R_EN (1 << 27) - -#define USBHS_EP12_T_EN (1 << 12) -#define USBHS_EP12_R_EN (1 << 28) - -#define USBHS_EP13_T_EN (1 << 13) -#define USBHS_EP13_R_EN (1 << 29) - -#define USBHS_EP14_T_EN (1 << 14) -#define USBHS_EP14_R_EN (1 << 30) - -#define USBHS_EP15_T_EN (1 << 15) -#define USBHS_EP15_R_EN (1 << 31) - -//UEP_TYPE -#define USBHS_UEP_TYPE_OFFSET 0x14 -#define USBHS_EP0_T_TYP (1 << 0) -#define USBHS_EP0_R_TYP (1 << 16) - -#define USBHS_EP1_T_TYP (1 << 1) -#define USBHS_EP1_R_TYP (1 << 17) - -#define USBHS_EP2_T_TYP (1 << 2) -#define USBHS_EP2_R_TYP (1 << 18) - -#define USBHS_EP3_T_TYP (1 << 3) -#define USBHS_EP3_R_TYP (1 << 19) - -#define USBHS_EP4_T_TYP (1 << 4) -#define USBHS_EP4_R_TYP (1 << 20) - -#define USBHS_EP5_T_TYP (1 << 5) -#define USBHS_EP5_R_TYP (1 << 21) - -#define USBHS_EP6_T_TYP (1 << 6) -#define USBHS_EP6_R_TYP (1 << 22) - -#define USBHS_EP7_T_TYP (1 << 7) -#define USBHS_EP7_R_TYP (1 << 23) - -#define USBHS_EP8_T_TYP (1 << 8) -#define USBHS_EP8_R_TYP (1 << 24) - -#define USBHS_EP9_T_TYP (1 << 8) -#define USBHS_EP9_R_TYP (1 << 25) - -#define USBHS_EP10_T_TYP (1 << 10) -#define USBHS_EP10_R_TYP (1 << 26) - -#define USBHS_EP11_T_TYP (1 << 11) -#define USBHS_EP11_R_TYP (1 << 27) - -#define USBHS_EP12_T_TYP (1 << 12) -#define USBHS_EP12_R_TYP (1 << 28) - -#define USBHS_EP13_T_TYP (1 << 13) -#define USBHS_EP13_R_TYP (1 << 29) - -#define USBHS_EP14_T_TYP (1 << 14) -#define USBHS_EP14_R_TYP (1 << 30) - -#define USBHS_EP15_T_TYP (1 << 15) -#define USBHS_EP15_R_TYP (1 << 31) - -/* BUF_MOD UEP1~15 */ -#define USBHS_BUF_MOD_OFFSET 0x18 -#define USBHS_EP0_BUF_MOD (1 << 0) -#define USBHS_EP0_ISO_BUF_MOD (1 << 16) - -#define USBHS_EP1_BUF_MOD (1 << 1) -#define USBHS_EP1_ISO_BUF_MOD (1 << 17) - -#define USBHS_EP2_BUF_MOD (1 << 2) -#define USBHS_EP2_ISO_BUF_MOD (1 << 18) - -#define USBHS_EP3_BUF_MOD (1 << 3) -#define USBHS_EP3_ISO_BUF_MOD (1 << 19) - -#define USBHS_EP4_BUF_MOD (1 << 4) -#define USBHS_EP4_ISO_BUF_MOD (1 << 20) - -#define USBHS_EP5_BUF_MOD (1 << 5) -#define USBHS_EP5_ISO_BUF_MOD (1 << 21) - -#define USBHS_EP6_BUF_MOD (1 << 6) -#define USBHS_EP6_ISO_BUF_MOD (1 << 22) - -#define USBHS_EP7_BUF_MOD (1 << 7) -#define USBHS_EP7_ISO_BUF_MOD (1 << 23) - -#define USBHS_EP8_BUF_MOD (1 << 8) -#define USBHS_EP8_ISO_BUF_MOD (1 << 24) - -#define USBHS_EP9_BUF_MOD (1 << 9) -#define USBHS_EP9_ISO_BUF_MOD (1 << 25) - -#define USBHS_EP10_BUF_MOD (1 << 10) -#define USBHS_EP10_ISO_BUF_MOD (1 << 26) - -#define USBHS_EP11_BUF_MOD (1 << 11) -#define USBHS_EP11_ISO_BUF_MOD (1 << 27) - -#define USBHS_EP12_BUF_MOD (1 << 12) -#define USBHS_EP12_ISO_BUF_MOD (1 << 28) - -#define USBHS_EP13_BUF_MOD (1 << 13) -#define USBHS_EP13_ISO_BUF_MOD (1 << 29) - -#define USBHS_EP14_BUF_MOD (1 << 14) -#define USBHS_EP14_ISO_BUF_MOD (1 << 30) - -#define USBHS_EP15_BUF_MOD (1 << 15) -#define USBHS_EP15_ISO_BUF_MOD (1 << 31) -//USBHS_EPn_T_EN USBHS_EPn_R_EN USBHS_EPn_BUF_MOD Description: Arrange from low to high with UEPn_DMA as the starting address -// 0 0 x The endpoint is disabled and the UEPn_*_DMA buffers are not used. -// 1 0 0 The first address of the receive (OUT) buffer is UEPn_RX_DMA -// 1 0 1 RB_UEPn_RX_TOG[0]=0, use buffer UEPn_RX_DMA RB_UEPn_RX_TOG[0]=1, use buffer UEPn_TX_DMA -// 0 1 0 The first address of the transmit (IN) buffer is UEPn_TX_DMA. -// 0 1 1 RB_UEPn_TX_TOG[0]=0, use buffer UEPn_TX_DMA RB_UEPn_TX_TOG[0]=1, use buffer UEPn_RX_DMA - -/* USB0_DMA */ -#define USBHS_UEP0_DMA_OFFSET(n) (0x1C) // endpoint 0 DMA buffer address - -/* USBX_RX_DMA */ -#define USBHS_UEPx_RX_DMA_OFFSET(n) (0x1C + 4 * (n)) // endpoint x DMA buffer address - -#define USBHS_UEPx_TX_DMA_OFFSET(n) (0x58 + 4 * (n)) // endpoint x DMA buffer address - -#define USBHS_UEPx_MAX_LEN_OFFSET(n) (0x98 + 4 * (n)) // endpoint x DMA buffer address - -#define USBHS_UEPx_T_LEN_OFFSET(n) (0xD8 + 4 * (n)) // endpoint x DMA buffer address -#define USBHS_UEPx_TX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 2) // endpoint x DMA buffer address -#define USBHS_UEPx_RX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 3) // endpoint x DMA buffer address - -// UEPn_T_LEN -#define USBHS_EP_T_LEN_MASK (0x7FF) - -//UEPn_TX_CTRL -#define USBHS_EP_T_RES_MASK (3 << 0) -#define USBHS_EP_T_RES_ACK (0 << 0) -#define USBHS_EP_T_RES_NYET (1 << 0) -#define USBHS_EP_T_RES_NAK (2 << 0) -#define USBHS_EP_T_RES_STALL (3 << 0) - -#define USBHS_EP_T_TOG_MASK (3 << 3) -#define USBHS_EP_T_TOG_0 (0 << 3) -#define USBHS_EP_T_TOG_1 (1 << 3) -#define USBHS_EP_T_TOG_2 (2 << 3) -#define USBHS_EP_T_TOG_M (3 << 3) - -#define USBHS_EP_T_AUTOTOG (1 << 5) - -//UEPn_RX_CTRL -#define USBHS_EP_R_RES_MASK (3 << 0) -#define USBHS_EP_R_RES_ACK (0 << 0) -#define USBHS_EP_R_RES_NYET (1 << 0) -#define USBHS_EP_R_RES_NAK (2 << 0) -#define USBHS_EP_R_RES_STALL (3 << 0) - -#define USBHS_EP_R_TOG_MASK (3 << 3) -#define USBHS_EP_R_TOG_0 (0 << 3) -#define USBHS_EP_R_TOG_1 (1 << 3) -#define USBHS_EP_R_TOG_2 (2 << 3) -#define USBHS_EP_R_TOG_M (3 << 3) - -#define USBHS_EP_R_AUTOTOG (1 << 5) - -#define USBHS_TOG_MATCH (1 << 6) - -/******************* HOST ******************/ -// USB HOST_CTRL -#define USBHS_SEND_BUS_RESET (1 << 0) -#define USBHS_SEND_BUS_SUSPEND (1 << 1) -#define USBHS_SEND_BUS_RESUME (1 << 2) -#define USBHS_REMOTE_WAKE (1 << 3) -#define USBHS_PHY_SUSPENDM (1 << 4) -#define USBHS_UH_SOFT_FREE (1 << 6) -#define USBHS_SEND_SOF_EN (1 << 7) - -//UH_CONFIG -#define USBHS_HOST_TX_EN (1 << 3) -#define USBHS_HOST_RX_EN (1 << 18) - -// HOST_EP_TYPE -#define USBHS_ENDP_TX_ISO (1 << 3) -#define USBHS_ENDP_RX_ISO (1 << (16 + 2)) - -// R32_UH_EP_PID -#define USBHS_HOST_MASK_TOKEN (0x0f) -#define USBHS_HOST_MASK_ENDP (0x0f << 4) - -//R8_UH_RX_CTRL -#define USBHS_EP_R_RES_MASK (3 << 0) -#define USBHS_EP_R_RES_ACK (0 << 0) -#define USBHS_EP_R_RES_NYET (1 << 0) -#define USBHS_EP_R_RES_NAK (2 << 0) -#define USBHS_EP_R_RES_STALL (3 << 0) - -#define USBHS_UH_R_RES_NO (1 << 2) -#define USBHS_UH_R_TOG_1 (1 << 3) -#define USBHS_UH_R_TOG_2 (2 << 3) -#define USBHS_UH_R_TOG_3 (3 << 3) -#define USBHS_UH_R_TOG_AUTO (1 << 5) -#define USBHS_UH_R_DATA_NO (1 << 6) -//R8_UH_TX_CTRL -#define USBHS_UH_T_RES_MASK (3 << 0) -#define USBHS_UH_T_RES_ACK (0 << 0) -#define USBHS_UH_T_RES_NYET (1 << 0) -#define USBHS_UH_T_RES_NAK (2 << 0) -#define USBHS_UH_T_RES_STALL (3 << 0) - -#define USBHS_UH_T_RES_NO (1 << 2) -#define USBHS_UH_T_TOG_1 (1 << 3) -#define USBHS_UH_T_TOG_2 (2 << 3) -#define USBHS_UH_T_TOG_3 (3 << 3) -#define USBHS_UH_T_TOG_AUTO (1 << 5) -#define USBHS_UH_T_DATA_NO (1 << 6) - -// 00: OUT, 01:SOF, 10:IN, 11:SETUP -#define PID_OUT 0 -#define PID_SOF 1 -#define PID_IN 2 -#define PID_SETUP 3 - -#endif diff --git a/src/portable/wch/ch32v307/usb_dc_usbhs.c b/src/portable/wch/ch32v307/usb_dc_usbhs.c deleted file mode 100644 index 39fd41392..000000000 --- a/src/portable/wch/ch32v307/usb_dc_usbhs.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2022 Greg Davill - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb_option.h" - -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V307) -#include "device/dcd.h" - -#include "usb_ch32_usbhs_reg.h" -#include "core_riscv.h" - -// Max number of bi-directional endpoints including EP0 -#define EP_MAX 16 - -typedef struct { - uint8_t *buffer; - // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API - uint16_t total_len; - uint16_t queued_len; - uint16_t max_size; - bool short_packet; -} xfer_ctl_t; - -#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] -static xfer_ctl_t xfer_status[EP_MAX][2]; - -#define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep)*2) -#define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep)*4) -#define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep)*4) -#define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep)*2) - -#define EP_TX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_TX_DMA) + (ep - 1)) -#define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) - -/* Endpoint Buffer */ -TU_ATTR_ALIGNED(4) uint8_t EP0_DatabufHD[64]; // ep0(64) - -volatile uint8_t USBHS_Dev_Endp0_Tog = 0x01; - -void dcd_init(uint8_t rhport) { - (void)rhport; - - memset(&xfer_status, 0, sizeof(xfer_status)); - - USBHSD->HOST_CTRL = 0x00; - USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; - - USBHSD->CONTROL = 0; - -#if TUD_OPT_HIGH_SPEED - USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; -#else - #error OPT_MODE_FULL_SPEED not currently supported on CH32V307 - USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; -#endif - - USBHSD->INT_EN = 0; - USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN; - - /* ALL endpoint enable */ - USBHSD->ENDP_CONFIG = 0xffffffff; - - USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; - USBHSD->ENDP_TYPE = 0x00; - USBHSD->BUF_MODE = 0x00; - - USBHSD->UEP0_MAX_LEN = 64; - - USBHSD->UEP0_DMA = (uint32_t)EP0_DatabufHD; - - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_NAK; - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; - - for (int ep = 1; ep < EP_MAX; ep++) { - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; - EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - - EP_RX_MAX_LEN(ep) = 512; - } - - USBHSD->DEV_AD = 0; - USBHSD->CONTROL |= USBHS_DEV_PU_EN; -} - -void dcd_int_enable(uint8_t rhport) { - (void)rhport; - - NVIC_EnableIRQ(USBHS_IRQn); -} - -void dcd_int_disable(uint8_t rhport) { - (void)rhport; - - NVIC_DisableIRQ(USBHS_IRQn); -} - -void dcd_edpt_close_all(uint8_t rhport) { - (void)rhport; -} - -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void)dev_addr; - - // Response with zlp status - dcd_edpt_xfer(rhport, 0x80, NULL, 0); -} - -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { - (void)rhport; - - if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS) { - USBHSD->DEV_AD = (uint8_t)request->wValue; - } - - EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK; -} - -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { - (void)rhport; - - uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - - TU_ASSERT(epnum < EP_MAX); - - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); - xfer->max_size = tu_edpt_packet_size(desc_edpt); - - if (epnum != 0) { - if (tu_edpt_dir(desc_edpt->bEndpointAddress) == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK; - } else { - EP_TX_LEN(epnum) = 0; - EP_TX_CTRL(epnum) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - } - } - - return true; -} - -int usbd_ep_close(const uint8_t ep) { - (void)ep; - - return 0; -} -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - if (epnum == 0) { - if (dir == TUSB_DIR_OUT) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_STALL; - } else { - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_STALL; - } - } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL; - - } else { - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL; - } - } -} - -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - if (epnum == 0) { - if (dir == TUSB_DIR_OUT) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; - } else { - } - } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~(USBHS_EP_R_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_ACK; - - } else { - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_NAK; - } - } -} - -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void)rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = buffer; - // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API - xfer->total_len = total_bytes; - xfer->queued_len = 0; - xfer->short_packet = false; - - // uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t short_packet_size = total_bytes % (xfer->max_size + 1); - - // Zero-size packet is special case. - if (short_packet_size == 0 || (total_bytes == 0)) { - xfer->short_packet = true; - } - - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - if (!total_bytes) { - xfer->short_packet = true; - if (epnum == 0) { - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); - USBHS_Dev_Endp0_Tog ^= 1; - } else { - EP_TX_LEN(epnum) = 0; - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; - } - } else { - if (epnum == 0) { - xfer->queued_len += short_packet_size; - memcpy(&EP0_DatabufHD[0], buffer, short_packet_size); - - USBHSD->UEP0_TX_LEN = short_packet_size; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); - USBHS_Dev_Endp0_Tog ^= 1; - } else { - xfer->queued_len += short_packet_size; - - EP_TX_DMA_ADDR(epnum) = (uint32_t)buffer; - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << epnum); - EP_TX_LEN(epnum) = short_packet_size; - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; - } - } - } else { /* TUSB_DIR_OUT */ - if (epnum == 0) { - uint32_t read_count = USBHSD->RX_LEN; - read_count = TU_MIN(read_count, total_bytes); - - if ((total_bytes == 8)) { - read_count = 8; - memcpy(buffer, &EP0_DatabufHD[0], 8); - } else { - memcpy(buffer, &EP0_DatabufHD[0], read_count); - } - } else { - EP_RX_DMA_ADDR(epnum) = (uint32_t)xfer->buffer; - USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << epnum); - } - - // usbd_ep_read(ep_addr, buffer, total_bytes, &ret_bytes); - } - return true; -} - - -static void receive_packet(xfer_ctl_t *xfer, uint16_t xfer_size) { - // xfer->queued_len = xfer->total_len - remaining; - - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t to_recv_size; - - if (remaining <= xfer->max_size) { - // Avoid buffer overflow. - to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; - } else { - // Room for full packet, choose recv_size based on what the microcontroller - // claims. - to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; - } - - if (to_recv_size) { - } - - xfer->queued_len += xfer_size; - - // Per USB spec, a short OUT packet (including length 0) is always - // indicative of the end of a transfer (at least for ctl, bulk, int). - xfer->short_packet = (xfer_size < xfer->max_size); -} - -void dcd_int_handler(uint8_t rhport) { - (void)rhport; - - uint32_t end_num, rx_token; - uint8_t intflag = 0; - - intflag = USBHSD->INT_FG; - - if (intflag & USBHS_TRANSFER_FLAG) { - - end_num = (USBHSD->INT_ST) & MASK_UIS_ENDP; - rx_token = (((USBHSD->INT_ST) & MASK_UIS_TOKEN) >> 4) & 0x03; - - uint8_t endp = end_num | (rx_token == PID_IN ? TUSB_DIR_IN_MASK : 0); - - xfer_ctl_t *xfer = XFER_CTL_BASE(end_num, tu_edpt_dir(endp)); - - if (rx_token == PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; - - receive_packet(xfer, rx_len); - - if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - - dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } - - if (end_num == 0) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; - } - - } else if (rx_token == PID_IN) { - if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - xfer->total_len = 0; - dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); - - EP_TX_CTRL(end_num) = (EP_TX_CTRL(end_num) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_NAK; - - if (end_num == 0) { - } - } else { - dcd_edpt_xfer(0, endp, xfer->buffer + xfer->queued_len, xfer->total_len - xfer->queued_len); - } - } - - USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ - } else if (intflag & USBHS_SETUP_FLAG) { - USBHS_Dev_Endp0_Tog = 1; - dcd_event_setup_received(0, EP0_DatabufHD, true); - - USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ - } else if (intflag & USBHS_DETECT_FLAG) { - USBHS_Dev_Endp0_Tog = 1; - - xfer_status[0][TUSB_DIR_OUT].max_size = 64; - xfer_status[0][TUSB_DIR_IN].max_size = 64; - - dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); - - USBHSD->DEV_AD = 0; - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; - - USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ - } else if (intflag & USBHS_SUSPEND_FLAG) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; - dcd_event_handler(&event, true); - - USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ - } -} - -#endif -- cgit v1.3.1 From 3cf21c66b6ef19c6dd648f952e8679a654b15803 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Jan 2023 15:26:48 +0700 Subject: add dcd_remote_wakeup() stub --- src/portable/wch/ch32v307/dcd_usbhs.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/portable/wch/ch32v307/dcd_usbhs.c b/src/portable/wch/ch32v307/dcd_usbhs.c index 7a0dcfc23..b7a79e166 100644 --- a/src/portable/wch/ch32v307/dcd_usbhs.c +++ b/src/portable/wch/ch32v307/dcd_usbhs.c @@ -130,6 +130,11 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { dcd_edpt_xfer(rhport, 0x80, NULL, 0); } +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; +} + void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void)rhport; -- cgit v1.3.1 From b1021d53f3617491656c50f6a1cb2c21da029f6a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Jan 2023 15:38:18 +0700 Subject: add TUP_RHPORT_HIGHSPEED for ch32v307 --- src/common/tusb_mcu.h | 2 +- src/tusb_option.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index b37ce9a34..0b10c5118 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -278,7 +278,7 @@ //------------- WCH -------------// #elif TU_CHECK_MCU(OPT_MCU_CH32V307) #define TUP_DCD_ENDPOINT_MAX 16 - + #define TUP_RHPORT_HIGHSPEED 1 #endif //--------------------------------------------------------------------+ diff --git a/src/tusb_option.h b/src/tusb_option.h index 92fbbd33f..67377b7ec 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -161,7 +161,7 @@ typedef int make_iso_compilers_happy; #define OPT_MCU_F1C100S 2100 ///< Allwinner F1C100s family // WCH -#define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 config +#define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 // Helper to check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input -- cgit v1.3.1 From 6dd40603f92a04d695b78a3ee6c0276525960aef Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 30 Jan 2023 11:46:52 +0700 Subject: fix typo --- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index f4c9b2b27..efca5bdcb 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -1023,7 +1023,7 @@ void dcd_int_handler(uint8_t rhport) USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL; } - // Host has sent a SETUP packet. Recieve this into the SETUP packet store. + // Host has sent a SETUP packet. Receive this into the SETUP packet store. _ft9xx_dusb_out(USBD_EP_0, (uint8_t *)_ft9xx_setup_packet, sizeof(USB_device_request)); // Send the packet to tinyusb. -- cgit v1.3.1