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 ++++ 1 file changed, 4 insertions(+) (limited to 'src/common') 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 //--------------------------------------------------------------------+ -- 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/common') 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 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/common') 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 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/common') 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 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/common') 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 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/common') 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/common') 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/common') 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 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/common') 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 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/common') 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 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/common') 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 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/common') 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 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/common') 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 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/common') 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/common') 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 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/common') 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 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/common') 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/common') 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/common') 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/common') 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/common') 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/common') 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/common') 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/common') 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/common') 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/common') 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 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/common') 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