diff --git a/hw/bsp/stm32u0/boards/stm32u083cdk/board.cmake b/hw/bsp/stm32u0/boards/stm32u083cdk/board.cmake index 945146810..e00e681d8 100644 --- a/hw/bsp/stm32u0/boards/stm32u083cdk/board.cmake +++ b/hw/bsp/stm32u0/boards/stm32u083cdk/board.cmake @@ -1,9 +1,6 @@ set(MCU_VARIANT stm32u083xx) set(JLINK_DEVICE stm32u083mc) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32U083MCTx_FLASH.ld) -set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/stm32u083xx_flash.icf) - function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32U083xx diff --git a/hw/bsp/stm32u0/boards/stm32u083cdk/board.h b/hw/bsp/stm32u0/boards/stm32u083cdk/board.h index 3030b1a1d..278d9b695 100644 --- a/hw/bsp/stm32u0/boards/stm32u083cdk/board.h +++ b/hw/bsp/stm32u0/boards/stm32u083cdk/board.h @@ -57,8 +57,7 @@ //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_stm32u0_clock_init(void) -{ +static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; @@ -78,10 +77,10 @@ static inline void board_stm32u0_clock_init(void) RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; - RCC_OscInitStruct.PLL.PLLN = 8; + RCC_OscInitStruct.PLL.PLLN = 7; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; - RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; - RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /** Initializes the CPU, AHB and APB buses clocks diff --git a/hw/bsp/stm32u0/boards/stm32u083cdk/board.mk b/hw/bsp/stm32u0/boards/stm32u083cdk/board.mk index 892854f54..09216440b 100644 --- a/hw/bsp/stm32u0/boards/stm32u083cdk/board.mk +++ b/hw/bsp/stm32u0/boards/stm32u083cdk/board.mk @@ -2,10 +2,6 @@ MCU_VARIANT = stm32u083xx CFLAGS += \ -DSTM32U083xx -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/STM32U083MCTx_FLASH.ld -LD_FILE_IAR = $(BOARD_PATH)/stm32u083xx_flash.icf - # For flash-jlink target JLINK_DEVICE = STM32U083MC diff --git a/hw/bsp/stm32u0/boards/stm32u083nucleo/board.cmake b/hw/bsp/stm32u0/boards/stm32u083nucleo/board.cmake new file mode 100644 index 000000000..8d1dafc15 --- /dev/null +++ b/hw/bsp/stm32u0/boards/stm32u083nucleo/board.cmake @@ -0,0 +1,9 @@ +set(MCU_VARIANT stm32u083xx) +set(JLINK_DEVICE stm32u083rc) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32U083xx + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/stm32u0/boards/stm32u083nucleo/board.h b/hw/bsp/stm32u0/boards/stm32u083nucleo/board.h new file mode 100644 index 000000000..23fddbef9 --- /dev/null +++ b/hw/bsp/stm32u0/boards/stm32u083nucleo/board.h @@ -0,0 +1,99 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* metadata: + name: NUCLEO-U083RC + url: https://www.st.com/en/evaluation-tools/nucleo-u083rc.html +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED: PA5 (LD4, Green) +#define LED_PORT GPIOA +#define LED_PIN GPIO_PIN_5 +#define LED_STATE_ON 1 + +// Button: PC13 (B1, Blue) +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 0 + +// UART: USART2 on PA2/PA3 (VCP via ST-Link) +#define UART_DEV USART2 +#define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF7_USART2 +#define UART_TX_PIN GPIO_PIN_2 +#define UART_RX_PIN GPIO_PIN_3 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; + RCC_OscInitStruct.PLL.PLLN = 7; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); +} + +static inline void board_vbus_sense_init(void) { +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32u0/boards/stm32u083nucleo/board.mk b/hw/bsp/stm32u0/boards/stm32u083nucleo/board.mk new file mode 100644 index 000000000..f5f3d41b3 --- /dev/null +++ b/hw/bsp/stm32u0/boards/stm32u083nucleo/board.mk @@ -0,0 +1,9 @@ +MCU_VARIANT = stm32u083xx +CFLAGS += \ + -DSTM32U083xx + +# For flash-jlink target +JLINK_DEVICE = STM32U083RC + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32u0/boards/stm32u083nucleo/cubemx/cubemx.ioc b/hw/bsp/stm32u0/boards/stm32u083nucleo/cubemx/cubemx.ioc new file mode 100644 index 000000000..5e40247b2 --- /dev/null +++ b/hw/bsp/stm32u0/boards/stm32u083nucleo/cubemx/cubemx.ioc @@ -0,0 +1,185 @@ +#MicroXplorer Configuration settings - do not modify +BSP_IP_NAME=NUCLEO-U083RC +CAD.formats=[] +CAD.pinconfig=Dual +CAD.provider= +File.Version=6 +GPIO.groupedBy= +KeepUserPlacement=false +Mcu.CPN=STM32U083RCT6 +Mcu.Family=STM32U0 +Mcu.IP0=CORTEX_M0+ +Mcu.IP1=NVIC +Mcu.IP2=PWR +Mcu.IP3=RCC +Mcu.IP4=SYS +Mcu.IP5=USART2 +Mcu.IP6=USB +Mcu.IP7=NUCLEO-U083RC +Mcu.IPNb=8 +Mcu.Name=STM32U083RCTx +Mcu.Package=LQFP64 +Mcu.Pin0=PC14-OSC32_IN +Mcu.Pin1=PC15-OSC32_OUT +Mcu.Pin10=VP_PWR_VS_SECSignals +Mcu.Pin11=VP_SYS_VS_Systick +Mcu.Pin2=PF0-OSC_IN +Mcu.Pin3=PF1-OSC_OUT +Mcu.Pin4=PA2 +Mcu.Pin5=PA3 +Mcu.Pin6=PA11 [PA9] +Mcu.Pin7=PA12 [PA10] +Mcu.Pin8=PA13 (SWDIO) +Mcu.Pin9=PA14 (SWCLK) +Mcu.PinsNb=12 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32U083RCTx +MxCube.Version=6.17.0 +MxDb.Version=DB.6.0.170 +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_2 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.SysTick_IRQn=true\:3\:0\:false\:false\:true\:false\:true\:false +PA11\ [PA9].Mode=Device +PA11\ [PA9].Signal=USB_DM +PA12\ [PA10].Mode=Device +PA12\ [PA10].Signal=USB_DP +PA13\ (SWDIO).GPIOParameters=GPIO_Label +PA13\ (SWDIO).GPIO_Label=SWDIO +PA13\ (SWDIO).Locked=true +PA13\ (SWDIO).Signal=DEBUG_JTMS-SWDIO +PA14\ (SWCLK).GPIOParameters=GPIO_Label +PA14\ (SWCLK).GPIO_Label=SWCLK +PA14\ (SWCLK).Locked=true +PA14\ (SWCLK).Signal=DEBUG_JTCK-SWCLK +PA2.GPIOParameters=GPIO_ModeDefaultPP,GPIO_Speed,GPIO_PuPd +PA2.GPIO_ModeDefaultPP=GPIO_MODE_AF_PP +PA2.GPIO_PuPd=GPIO_NOPULL +PA2.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PA2.Locked=true +PA2.Mode=Asynchronous +PA2.Signal=USART2_TX +PA3.GPIOParameters=GPIO_ModeDefaultPP,GPIO_Speed,GPIO_PuPd +PA3.GPIO_ModeDefaultPP=GPIO_MODE_AF_PP +PA3.GPIO_PuPd=GPIO_NOPULL +PA3.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PA3.Locked=true +PA3.Mode=Asynchronous +PA3.Signal=USART2_RX +PC14-OSC32_IN.GPIOParameters=GPIO_Label +PC14-OSC32_IN.GPIO_Label=OSC32_IN +PC14-OSC32_IN.Locked=true +PC14-OSC32_IN.Mode=LSE-External-Oscillator-for-RTC +PC14-OSC32_IN.Signal=RCC_OSC32_IN +PC15-OSC32_OUT.GPIOParameters=GPIO_Label +PC15-OSC32_OUT.GPIO_Label=OSC32_OUT +PC15-OSC32_OUT.Locked=true +PC15-OSC32_OUT.Mode=LSE-External-Oscillator-for-RTC +PC15-OSC32_OUT.Signal=RCC_OSC32_OUT +PCC.Checker=false +PCC.Display=Plot\: All Steps +PCC.Line=STM32U0x3 +PCC.MCU=STM32U083RCTx +PCC.PartNumber=STM32U083RCTx +PCC.Series=STM32U0 +PCC.Temperature=25 +PCC.Vdd=3.0 +PF0-OSC_IN.GPIOParameters=GPIO_Label +PF0-OSC_IN.GPIO_Label=OSC_IN +PF0-OSC_IN.Locked=true +PF0-OSC_IN.Signal=RCC_OSC_IN +PF1-OSC_OUT.GPIOParameters=GPIO_Label +PF1-OSC_OUT.GPIO_Label=OSC_OUT +PF1-OSC_OUT.Locked=true +PF1-OSC_OUT.Signal=RCC_OSC_OUT +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32U083RCTx +ProjectManager.FirmwarePackage=STM32Cube FW_U0 V1.3.0 +ProjectManager.FreePins=false +ProjectManager.FreePinsContext= +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=2 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=cubemx.ioc +ProjectManager.ProjectName=cubemx +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=CMake +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART2_UART_Init-USART2-false-HAL-true,4-MX_USB_PCD_Init-USB-false-HAL-true,0-MX_CORTEX_M0+_Init-CORTEX_M0+-false-HAL-true,0-MX_PWR_Init-PWR-false-HAL-true +RCC.ADCFreq_Value=56000000 +RCC.AHBFreq_Value=56000000 +RCC.APBFreq_Value=56000000 +RCC.APBTimFreq_Value=56000000 +RCC.CortexFreq_Value=56000000 +RCC.FCLKCortexFreq_Value=56000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=56000000 +RCC.HSE_VALUE=4000000 +RCC.HSI48_VALUE=48000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=56000000 +RCC.I2C3Freq_Value=56000000 +RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APBFreq_Value,APBTimFreq_Value,CortexFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM3Freq_Value,LPUART1Freq_Value,LPUART2Freq_Value,LPUART3Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,MCO2PinFreq_Value,MSIClockRangeVal,MSI_VALUE,PLLN,PLLPoutputFreq_Value,PLLQ,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PWRFreq_Value,RNGFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,TIM15Freq_Value,TIM1Freq_Value,USART1Freq_Value,USART2Freq_Value,USBCLockSelection,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value +RCC.LPTIM1Freq_Value=56000000 +RCC.LPTIM2Freq_Value=56000000 +RCC.LPTIM3Freq_Value=56000000 +RCC.LPUART1Freq_Value=56000000 +RCC.LPUART2Freq_Value=56000000 +RCC.LPUART3Freq_Value=56000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSI_VALUE=32000 +RCC.MCO1PinFreq_Value=56000000 +RCC.MCO2PinFreq_Value=56000000 +RCC.MSIClockRangeVal=RCC_MSIRANGE_11 +RCC.MSI_VALUE=48000000 +RCC.PLLN=7 +RCC.PLLPoutputFreq_Value=56000000 +RCC.PLLQ=RCC_PLLQ_DIV4 +RCC.PLLQoutputFreq_Value=28000000 +RCC.PLLRCLKFreq_Value=56000000 +RCC.PWRFreq_Value=56000000 +RCC.RNGFreq_Value=48000000 +RCC.SYSCLKFreq_VALUE=56000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.TIM15Freq_Value=56000000 +RCC.TIM1Freq_Value=56000000 +RCC.USART1Freq_Value=56000000 +RCC.USART2Freq_Value=56000000 +RCC.USBCLockSelection=RCC_USBCLKSOURCE_HSI48 +RCC.USBFreq_Value=48000000 +RCC.VCOInputFreq_Value=16000000 +RCC.VCOOutputFreq_Value=112000000 +USART2.IPParameters=VirtualMode-Asynchronous +USART2.VirtualMode-Asynchronous=VM_ASYNC +USB.IPParameters=VirtualMode +USB.VirtualMode=Device_Only +VP_PWR_VS_SECSignals.Mode=Security/Privilege +VP_PWR_VS_SECSignals.Signal=PWR_VS_SECSignals +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=NUCLEO-U083RC +boardIOC=true diff --git a/hw/bsp/stm32u0/family.c b/hw/bsp/stm32u0/family.c index 0f91d1f30..af39ae398 100644 --- a/hw/bsp/stm32u0/family.c +++ b/hw/bsp/stm32u0/family.c @@ -30,6 +30,9 @@ #include "stm32u0xx_hal.h" #include "bsp/board_api.h" + +TU_ATTR_UNUSED static void Error_Handler(void) { } + #include "board.h" //--------------------------------------------------------------------+ @@ -47,7 +50,7 @@ UART_HandleTypeDef UartHandle; #endif void board_init(void) { - board_stm32u0_clock_init(); + SystemClock_Config(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); diff --git a/hw/bsp/stm32u0/family.mk b/hw/bsp/stm32u0/family.mk index 5f25906d3..241323f62 100644 --- a/hw/bsp/stm32u0/family.mk +++ b/hw/bsp/stm32u0/family.mk @@ -48,4 +48,6 @@ SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_${MCU_VARIANT}.s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_${MCU_VARIANT}.s # Linker +MCU_VARIANT_UPPER = $(subst stm32u,STM32U,$(MCU_VARIANT)) +LD_FILE ?= $(FAMILY_PATH)/linker/$(MCU_VARIANT_UPPER)_FLASH.ld LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf diff --git a/hw/bsp/stm32u0/boards/stm32u083cdk/STM32U083MCTx_FLASH.ld b/hw/bsp/stm32u0/linker/STM32U083xx_FLASH.ld similarity index 98% rename from hw/bsp/stm32u0/boards/stm32u083cdk/STM32U083MCTx_FLASH.ld rename to hw/bsp/stm32u0/linker/STM32U083xx_FLASH.ld index c5ea72fb0..410d247a1 100644 --- a/hw/bsp/stm32u0/boards/stm32u083cdk/STM32U083MCTx_FLASH.ld +++ b/hw/bsp/stm32u0/linker/STM32U083xx_FLASH.ld @@ -2,7 +2,7 @@ ****************************************************************************** * @file LinkerScript.ld * @author Auto-generated by STM32CubeIDE - * @brief Linker script for STM32U083MCTx Device from STM32U0 series + * @brief Linker script for STM32U083xx Device from STM32U0 series * 256KBytes FLASH * 40KBytes RAM * diff --git a/hw/bsp/stm32u0/boards/stm32u083cdk/stm32u083xx_flash.icf b/hw/bsp/stm32u0/linker/stm32u083xx_flash.icf similarity index 100% rename from hw/bsp/stm32u0/boards/stm32u083cdk/stm32u083xx_flash.icf rename to hw/bsp/stm32u0/linker/stm32u083xx_flash.icf diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index edc7ecc3e..34dd6af8d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -241,9 +241,11 @@ #if defined(STM32F302xB) || defined(STM32F302xC) || defined(STM32F303xB) || defined(STM32F303xC) || \ defined(STM32F373xC) + // xB, and xC: 512 #define CFG_TUSB_FSDEV_PMA_SIZE 512u #elif defined(STM32F302x6) || defined(STM32F302x8) || defined(STM32F302xD) || defined(STM32F302xE) || \ defined(STM32F303xD) || defined(STM32F303xE) + // x6, x8, xD, and xE: 1024 + LPM Support #define CFG_TUSB_FSDEV_PMA_SIZE 1024u #else #error "Unsupported STM32F3 mcu" diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index a6abc6244..13d1a6cb4 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -59,7 +59,6 @@ * - Enable USB clock; Perhaps use __HAL_RCC_USB_CLK_ENABLE(); * - (Optionally configure GPIO HAL to tell it the USB driver is using the USB pins) * - call tusb_init(); - * - periodically call tusb_task(); * * Assumptions of the driver: * - You are not using CAN (it must share the packet buffer) @@ -87,19 +86,6 @@ * below functions could be adjusting the wrong interrupts (if they had been reconfigured) * - LPM is not used correctly, or at all? * - * USB documentation and Reference implementations - * - STM32 Reference manuals - * - STM32 USB Hardware Guidelines AN4879 - * - * - STM32 HAL (much of this driver is based on this) - * - libopencm3/lib/stm32/common/st_usbfs_core.c - * - Keil USB Device http://www.keil.com/pack/doc/mw/USB/html/group__usbd.html - * - * - YouTube OpenTechLab 011; https://www.youtube.com/watch?v=4FOkJLp_PUw - * - * Advantages over HAL driver: - * - Tiny (saves RAM, assumes a single USB peripheral) - * * Notes: * - The buffer table is allocated as endpoints are opened. The allocation is only * cleared when the device is reset. This may be bad if the USB device needs @@ -177,14 +163,14 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { FSDEV_REG->CNTR = 0; // Enable USB - #if !defined(FSDEV_BUS_32BIT) + #if !defined( CFG_TUSB_FSDEV_32BIT) // BTABLE register does not exist any more on 32-bit bus devices FSDEV_REG->BTABLE = FSDEV_BTABLE_BASE; #endif // Enable interrupts for device mode FSDEV_REG->CNTR |= - USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_PMAOVRM; + U_CNTR_RESETM | U_CNTR_ESOFM | U_CNTR_CTRM | U_CNTR_SUSPM | U_CNTR_WKUPM | U_CNTR_PMAOVRM; handle_bus_reset(rhport); @@ -206,9 +192,9 @@ void dcd_sof_enable(uint8_t rhport, bool en) { (void)rhport; if (en) { - FSDEV_REG->CNTR |= USB_CNTR_SOFM; + FSDEV_REG->CNTR |= U_CNTR_SOFM; } else { - FSDEV_REG->CNTR &= ~USB_CNTR_SOFM; + FSDEV_REG->CNTR &= ~U_CNTR_SOFM; } } @@ -226,7 +212,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; - FSDEV_REG->CNTR |= USB_CNTR_RESUME; + FSDEV_REG->CNTR |= U_CNTR_RESUME; remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } @@ -246,14 +232,14 @@ static void handle_bus_reset(uint8_t rhport) { edpt0_open(rhport); // open control endpoint (both IN & OUT) - FSDEV_REG->DADDR = USB_DADDR_EF; // Enable USB Function + FSDEV_REG->DADDR = U_DADDR_EF; // Enable USB Function } // Handle CTR interrupt for the TX/IN direction static void handle_ctr_tx(uint32_t ep_id) { - uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; + uint32_t ep_reg = ep_read(ep_id) | U_EP_CTR_TX | U_EP_CTR_RX; - const uint8_t ep_num = ep_reg & USB_EPADDR_FIELD; + const uint8_t ep_num = ep_reg & U_EPADDR_FIELD; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN); if (ep_is_iso(ep_reg)) { @@ -265,7 +251,7 @@ static void handle_ctr_tx(uint32_t ep_id) { } xfer->iso_in_sending = false; #if FSDEV_USE_SBUF_ISO == 0 - uint8_t buf_id = (ep_reg & USB_EP_DTOG_TX) ? 0 : 1; + uint8_t buf_id = (ep_reg & U_EP_DTOG_TX) ? 0 : 1; #else uint8_t buf_id = BTABLE_BUF_TX; #endif @@ -302,8 +288,8 @@ static void handle_ctr_setup(uint32_t ep_id) { // Handle CTR interrupt for the RX/OUT direction static void handle_ctr_rx(uint32_t ep_id) { - uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; - const uint8_t ep_num = ep_reg & USB_EPADDR_FIELD; + uint32_t ep_reg = ep_read(ep_id) | U_EP_CTR_TX | U_EP_CTR_RX; + const uint8_t ep_num = ep_reg & U_EPADDR_FIELD; const bool is_iso = ep_is_iso(ep_reg); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); @@ -314,7 +300,7 @@ static void handle_ctr_rx(uint32_t ep_id) { bool const dbl_buf = false; #endif if (dbl_buf) { - buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; + buf_id = (ep_reg & U_EP_DTOG_RX) ? 0 : 1; } else { buf_id = BTABLE_BUF_RX; } @@ -346,7 +332,7 @@ static void handle_ctr_rx(uint32_t ep_id) { const uint16_t cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits + ep_reg &= U_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); ep_write(ep_id, ep_reg, false); } @@ -356,58 +342,58 @@ void dcd_int_handler(uint8_t rhport) { uint32_t int_status = FSDEV_REG->ISTR; /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ - if (int_status & USB_ISTR_SOF) { - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; - dcd_event_sof(0, FSDEV_REG->FNR & USB_FNR_FN, true); + if (int_status & U_ISTR_SOF) { + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_SOF; + dcd_event_sof(0, FSDEV_REG->FNR & U_FNR_FN, true); } - if (int_status & USB_ISTR_RESET) { + if (int_status & U_ISTR_RESET) { // USBRST is start of reset. - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_RESET; handle_bus_reset(rhport); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); return; // Don't do the rest of the things here; perhaps they've been cleared? } - if (int_status & USB_ISTR_WKUP) { - FSDEV_REG->CNTR &= ~USB_CNTR_LPMODE; - FSDEV_REG->CNTR &= ~USB_CNTR_FSUSP; + if (int_status & U_ISTR_WKUP) { + FSDEV_REG->CNTR &= ~U_CNTR_LPMODE; + FSDEV_REG->CNTR &= ~U_CNTR_FSUSP; - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_WKUP; + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_WKUP; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } - if (int_status & USB_ISTR_SUSP) { + if (int_status & U_ISTR_SUSP) { /* Suspend is asserted for both suspend and unplug events. without Vbus monitoring, * these events cannot be differentiated, so we only trigger suspend. */ /* Force low-power mode in the macrocell */ - FSDEV_REG->CNTR |= USB_CNTR_FSUSP; - FSDEV_REG->CNTR |= USB_CNTR_LPMODE; + FSDEV_REG->CNTR |= U_CNTR_FSUSP; + FSDEV_REG->CNTR |= U_CNTR_LPMODE; /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SUSP; + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_SUSP; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } - if (int_status & USB_ISTR_ESOF) { + if (int_status & U_ISTR_ESOF) { if (remoteWakeCountdown == 1u) { - FSDEV_REG->CNTR &= ~USB_CNTR_RESUME; + FSDEV_REG->CNTR &= ~U_CNTR_RESUME; } if (remoteWakeCountdown > 0u) { remoteWakeCountdown--; } - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_ESOF; } // loop to handle all pending CTR interrupts - while (FSDEV_REG->ISTR & USB_ISTR_CTR) { + while (FSDEV_REG->ISTR & U_ISTR_CTR) { // skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt - const uint32_t ep_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID; + const uint32_t ep_id = FSDEV_REG->ISTR & U_ISTR_EP_ID; const uint32_t ep_reg = ep_read(ep_id); - if (ep_reg & USB_EP_CTR_RX) { - #ifdef FSDEV_BUS_32BIT + if (ep_reg & U_EP_CTR_RX) { + #ifdef CFG_TUSB_FSDEV_32BIT /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf * https://www.st.com/resource/en/errata_sheet/es0587-stm32u535xx-and-stm32u545xx-device-errata-stmicroelectronics.pdf * From H503/U535 errata: Buffer description table update completes after CTR interrupt triggers @@ -429,7 +415,7 @@ void dcd_int_handler(uint8_t rhport) { } #endif - if (ep_reg & USB_EP_SETUP) { + if (ep_reg & U_EP_SETUP) { handle_ctr_setup(ep_id); // CTR will be clear after copied setup packet } else { ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); @@ -437,15 +423,15 @@ void dcd_int_handler(uint8_t rhport) { } } - if (ep_reg & USB_EP_CTR_TX) { + if (ep_reg & U_EP_CTR_TX) { ep_write_clear_ctr(ep_id, TUSB_DIR_IN); handle_ctr_tx(ep_id); } } - if (int_status & USB_ISTR_PMAOVR) { + if (int_status & U_ISTR_PMAOVR) { TU_BREAKPOINT(); - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR; + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_PMAOVR; } } @@ -461,7 +447,7 @@ void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t *req if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { const uint8_t dev_addr = (uint8_t)request->wValue; - FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr); + FSDEV_REG->DADDR = (U_DADDR_EF | dev_addr); } edpt0_prepare_setup(); @@ -551,8 +537,8 @@ void edpt0_open(uint8_t rhport) { btable_set_addr(0, BTABLE_BUF_RX, pma_addr0); btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); - uint32_t ep_reg = ep_read(0) & ~USB_EPREG_MASK; // only get toggle bits - ep_reg |= USB_EP_CONTROL; + uint32_t ep_reg = ep_read(0) & ~U_EPREG_MASK; // only get toggle bits + ep_reg |= U_EP_CONTROL; ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit @@ -570,16 +556,16 @@ bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { const uint8_t ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); TU_ASSERT(ep_idx < FSDEV_EP_COUNT); - uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; - ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_TX | USB_EP_CTR_RX; + uint32_t ep_reg = ep_read(ep_idx) & ~U_EPREG_MASK; + ep_reg |= tu_edpt_number(ep_addr) | U_EP_CTR_TX | U_EP_CTR_RX; // Set type switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_BULK: - ep_reg |= USB_EP_BULK; + ep_reg |= U_EP_BULK; break; case TUSB_XFER_INTERRUPT: - ep_reg |= USB_EP_INTERRUPT; + ep_reg |= U_EP_INTERRUPT; break; default: @@ -600,9 +586,9 @@ bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { // reserve other direction toggle bits if (dir == TUSB_DIR_IN) { - ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX); + ep_reg &= ~(U_EPRX_STAT | U_EP_DTOG_RX); } else { - ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); + ep_reg &= ~(U_EPTX_STAT | U_EP_DTOG_TX); } ep_write(ep_idx, ep_reg, true); @@ -669,18 +655,18 @@ bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) xfer->max_packet_size = tu_edpt_packet_size(desc_ep); - uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; - ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX; + uint32_t ep_reg = ep_read(ep_idx) & ~U_EPREG_MASK; + ep_reg |= tu_edpt_number(ep_addr) | U_EP_ISOCHRONOUS | U_EP_CTR_TX | U_EP_CTR_RX; #if FSDEV_USE_SBUF_ISO != 0 - ep_reg |= USB_EP_KIND; + ep_reg |= U_EP_KIND; ep_change_status(&ep_reg, dir, EP_STAT_DISABLED); ep_change_dtog(&ep_reg, dir, 0); if (dir == TUSB_DIR_IN) { - ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX); + ep_reg &= ~(U_EPRX_STAT | U_EP_DTOG_RX); } else { - ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); + ep_reg &= ~(U_EPTX_STAT | U_EP_DTOG_TX); } #else ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); @@ -697,7 +683,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR + uint32_t ep_reg = ep_read(ep_ix) | U_EP_CTR_TX | U_EP_CTR_RX; // reserve CTR const bool is_iso = ep_is_iso(ep_reg); @@ -708,7 +694,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { bool const dbl_buf = false; #endif if (dbl_buf) { - buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0; + buf_id = (ep_reg & U_EP_DTOG_TX) ? 1 : 0; } else { buf_id = BTABLE_BUF_TX; } @@ -728,7 +714,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { if (is_iso) { xfer->iso_in_sending = true; } - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits + ep_reg &= U_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits ep_write(ep_ix, ep_reg, true); } @@ -741,8 +727,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) { if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); + uint32_t ep_reg = ep_read(ep_idx) | U_EP_CTR_TX | U_EP_CTR_RX; // reserve CTR + ep_reg &= U_EPREG_MASK | EP_STAT_MASK(dir); uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); @@ -800,8 +786,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); const uint8_t ep_idx = xfer->ep_idx; - uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); + uint32_t ep_reg = ep_read(ep_idx) | U_EP_CTR_TX | U_EP_CTR_RX; // reserve CTR bits + ep_reg &= U_EPREG_MASK | EP_STAT_MASK(dir); ep_change_status(&ep_reg, dir, EP_STAT_STALL); ep_write(ep_idx, ep_reg, true); @@ -815,8 +801,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); const uint8_t ep_idx = xfer->ep_idx; - uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); + uint32_t ep_reg = ep_read(ep_idx) | U_EP_CTR_TX | U_EP_CTR_RX; // reserve CTR bits + ep_reg &= U_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { ep_change_status(&ep_reg, dir, EP_STAT_NAK); diff --git a/src/portable/st/stm32_fsdev/fsdev_at32.h b/src/portable/st/stm32_fsdev/fsdev_at32.h index e75430396..107884370 100644 --- a/src/portable/st/stm32_fsdev/fsdev_at32.h +++ b/src/portable/st/stm32_fsdev/fsdev_at32.h @@ -43,112 +43,6 @@ #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0 #endif -/**************************** ISTR interrupt events *************************/ -#define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */ -#define USB_ISTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun (clear-only bit) */ -#define USB_ISTR_ERR ((uint16_t)0x2000U) /*!< ERRor (clear-only bit) */ -#define USB_ISTR_WKUP ((uint16_t)0x1000U) /*!< WaKe UP (clear-only bit) */ -#define USB_ISTR_SUSP ((uint16_t)0x0800U) /*!< SUSPend (clear-only bit) */ -#define USB_ISTR_RESET ((uint16_t)0x0400U) /*!< RESET (clear-only bit) */ -#define USB_ISTR_SOF ((uint16_t)0x0200U) /*!< Start Of Frame (clear-only bit) */ -#define USB_ISTR_ESOF ((uint16_t)0x0100U) /*!< Expected Start Of Frame (clear-only bit) */ -#define USB_ISTR_DIR ((uint16_t)0x0010U) /*!< DIRection of transaction (read-only bit) */ -#define USB_ISTR_EP_ID ((uint16_t)0x000FU) /*!< EndPoint IDentifier (read-only bit) */ - -/* Legacy defines */ -#define USB_ISTR_PMAOVRM USB_ISTR_PMAOVR - -#define USB_CLR_CTR (~USB_ISTR_CTR) /*!< clear Correct TRansfer bit */ -#define USB_CLR_PMAOVR (~USB_ISTR_PMAOVR) /*!< clear DMA OVeR/underrun bit*/ -#define USB_CLR_ERR (~USB_ISTR_ERR) /*!< clear ERRor bit */ -#define USB_CLR_WKUP (~USB_ISTR_WKUP) /*!< clear WaKe UP bit */ -#define USB_CLR_SUSP (~USB_ISTR_SUSP) /*!< clear SUSPend bit */ -#define USB_CLR_RESET (~USB_ISTR_RESET) /*!< clear RESET bit */ -#define USB_CLR_SOF (~USB_ISTR_SOF) /*!< clear Start Of Frame bit */ -#define USB_CLR_ESOF (~USB_ISTR_ESOF) /*!< clear Expected Start Of Frame bit */ - -/* Legacy defines */ -#define USB_CLR_PMAOVRM USB_CLR_PMAOVR - -/************************* CNTR control register bits definitions ***********/ -#define USB_CNTR_CTRM ((uint16_t)0x8000U) /*!< Correct TRansfer Mask */ -#define USB_CNTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun Mask */ -#define USB_CNTR_ERRM ((uint16_t)0x2000U) /*!< ERRor Mask */ -#define USB_CNTR_WKUPM ((uint16_t)0x1000U) /*!< WaKe UP Mask */ -#define USB_CNTR_SUSPM ((uint16_t)0x0800U) /*!< SUSPend Mask */ -#define USB_CNTR_RESETM ((uint16_t)0x0400U) /*!< RESET Mask */ -#define USB_CNTR_SOFM ((uint16_t)0x0200U) /*!< Start Of Frame Mask */ -#define USB_CNTR_ESOFM ((uint16_t)0x0100U) /*!< Expected Start Of Frame Mask */ -#define USB_CNTR_RESUME ((uint16_t)0x0010U) /*!< RESUME request */ -#define USB_CNTR_FSUSP ((uint16_t)0x0008U) /*!< Force SUSPend */ -#define USB_CNTR_LPMODE ((uint16_t)0x0004U) /*!< Low-power MODE */ -#define USB_CNTR_PDWN ((uint16_t)0x0002U) /*!< Power DoWN */ -#define USB_CNTR_FRES ((uint16_t)0x0001U) /*!< Force USB RESet */ - -/* Legacy defines */ -#define USB_CNTR_PMAOVRM USB_CNTR_PMAOVR -#define USB_CNTR_LP_MODE USB_CNTR_LPMODE - -/******************** FNR Frame Number Register bit definitions ************/ -#define USB_FNR_RXDP ((uint16_t)0x8000U) /*!< status of D+ data line */ -#define USB_FNR_RXDM ((uint16_t)0x4000U) /*!< status of D- data line */ -#define USB_FNR_LCK ((uint16_t)0x2000U) /*!< LoCKed */ -#define USB_FNR_LSOF ((uint16_t)0x1800U) /*!< Lost SOF */ -#define USB_FNR_FN ((uint16_t)0x07FFU) /*!< Frame Number */ - -/******************** DADDR Device ADDRess bit definitions ****************/ -#define USB_DADDR_EF ((uint8_t)0x80U) /*!< USB device address Enable Function */ -#define USB_DADDR_ADD ((uint8_t)0x7FU) /*!< USB device address */ - -/****************************** Endpoint register *************************/ -#define USB_EP0R USB_BASE /*!< endpoint 0 register address */ -#define USB_EP1R (USB_BASE + 0x04U) /*!< endpoint 1 register address */ -#define USB_EP2R (USB_BASE + 0x08U) /*!< endpoint 2 register address */ -#define USB_EP3R (USB_BASE + 0x0CU) /*!< endpoint 3 register address */ -#define USB_EP4R (USB_BASE + 0x10U) /*!< endpoint 4 register address */ -#define USB_EP5R (USB_BASE + 0x14U) /*!< endpoint 5 register address */ -#define USB_EP6R (USB_BASE + 0x18U) /*!< endpoint 6 register address */ -#define USB_EP7R (USB_BASE + 0x1CU) /*!< endpoint 7 register address */ -/* bit positions */ -#define USB_EP_CTR_RX ((uint16_t)0x8000U) /*!< EndPoint Correct TRansfer RX */ -#define USB_EP_DTOG_RX ((uint16_t)0x4000U) /*!< EndPoint Data TOGGLE RX */ -#define USB_EPRX_STAT ((uint16_t)0x3000U) /*!< EndPoint RX STATus bit field */ -#define USB_EP_SETUP ((uint16_t)0x0800U) /*!< EndPoint SETUP */ -#define USB_EP_T_FIELD ((uint16_t)0x0600U) /*!< EndPoint TYPE */ -#define USB_EP_KIND ((uint16_t)0x0100U) /*!< EndPoint KIND */ -#define USB_EP_CTR_TX ((uint16_t)0x0080U) /*!< EndPoint Correct TRansfer TX */ -#define USB_EP_DTOG_TX ((uint16_t)0x0040U) /*!< EndPoint Data TOGGLE TX */ -#define USB_EPTX_STAT ((uint16_t)0x0030U) /*!< EndPoint TX STATus bit field */ -#define USB_EPADDR_FIELD ((uint16_t)0x000FU) /*!< EndPoint ADDRess FIELD */ - -/* EndPoint REGister MASK (no toggle fields) */ -#define USB_EPREG_MASK (USB_EP_CTR_RX|USB_EP_SETUP|USB_EP_T_FIELD|USB_EP_KIND|USB_EP_CTR_TX|USB_EPADDR_FIELD) - /*!< EP_TYPE[1:0] EndPoint TYPE */ -#define USB_EP_TYPE_MASK ((uint16_t)0x0600U) /*!< EndPoint TYPE Mask */ -#define USB_EP_BULK ((uint16_t)0x0000U) /*!< EndPoint BULK */ -#define USB_EP_CONTROL ((uint16_t)0x0200U) /*!< EndPoint CONTROL */ -#define USB_EP_ISOCHRONOUS ((uint16_t)0x0400U) /*!< EndPoint ISOCHRONOUS */ -#define USB_EP_INTERRUPT ((uint16_t)0x0600U) /*!< EndPoint INTERRUPT */ -#define USB_EP_T_MASK ((uint16_t) ~USB_EP_T_FIELD & USB_EPREG_MASK) - -#define USB_EPKIND_MASK ((uint16_t) ~USB_EP_KIND & USB_EPREG_MASK) /*!< EP_KIND EndPoint KIND */ - /*!< STAT_TX[1:0] STATus for TX transfer */ -#define USB_EP_TX_DIS ((uint16_t)0x0000U) /*!< EndPoint TX DISabled */ -#define USB_EP_TX_STALL ((uint16_t)0x0010U) /*!< EndPoint TX STALLed */ -#define USB_EP_TX_NAK ((uint16_t)0x0020U) /*!< EndPoint TX NAKed */ -#define USB_EP_TX_VALID ((uint16_t)0x0030U) /*!< EndPoint TX VALID */ -#define USB_EPTX_DTOG1 ((uint16_t)0x0010U) /*!< EndPoint TX Data TOGgle bit1 */ -#define USB_EPTX_DTOG2 ((uint16_t)0x0020U) /*!< EndPoint TX Data TOGgle bit2 */ -#define USB_EPTX_DTOGMASK (USB_EPTX_STAT|USB_EPREG_MASK) - /*!< STAT_RX[1:0] STATus for RX transfer */ -#define USB_EP_RX_DIS ((uint16_t)0x0000U) /*!< EndPoint RX DISabled */ -#define USB_EP_RX_STALL ((uint16_t)0x1000U) /*!< EndPoint RX STALLed */ -#define USB_EP_RX_NAK ((uint16_t)0x2000U) /*!< EndPoint RX NAKed */ -#define USB_EP_RX_VALID ((uint16_t)0x3000U) /*!< EndPoint RX VALID */ -#define USB_EPRX_DTOG1 ((uint16_t)0x1000U) /*!< EndPoint RX Data TOGgle bit1 */ -#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */ -#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK) - //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ @@ -206,7 +100,7 @@ TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) { TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) { (void) rhport; /* disable usb phy */ - *(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) |= USB_CNTR_PDWN; + *(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) |= U_CNTR_PDWN; /* D+ 1.5k pull-up disable, USB->cfg_bit.puo = TRUE; */ *(volatile uint32_t *)(FSDEV_REG_BASE+0x60) |= (1u<<1); } @@ -214,7 +108,7 @@ TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) { TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) { (void) rhport; /* enable usb phy */ - *(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) &= ~USB_CNTR_PDWN; + *(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) &= ~U_CNTR_PDWN; /* Dp 1.5k pull-up enable, USB->cfg_bit.puo = 0; */ *(volatile uint32_t *)(FSDEV_REG_BASE+0x60) &= ~(1u<<1); } diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 37ea7808e..b92bf3f58 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -61,112 +61,6 @@ #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0 #endif -/**************************** ISTR interrupt events *************************/ -#define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */ -#define USB_ISTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun (clear-only bit) */ -#define USB_ISTR_ERR ((uint16_t)0x2000U) /*!< ERRor (clear-only bit) */ -#define USB_ISTR_WKUP ((uint16_t)0x1000U) /*!< WaKe UP (clear-only bit) */ -#define USB_ISTR_SUSP ((uint16_t)0x0800U) /*!< SUSPend (clear-only bit) */ -#define USB_ISTR_RESET ((uint16_t)0x0400U) /*!< RESET (clear-only bit) */ -#define USB_ISTR_SOF ((uint16_t)0x0200U) /*!< Start Of Frame (clear-only bit) */ -#define USB_ISTR_ESOF ((uint16_t)0x0100U) /*!< Expected Start Of Frame (clear-only bit) */ -#define USB_ISTR_DIR ((uint16_t)0x0010U) /*!< DIRection of transaction (read-only bit) */ -#define USB_ISTR_EP_ID ((uint16_t)0x000FU) /*!< EndPoint IDentifier (read-only bit) */ - -/* Legacy defines */ -#define USB_ISTR_PMAOVRM USB_ISTR_PMAOVR - -#define USB_CLR_CTR (~USB_ISTR_CTR) /*!< clear Correct TRansfer bit */ -#define USB_CLR_PMAOVR (~USB_ISTR_PMAOVR) /*!< clear DMA OVeR/underrun bit*/ -#define USB_CLR_ERR (~USB_ISTR_ERR) /*!< clear ERRor bit */ -#define USB_CLR_WKUP (~USB_ISTR_WKUP) /*!< clear WaKe UP bit */ -#define USB_CLR_SUSP (~USB_ISTR_SUSP) /*!< clear SUSPend bit */ -#define USB_CLR_RESET (~USB_ISTR_RESET) /*!< clear RESET bit */ -#define USB_CLR_SOF (~USB_ISTR_SOF) /*!< clear Start Of Frame bit */ -#define USB_CLR_ESOF (~USB_ISTR_ESOF) /*!< clear Expected Start Of Frame bit */ - -/* Legacy defines */ -#define USB_CLR_PMAOVRM USB_CLR_PMAOVR - -/************************* CNTR control register bits definitions ***********/ -#define USB_CNTR_CTRM ((uint16_t)0x8000U) /*!< Correct TRansfer Mask */ -#define USB_CNTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun Mask */ -#define USB_CNTR_ERRM ((uint16_t)0x2000U) /*!< ERRor Mask */ -#define USB_CNTR_WKUPM ((uint16_t)0x1000U) /*!< WaKe UP Mask */ -#define USB_CNTR_SUSPM ((uint16_t)0x0800U) /*!< SUSPend Mask */ -#define USB_CNTR_RESETM ((uint16_t)0x0400U) /*!< RESET Mask */ -#define USB_CNTR_SOFM ((uint16_t)0x0200U) /*!< Start Of Frame Mask */ -#define USB_CNTR_ESOFM ((uint16_t)0x0100U) /*!< Expected Start Of Frame Mask */ -#define USB_CNTR_RESUME ((uint16_t)0x0010U) /*!< RESUME request */ -#define USB_CNTR_FSUSP ((uint16_t)0x0008U) /*!< Force SUSPend */ -#define USB_CNTR_LPMODE ((uint16_t)0x0004U) /*!< Low-power MODE */ -#define USB_CNTR_PDWN ((uint16_t)0x0002U) /*!< Power DoWN */ -#define USB_CNTR_FRES ((uint16_t)0x0001U) /*!< Force USB RESet */ - -/* Legacy defines */ -#define USB_CNTR_PMAOVRM USB_CNTR_PMAOVR -#define USB_CNTR_LP_MODE USB_CNTR_LPMODE - -/******************** FNR Frame Number Register bit definitions ************/ -#define USB_FNR_RXDP ((uint16_t)0x8000U) /*!< status of D+ data line */ -#define USB_FNR_RXDM ((uint16_t)0x4000U) /*!< status of D- data line */ -#define USB_FNR_LCK ((uint16_t)0x2000U) /*!< LoCKed */ -#define USB_FNR_LSOF ((uint16_t)0x1800U) /*!< Lost SOF */ -#define USB_FNR_FN ((uint16_t)0x07FFU) /*!< Frame Number */ - -/******************** DADDR Device ADDRess bit definitions ****************/ -#define USB_DADDR_EF ((uint8_t)0x80U) /*!< USB device address Enable Function */ -#define USB_DADDR_ADD ((uint8_t)0x7FU) /*!< USB device address */ - -/****************************** Endpoint register *************************/ -#define USB_EP0R USB_BASE /*!< endpoint 0 register address */ -#define USB_EP1R (USB_BASE + 0x04U) /*!< endpoint 1 register address */ -#define USB_EP2R (USB_BASE + 0x08U) /*!< endpoint 2 register address */ -#define USB_EP3R (USB_BASE + 0x0CU) /*!< endpoint 3 register address */ -#define USB_EP4R (USB_BASE + 0x10U) /*!< endpoint 4 register address */ -#define USB_EP5R (USB_BASE + 0x14U) /*!< endpoint 5 register address */ -#define USB_EP6R (USB_BASE + 0x18U) /*!< endpoint 6 register address */ -#define USB_EP7R (USB_BASE + 0x1CU) /*!< endpoint 7 register address */ -/* bit positions */ -#define USB_EP_CTR_RX ((uint16_t)0x8000U) /*!< EndPoint Correct TRansfer RX */ -#define USB_EP_DTOG_RX ((uint16_t)0x4000U) /*!< EndPoint Data TOGGLE RX */ -#define USB_EPRX_STAT ((uint16_t)0x3000U) /*!< EndPoint RX STATus bit field */ -#define USB_EP_SETUP ((uint16_t)0x0800U) /*!< EndPoint SETUP */ -#define USB_EP_T_FIELD ((uint16_t)0x0600U) /*!< EndPoint TYPE */ -#define USB_EP_KIND ((uint16_t)0x0100U) /*!< EndPoint KIND */ -#define USB_EP_CTR_TX ((uint16_t)0x0080U) /*!< EndPoint Correct TRansfer TX */ -#define USB_EP_DTOG_TX ((uint16_t)0x0040U) /*!< EndPoint Data TOGGLE TX */ -#define USB_EPTX_STAT ((uint16_t)0x0030U) /*!< EndPoint TX STATus bit field */ -#define USB_EPADDR_FIELD ((uint16_t)0x000FU) /*!< EndPoint ADDRess FIELD */ - -/* EndPoint REGister MASK (no toggle fields) */ -#define USB_EPREG_MASK (USB_EP_CTR_RX|USB_EP_SETUP|USB_EP_T_FIELD|USB_EP_KIND|USB_EP_CTR_TX|USB_EPADDR_FIELD) - /*!< EP_TYPE[1:0] EndPoint TYPE */ -#define USB_EP_TYPE_MASK ((uint16_t)0x0600U) /*!< EndPoint TYPE Mask */ -#define USB_EP_BULK ((uint16_t)0x0000U) /*!< EndPoint BULK */ -#define USB_EP_CONTROL ((uint16_t)0x0200U) /*!< EndPoint CONTROL */ -#define USB_EP_ISOCHRONOUS ((uint16_t)0x0400U) /*!< EndPoint ISOCHRONOUS */ -#define USB_EP_INTERRUPT ((uint16_t)0x0600U) /*!< EndPoint INTERRUPT */ -#define USB_EP_T_MASK ((uint16_t) ~USB_EP_T_FIELD & USB_EPREG_MASK) - -#define USB_EPKIND_MASK ((uint16_t) ~USB_EP_KIND & USB_EPREG_MASK) /*!< EP_KIND EndPoint KIND */ - /*!< STAT_TX[1:0] STATus for TX transfer */ -#define USB_EP_TX_DIS ((uint16_t)0x0000U) /*!< EndPoint TX DISabled */ -#define USB_EP_TX_STALL ((uint16_t)0x0010U) /*!< EndPoint TX STALLed */ -#define USB_EP_TX_NAK ((uint16_t)0x0020U) /*!< EndPoint TX NAKed */ -#define USB_EP_TX_VALID ((uint16_t)0x0030U) /*!< EndPoint TX VALID */ -#define USB_EPTX_DTOG1 ((uint16_t)0x0010U) /*!< EndPoint TX Data TOGgle bit1 */ -#define USB_EPTX_DTOG2 ((uint16_t)0x0020U) /*!< EndPoint TX Data TOGgle bit2 */ -#define USB_EPTX_DTOGMASK (USB_EPTX_STAT|USB_EPREG_MASK) - /*!< STAT_RX[1:0] STATus for RX transfer */ -#define USB_EP_RX_DIS ((uint16_t)0x0000U) /*!< EndPoint RX DISabled */ -#define USB_EP_RX_STALL ((uint16_t)0x1000U) /*!< EndPoint RX STALLed */ -#define USB_EP_RX_NAK ((uint16_t)0x2000U) /*!< EndPoint RX NAKed */ -#define USB_EP_RX_VALID ((uint16_t)0x3000U) /*!< EndPoint RX VALID */ -#define USB_EPRX_DTOG1 ((uint16_t)0x1000U) /*!< EndPoint RX Data TOGgle bit1 */ -#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */ -#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK) - //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/fsdev_common.c b/src/portable/st/stm32_fsdev/fsdev_common.c index 4f127ae86..003bcd069 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.c +++ b/src/portable/st/stm32_fsdev/fsdev_common.c @@ -38,12 +38,12 @@ // Reset the USB Core void fsdev_core_reset(void) { // Perform USB peripheral reset - FSDEV_REG->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; + FSDEV_REG->CNTR = U_CNTR_FRES | U_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } - FSDEV_REG->CNTR &= ~USB_CNTR_PDWN; + FSDEV_REG->CNTR &= ~U_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us @@ -57,13 +57,13 @@ void fsdev_core_reset(void) { // De-initialize the USB Core void fsdev_deinit(void) { // Disable all interrupts and force USB reset - FSDEV_REG->CNTR = USB_CNTR_FRES; + FSDEV_REG->CNTR = U_CNTR_FRES; // Clear pending interrupts FSDEV_REG->ISTR = 0; // Put USB peripheral in power down mode - FSDEV_REG->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; + FSDEV_REG->CNTR = U_CNTR_FRES | U_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } @@ -104,7 +104,7 @@ void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) { bl_nb = 1 << 15; } -#ifdef FSDEV_BUS_32BIT +#ifdef CFG_TUSB_FSDEV_32BIT uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index b749a92ff..140ff1d61 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -29,6 +29,10 @@ #ifndef TUSB_FSDEV_COMMON_H #define TUSB_FSDEV_COMMON_H +#ifdef __cplusplus +extern "C" { +#endif + #include "common/tusb_common.h" #if CFG_TUD_ENABLED @@ -39,99 +43,181 @@ #include "host/hcd.h" #endif -#if defined(TUP_USBIP_FSDEV_STM32) - #include "fsdev_stm32.h" -#elif defined(TUP_USBIP_FSDEV_CH32) - #include "fsdev_ch32.h" -#elif defined(TUP_USBIP_FSDEV_AT32) - #include "fsdev_at32.h" -#else - #error "Unknown USB IP" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it -// Both of these MUST be a multiple of 2, and are in byte units. -#ifndef FSDEV_BTABLE_BASE - #define FSDEV_BTABLE_BASE 0U -#endif - -TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes"); - -// CFG_TUSB_FSDEV_PMA_SIZE is PMA buffer size in bytes. -// - 512-byte devices, access with a stride of two words (use every other 16-bit address) -// - 1024-byte devices, access with a stride of one word (use every 16-bit address) or 32-bit address -// - 2048-byte devices, access with 32-bit address -#if CFG_TUSB_FSDEV_PMA_SIZE == 2048 || TU_CHECK_MCU(OPT_MCU_STM32U0) - // 32 bit access scheme - #define FSDEV_BUS_32BIT - #define FSDEV_PMA_STRIDE 1 - #define pma_access_scheme -#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 - // 2x16 bit / word access scheme - #define FSDEV_PMA_STRIDE 1 - #define pma_access_scheme -#elif CFG_TUSB_FSDEV_PMA_SIZE == 512 - // 1x16 bit / word access scheme - #define FSDEV_PMA_STRIDE 2 - #define pma_access_scheme TU_ATTR_ALIGNED(4) -#endif - -// The fsdev_bus_t type can be used for both register and PMA access necessities -#ifdef FSDEV_BUS_32BIT -typedef uint32_t fsdev_bus_t; -#else -typedef uint16_t fsdev_bus_t; -#endif - -enum { - FSDEV_BUS_SIZE = sizeof(fsdev_bus_t), -}; - //--------------------------------------------------------------------+ -// BTable Typedef +// FSDEV Register Bit Definitions +// Vendor-independent definitions with U_ prefix to avoid conflicts. +// Based on the common USB FSDEV IP block register layout. +// Lower 16 bits are shared across all variants (STM32, CH32, AT32). +// Upper 16 bits (DRD extensions) only exist on 32-bit DRD MCUs. //--------------------------------------------------------------------+ -enum { - BTABLE_BUF_TX = 0, - BTABLE_BUF_RX = 1 -}; -// hardware limit endpoint -#define FSDEV_EP_COUNT 8 +// EPnR / CHEPnR - Endpoint/Channel Register +// DTOG and STAT bits are toggle-on-write-1. CTR bits are clear-on-write-0. +// +// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +// CTR_RX DTOG_RX STAT_RX[1:0] SETUP EP_TYPE[1:0] KIND CTR_TX DTOG_TX STAT_TX[1:0] EA[3:0] +// +// DRD 32-bit only (C0, G0, H5, U0, U5): +// 31:27 26 25 24 23 22 21 20 19 18 17 16 +// Rsvd ERR_RX ERR_TX LSEP NAK DEVADDR[6:0] +#define U_EP_CTR_RX 0x8000u +#define U_EP_DTOG_RX 0x4000u +#define U_EPRX_STAT 0x3000u +#define U_EP_SETUP 0x0800u +#define U_EP_T_FIELD 0x0600u +#define U_EP_KIND 0x0100u +#define U_EP_CTR_TX 0x0080u +#define U_EP_DTOG_TX 0x0040u +#define U_EPTX_STAT 0x0030u +#define U_EPADDR_FIELD 0x000Fu -// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either -// 16-bit or 32-bit depending on FSDEV_BUS_32BIT. -// 0: TX (IN), 1: RX (OUT) -typedef union { - // data is strictly 16-bit access (address could be 32-bit aligned) - struct { - volatile pma_access_scheme uint16_t addr; - volatile pma_access_scheme uint16_t count; - } ep16[FSDEV_EP_COUNT][2]; +// DRD 32-bit upper bits +#define U_EP_ERRRX 0x04000000u +#define U_EP_ERRTX 0x02000000u +#define U_EP_LSEP 0x01000000u +#define U_EP_NAK 0x00800000u +#define U_EP_DEVADDR 0x007F0000u +#define U_EP_DEVADDR_Pos 16u - // strictly 32-bit access - struct { - volatile uint32_t count_addr; - } ep32[FSDEV_EP_COUNT][2]; -} fsdev_btable_t; +// Endpoint types (EP_TYPE field values) +#define U_EP_BULK 0x0000u +#define U_EP_CONTROL 0x0200u +#define U_EP_ISOCHRONOUS 0x0400u +#define U_EP_INTERRUPT 0x0600u +#define U_EP_TYPE_MASK (U_EP_T_FIELD) -TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT * 8 * FSDEV_PMA_STRIDE, "size is not correct"); -TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT * 8 <= CFG_TUSB_FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); +// EP register mask components (non-toggle bits preserved during read-modify-write) +// Excludes DTOG_RX, STAT_RX, DTOG_TX, STAT_TX (toggle-on-write-1) +#define U_EPREG_MASK_16 (U_EP_CTR_RX | U_EP_SETUP | U_EP_T_FIELD | U_EP_KIND | U_EP_CTR_TX | U_EPADDR_FIELD) +#define U_EPREG_MASK_32 (U_EP_ERRRX | U_EP_ERRTX | U_EP_LSEP | U_EP_NAK | U_EP_DEVADDR | U_EPREG_MASK_16) -#define FSDEV_BTABLE ((volatile fsdev_btable_t *)(FSDEV_PMA_BASE + FSDEV_PMA_STRIDE * (FSDEV_BTABLE_BASE))) +// EP register mask selection based on bus width +#ifdef CFG_TUSB_FSDEV_32BIT + #define U_EPREG_MASK U_EPREG_MASK_32 +#else + #define U_EPREG_MASK U_EPREG_MASK_16 +#endif -typedef struct { - volatile pma_access_scheme fsdev_bus_t value; -} fsdev_pma_buf_t; +#define U_EPKIND_MASK ((uint32_t)(~U_EP_KIND) & U_EPREG_MASK) +#define U_EPTX_DTOGMASK (U_EPTX_STAT | U_EPREG_MASK) +#define U_EPRX_DTOGMASK (U_EPRX_STAT | U_EPREG_MASK) -#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t *)(FSDEV_PMA_BASE + FSDEV_PMA_STRIDE * (_addr))) +// Bit positions +#define U_EPTX_STAT_Pos 4u +#define U_EP_DTOG_TX_Pos 6u +#define U_EP_CTR_TX_Pos 7u + +// Data toggle helpers +#define U_EPTX_DTOG1 0x0010u +#define U_EPTX_DTOG2 0x0020u +#define U_EPRX_DTOG1 0x1000u +#define U_EPRX_DTOG2 0x2000u + +// CNTR - Control Register +// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +// CTRM PMAOVRM ERRM WKUPM SUSPM RESETM SOFM ESOFM Rsvd Rsvd Rsvd RESUME FSUSP LPMODE PDWN FRES +// +// DRD 32-bit only: +// 31 30:16 +// HOST Rsvd +#define U_CNTR_CTRM 0x8000u +#define U_CNTR_PMAOVRM 0x4000u +#define U_CNTR_ERRM 0x2000u +#define U_CNTR_WKUPM 0x1000u +#define U_CNTR_SUSPM 0x0800u +#define U_CNTR_RESETM 0x0400u +#define U_CNTR_SOFM 0x0200u +#define U_CNTR_ESOFM 0x0100u +#define U_CNTR_RESUME 0x0010u +#define U_CNTR_FSUSP 0x0008u +#define U_CNTR_LPMODE 0x0004u +#define U_CNTR_PDWN 0x0002u +#define U_CNTR_FRES 0x0001u + +#define U_CNTR_HOST 0x80000000u // DRD: enable host mode +#define U_CNTR_DCON 0x0400u // DRD host: same bit as RESETM + +// ISTR - Interrupt Status Register +// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +// CTR PMAOVR ERR WKUP SUSP RESET SOF ESOF Rsvd Rsvd Rsvd DIR EP_ID[3:0] +// +// DRD 32-bit only: +// 31 30 29 28:16 +// Rsvd LS_DCONN DCON_STAT Rsvd +#define U_ISTR_CTR 0x8000u +#define U_ISTR_PMAOVR 0x4000u +#define U_ISTR_ERR 0x2000u +#define U_ISTR_WKUP 0x1000u +#define U_ISTR_SUSP 0x0800u +#define U_ISTR_RESET 0x0400u +#define U_ISTR_SOF 0x0200u +#define U_ISTR_ESOF 0x0100u +#define U_ISTR_DIR 0x0010u +#define U_ISTR_EP_ID 0x000Fu + +#define U_ISTR_LS_DCONN 0x40000000u // DRD: low-speed device connected +#define U_ISTR_DCON_STAT 0x20000000u // DRD: device connection status +#define U_ISTR_DCON 0x0400u // DRD host: same bit as RESET + +// FNR - Frame Number Register (read-only) +// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +// RXDP RXDM LCK[2:0] FN[10:0] +#define U_FNR_RXDP 0x8000u +#define U_FNR_RXDM 0x4000u +#define U_FNR_FN 0x07FFu + +// DADDR - Device Address Register +// 15:8 7 6 5 4 3 2 1 0 +// Rsvd EF ADD[6:0] +#define U_DADDR_EF 0x80u + +// LPMCSR - LPM Control and Status Register +// Supported: STM32 F0, L0, L4, G0, G4, C0, H5, U0, WB. Not on: F1, F3, AT32, CH32. +// 15:8 7 6 5 4 3 2 1 0 +// Rsvd BESL[3:0] Rsvd REMWAKE Rsvd LPMACK LMPEN +#define U_LPMCSR_LMPEN 0x0001u +#define U_LPMCSR_LPMACK 0x0002u +#define U_LPMCSR_REMWAKE 0x0008u +#define U_LPMCSR_BESL 0x00F0u + +// BCDR - Battery Charging Detector Register +// Supported: STM32 F0, L0, L4, G0, G4, C0, H5, U0, WB. Not on: F1, F3, AT32, CH32. +// 15 14:8 7 6 5 4 3 2 1 0 +// DPPU Rsvd PS2DET SDET PDET DCDET SDEN PDEN DCDEN BCDEN +#define U_BCDR_BCDEN 0x0001u +#define U_BCDR_DCDEN 0x0002u +#define U_BCDR_PDEN 0x0004u +#define U_BCDR_SDEN 0x0008u +#define U_BCDR_DCDET 0x0010u +#define U_BCDR_PDET 0x0020u +#define U_BCDR_SDET 0x0040u +#define U_BCDR_PS2DET 0x0080u +#define U_BCDR_DPPU 0x8000u + +// Channel status (DRD host mode, reuses STAT_TX/STAT_RX bit positions) +#define U_CH_TX_STTX 0x0030u +#define U_CH_TX_ACK_SBUF 0x0000u +#define U_CH_TX_STALL 0x0010u +#define U_CH_TX_NAK 0x0020u + +#define U_CH_RX_STRX 0x3000u +#define U_CH_RX_ACK_SBUF 0x0000u +#define U_CH_RX_STALL 0x1000u +#define U_CH_RX_NAK 0x2000u +#define U_CH_RX_VALID 0x3000u //--------------------------------------------------------------------+ // Registers Typedef //--------------------------------------------------------------------+ +// hardware limit endpoint +#define FSDEV_EP_COUNT 8 + +// The fsdev_bus_t type can be used for both register and PMA access necessities +#ifdef CFG_TUSB_FSDEV_32BIT +typedef uint32_t fsdev_bus_t; +#else +typedef uint16_t fsdev_bus_t; +#endif // volatile 32-bit aligned #define _va32 volatile TU_ATTR_ALIGNED(4) @@ -146,9 +232,9 @@ typedef struct { _va32 fsdev_bus_t ISTR; // 44: Interrupt status register _va32 fsdev_bus_t FNR; // 48: Frame number register _va32 fsdev_bus_t DADDR; // 4C: Device address register - _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only) - _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only) - _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only) + _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register + _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status (not on F1, F3, AT32, CH32) + _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector (not on F1, F3, AT32, CH32) } fsdev_regs_t; TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset"); @@ -156,27 +242,76 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define FSDEV_REG ((fsdev_regs_t *)FSDEV_REG_BASE) +//--------------------------------------------------------------------+ +// BTable and PMA Access +//--------------------------------------------------------------------+ -#ifndef USB_EPTX_STAT - #define USB_EPTX_STAT 0x0030U +// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it +// Both of these MUST be a multiple of 2, and are in byte units. +#ifndef FSDEV_BTABLE_BASE + #define FSDEV_BTABLE_BASE 0U +#endif +TU_VERIFY_STATIC((FSDEV_BTABLE_BASE & 0x7) == 0, "BTABLE base must be aligned to 8 bytes"); + +#define FSDEV_ADDR_DATA_RATIO (CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE/CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE) + +// Need alignment when access address is 32 bit but data is only 16-bit +#if FSDEV_ADDR_DATA_RATIO == 2 + #define fsdev_addr_data_align TU_ATTR_ALIGNED(4) +#else + #define fsdev_addr_data_align #endif -#ifndef USB_EPRX_STAT - #define USB_EPRX_STAT 0x3000U -#endif - -#ifndef USB_EPTX_STAT_Pos - #define USB_EPTX_STAT_Pos 4u -#endif - -#ifndef USB_EP_DTOG_TX_Pos - #define USB_EP_DTOG_TX_Pos 6u -#endif - -#ifndef USB_EP_CTR_TX_Pos - #define USB_EP_CTR_TX_Pos 7u +enum { + BTABLE_BUF_TX = 0, + BTABLE_BUF_RX = 1 +}; + +// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either +// 16-bit or 32-bit depending on CFG_TUSB_FSDEV_32BIT. +// 0: TX (IN), 1: RX (OUT) +typedef union { + // data is strictly 16-bit access (address could be 32-bit aligned) + struct { + volatile fsdev_addr_data_align uint16_t addr; + volatile fsdev_addr_data_align uint16_t count; + } ep16[FSDEV_EP_COUNT][2]; + + // strictly 32-bit access + struct { + volatile uint32_t count_addr; + } ep32[FSDEV_EP_COUNT][2]; +} fsdev_btable_t; + +TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT * 8 * FSDEV_ADDR_DATA_RATIO, "size is not correct"); +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT * 8 <= CFG_TUSB_FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); + +#define FSDEV_BTABLE ((volatile fsdev_btable_t *)(FSDEV_PMA_BASE + FSDEV_ADDR_DATA_RATIO * FSDEV_BTABLE_BASE)) + +typedef struct { + volatile fsdev_addr_data_align fsdev_bus_t value; +} fsdev_pma_buf_t; + +#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t *)(FSDEV_PMA_BASE + FSDEV_ADDR_DATA_RATIO * (_addr))) + +//--------------------------------------------------------------------+ +// Vendor-specific includes +//--------------------------------------------------------------------+ +#if defined(TUP_USBIP_FSDEV_STM32) + #include "fsdev_stm32.h" +#elif defined(TUP_USBIP_FSDEV_CH32) + #include "fsdev_ch32.h" +#elif defined(TUP_USBIP_FSDEV_AT32) + #include "fsdev_at32.h" +#else + #error "Unknown USB IP" #endif +//--------------------------------------------------------------------+ +// Endpoint Helper +// - CTR is write 0 to clear +// - DTOG and STAT are write 1 to toggle +//--------------------------------------------------------------------+ typedef enum { EP_STAT_DISABLED = 0, EP_STAT_STALL = 1, @@ -184,17 +319,11 @@ typedef enum { EP_STAT_VALID = 3 } ep_stat_t; -#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) -#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) +#define EP_STAT_MASK(_dir) (3u << (U_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) +#define EP_DTOG_MASK(_dir) (1u << (U_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) -#define CH_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0))) -#define CH_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0))) - -//--------------------------------------------------------------------+ -// Endpoint Helper -// - CTR is write 0 to clear -// - DTOG and STAT are write 1 to toggle -//--------------------------------------------------------------------+ +#define CH_STAT_MASK(_dir) (3u << (U_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0))) +#define CH_DTOG_MASK(_dir) (1u << (U_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0))) TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { return FSDEV_REG->ep[ep_id].reg; @@ -214,22 +343,22 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb_dir_t dir) { uint32_t reg = FSDEV_REG->ep[ep_id].reg; - reg |= USB_EP_CTR_TX | USB_EP_CTR_RX; - reg &= USB_EPREG_MASK; - reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); + reg |= U_EP_CTR_TX | U_EP_CTR_RX; + reg &= U_EPREG_MASK; + reg &= ~(1 << (U_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); ep_write(ep_id, reg, false); } TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t *reg, tusb_dir_t dir, ep_stat_t state) { - *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); + *reg ^= (state << (U_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t *reg, tusb_dir_t dir, uint8_t state) { - *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); + *reg ^= (state << (U_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { - return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; + return (reg & U_EP_TYPE_MASK) == U_EP_ISOCHRONOUS; } //--------------------------------------------------------------------+ @@ -247,18 +376,18 @@ TU_ATTR_ALWAYS_INLINE static inline void ch_write(uint32_t ch_id, uint32_t value TU_ATTR_ALWAYS_INLINE static inline void ch_write_clear_ctr(uint32_t ch_id, tusb_dir_t dir) { uint32_t reg = FSDEV_REG->ep[ch_id].reg; - reg |= USB_EP_CTR_TX | USB_EP_CTR_RX; - reg &= USB_EPREG_MASK; - reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); + reg |= U_EP_CTR_TX | U_EP_CTR_RX; + reg &= U_EPREG_MASK; + reg &= ~(1 << (U_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); ep_write(ch_id, reg, false); } TU_ATTR_ALWAYS_INLINE static inline void ch_change_status(uint32_t *reg, tusb_dir_t dir, ep_stat_t state) { - *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); + *reg ^= (state << (U_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); } TU_ATTR_ALWAYS_INLINE static inline void ch_change_dtog(uint32_t *reg, tusb_dir_t dir, uint8_t state) { - *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); + *reg ^= (state << (U_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); } //--------------------------------------------------------------------+ @@ -266,7 +395,7 @@ TU_ATTR_ALWAYS_INLINE static inline void ch_change_dtog(uint32_t *reg, tusb_dir_ //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { -#ifdef FSDEV_BUS_32BIT +#ifdef CFG_TUSB_FSDEV_32BIT return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; #else return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; @@ -274,9 +403,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uin } TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#ifdef CFG_TUSB_FSDEV_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; @@ -285,7 +415,7 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t TU_ATTR_ALWAYS_INLINE static inline uint16_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { uint16_t count; -#ifdef FSDEV_BUS_32BIT +#ifdef CFG_TUSB_FSDEV_32BIT count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); #else count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; @@ -294,13 +424,15 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t btable_get_count(uint32_t ep_id, ui } TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); +#ifdef CFG_TUSB_FSDEV_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else - uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; - cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; + cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); + FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; #endif } diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 02dba05a6..a63592c5d 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -35,20 +35,9 @@ #if CFG_TUSB_MCU == OPT_MCU_STM32C0 #include "stm32c0xx.h" #define FSDEV_HAS_SBUF_ISO 1 - #define USB USB_DRD_FS - #define USB_EP_CTR_RX USB_CHEP_VTRX - #define USB_EP_CTR_TX USB_CHEP_VTTX - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN #elif CFG_TUSB_MCU == OPT_MCU_STM32F0 #include "stm32f0xx.h" - #define FSDEV_REG_BASE USB_BASE #define FSDEV_HAS_SBUF_ISO 0 // F0x2 models are crystal-less // All have internal D+ pull-up @@ -61,24 +50,24 @@ // NO internal Pull-ups // *B, and *C: 2 x 16 bits/word - // F1 names this differently from the rest - #define USB_CNTR_LPMODE USB_CNTR_LP_MODE - -#elif defined(STM32F302xB) || defined(STM32F302xC) || defined(STM32F303xB) || defined(STM32F303xC) || \ - defined(STM32F373xC) +#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 #include "stm32f3xx.h" #define FSDEV_HAS_SBUF_ISO 0 - // NO internal Pull-ups - // *B, and *C: 1 x 16 bits/word - // PMA dedicated to USB (no sharing with CAN) + // NO internal Pull-ups. PMA dedicated to USB (no sharing with CAN) + // xB, and xC: 512 bytes + // x6, x8, xD, and xE: 1024 bytes + LPM Support. When CAN clock is enabled, USB can use the first 768 bytes ONLY. -#elif defined(STM32F302x6) || defined(STM32F302x8) || defined(STM32F302xD) || defined(STM32F302xE) || \ - defined(STM32F303xD) || defined(STM32F303xE) - #include "stm32f3xx.h" +#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 + #include "stm32g0xx.h" + #define FSDEV_HAS_SBUF_ISO 1 + +#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 + #include "stm32g4xx.h" #define FSDEV_HAS_SBUF_ISO 0 - // NO internal Pull-ups - // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support - // When CAN clock is enabled, USB can use first 768 bytes ONLY. + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + #include "stm32h5xx.h" + #define FSDEV_HAS_SBUF_ISO 1 #elif CFG_TUSB_MCU == OPT_MCU_STM32L0 #include "stm32l0xx.h" @@ -100,141 +89,24 @@ #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) #endif -#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 - #include "stm32g0xx.h" - #define FSDEV_HAS_SBUF_ISO 1 - #define USB USB_DRD_FS - - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 - #include "stm32g4xx.h" - #define FSDEV_HAS_SBUF_ISO 0 - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 - #include "stm32h5xx.h" - #define FSDEV_HAS_SBUF_ISO 1 - #define USB USB_DRD_FS - - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN - #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 #include "stm32u0xx.h" - #define FSDEV_BUS_32BIT #define FSDEV_HAS_SBUF_ISO 1 - #define USB USB_DRD_FS - - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN #elif CFG_TUSB_MCU == OPT_MCU_STM32U3 #include "stm32u3xx.h" - #define FSDEV_BUS_32BIT - #define FSDEV_HAS_SBUF_ISO 1 // This is assumed to work but has not been tested... - #define USB USB_DRD_FS - - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + #define FSDEV_HAS_SBUF_ISO 1 #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" #define FSDEV_HAS_SBUF_ISO 1 - #define USB USB_DRD_FS - - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN #elif CFG_TUSB_MCU == OPT_MCU_STM32WB #include "stm32wbxx.h" #define FSDEV_HAS_SBUF_ISO 0 - /* ST provided header has incorrect value of USB_PMAADDR */ - #define FSDEV_PMA_BASE USB1_PMAADDR #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. - // This includes U0 #endif //--------------------------------------------------------------------+ @@ -262,16 +134,6 @@ #endif #endif -// This checks if the device has "LPM" -#if defined(USB_ISTR_L1REQ) -#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) -#else -#define USB_ISTR_L1REQ_FORCED ((uint16_t)0x0000U) -#endif - -#define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \ - USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) - #ifndef FSDEV_HAS_SBUF_ISO #error "FSDEV_HAS_SBUF_ISO not defined" #endif @@ -311,42 +173,33 @@ #endif static const IRQn_Type fsdev_irq[] = { - #if TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32L0, OPT_MCU_STM32L4) + #if TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32L0, OPT_MCU_STM32L4, OPT_MCU_STM32U5) USB_IRQn, - #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 - USB_HP_CAN1_TX_IRQn, - USB_LP_CAN1_RX0_IRQn, - USBWakeUp_IRQn, - #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 - // USB remap handles dcd functions - USB_HP_CAN_TX_IRQn, - USB_LP_CAN_RX0_IRQn, - USBWakeUp_IRQn, + #elif TU_CHECK_MCU(OPT_MCU_STM32L5, OPT_MCU_STM32U3) + USB_FS_IRQn, + #elif TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32H5, OPT_MCU_STM32U0) + USB_DRD_FS_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #ifdef STM32G0B0xx USB_IRQn, #else USB_UCPD1_2_IRQn, #endif - #elif CFG_TUSB_MCU == OPT_MCU_STM32C0 - USB_DRD_FS_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 + USB_HP_CAN1_TX_IRQn, + USB_LP_CAN1_RX0_IRQn, + USBWakeUp_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 + USB_HP_CAN_TX_IRQn, + USB_LP_CAN_RX0_IRQn, + USBWakeUp_IRQn, #elif TU_CHECK_MCU(OPT_MCU_STM32G4, OPT_MCU_STM32L1) USB_HP_IRQn, USB_LP_IRQn, USBWakeUp_IRQn, - #elif CFG_TUSB_MCU == OPT_MCU_STM32H5 - USB_DRD_FS_IRQn, - #elif CFG_TUSB_MCU == OPT_MCU_STM32L5 - USB_FS_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32WB USB_HP_IRQn, USB_LP_IRQn, - #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 - USB_IRQn, - #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 - USB_DRD_FS_IRQn, - #elif CFG_TUSB_MCU == OPT_MCU_STM32U3 - USB_FS_IRQn, #else #error Unknown arch in USB driver #endif @@ -398,17 +251,20 @@ TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) { // CMSIS has a membar after disabling interrupts } -// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. +//--------------------------------------------------------------------+ +// Connect / Disconnect +//--------------------------------------------------------------------+ + #if defined(USB_BCDR_DPPU) TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) { (void)rhport; - USB->BCDR &= ~(USB_BCDR_DPPU); + FSDEV_REG->BCDR &= ~U_BCDR_DPPU; } TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) { (void)rhport; - USB->BCDR |= USB_BCDR_DPPU; + FSDEV_REG->BCDR |= U_BCDR_DPPU; } #elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151 diff --git a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c index 1813ef70b..dd86b052a 100644 --- a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c @@ -160,7 +160,7 @@ static inline void channel_dealloc(hcd_channel_t* ch, tusb_dir_t dir) { // Write channel state in specified direction static inline void channel_write_status(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir, ep_stat_t state, bool need_exclusive) { - ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir); + ch_reg &= U_EPREG_MASK | CH_STAT_MASK(dir); ch_change_status(&ch_reg, dir, state); ch_write(ch_id, ch_reg, need_exclusive); } @@ -182,7 +182,7 @@ static inline uint16_t channel_get_rx_count(uint8_t ch_id) { */ uint32_t ch_reg = ch_read(ch_id); - if (FSDEV_REG->ISTR & USB_ISTR_LS_DCONN || ch_reg & USB_CHEP_LSEP) { + if (FSDEV_REG->ISTR & U_ISTR_LS_DCONN || ch_reg & U_EP_LSEP) { // Low speed mode: 6.4 us delay -> about 2 cycles per MHz volatile uint32_t cycle_count = CPU_FREQUENCY_MHZ * 2U; while (cycle_count > 0U) { @@ -219,7 +219,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { fsdev_core_reset(); - FSDEV_REG->CNTR = USB_CNTR_HOST; // Enable USB in Host mode + FSDEV_REG->CNTR = U_CNTR_HOST; // Enable USB in Host mode tu_memclr(&_hcd_data, sizeof(_hcd_data)); @@ -229,7 +229,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { FSDEV_REG->ISTR = 0; // Enable interrupts for host mode - FSDEV_REG->CNTR |= USB_CNTR_DCON | USB_CNTR_CTRM | USB_CNTR_SOFM | USB_CNTR_ERRM | USB_CNTR_PMAOVRM; + FSDEV_REG->CNTR |= U_CNTR_DCON | U_CNTR_CTRM | U_CNTR_SOFM | U_CNTR_ERRM | U_CNTR_PMAOVRM; // Initialize port state _hcd_data.connected = false; @@ -237,7 +237,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { fsdev_connect(rhport); // If DCON_STAT is already set, the controller sometimes misses the initial connection interrupt - if (FSDEV_REG->ISTR & USB_ISTR_DCON_STAT) { + if (FSDEV_REG->ISTR & U_ISTR_DCON_STAT) { // Wait DP/DM stabilize time volatile uint32_t cycle_count = CPU_FREQUENCY_MHZ / 4U; while (cycle_count > 0U) { @@ -280,7 +280,7 @@ static void port_status_handler(uint8_t rhport, bool in_isr) { uint32_t const fnr_reg = FSDEV_REG->FNR; uint32_t const istr_reg = FSDEV_REG->ISTR; // SE0 detected USB Disconnected state - if ((fnr_reg & (USB_FNR_RXDP | USB_FNR_RXDM)) == 0U) { + if ((fnr_reg & (U_FNR_RXDP | U_FNR_RXDM)) == 0U) { _hcd_data.connected = false; hcd_event_device_remove(rhport, in_isr); return; @@ -288,13 +288,13 @@ static void port_status_handler(uint8_t rhport, bool in_isr) { if (!_hcd_data.connected) { // J-state or K-state detected & LastState=Disconnected - if (((fnr_reg & USB_FNR_RXDP) != 0U) || ((istr_reg & USB_ISTR_LS_DCONN) != 0U)) { + if (((fnr_reg & U_FNR_RXDP) != 0U) || ((istr_reg & U_ISTR_LS_DCONN) != 0U)) { _hcd_data.connected = true; hcd_event_device_attach(rhport, in_isr); } } else { // J-state or K-state detected & lastState=Connected: a Missed disconnection is detected - if (((fnr_reg & USB_FNR_RXDP) != 0U) || ((istr_reg & USB_ISTR_LS_DCONN) != 0U)) { + if (((fnr_reg & U_FNR_RXDP) != 0U) || ((istr_reg & U_ISTR_LS_DCONN) != 0U)) { _hcd_data.connected = false; hcd_event_device_remove(rhport, in_isr); } @@ -303,8 +303,8 @@ static void port_status_handler(uint8_t rhport, bool in_isr) { // Handle ACK response static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { - uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD; - uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos; + uint8_t const ep_num = ch_reg & U_EPADDR_FIELD; + uint8_t const daddr = (ch_reg & U_EP_DEVADDR) >> U_EP_DEVADDR_Pos; uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0)); if (ep_id == TUSB_INDEX_INVALID_8) { @@ -328,7 +328,7 @@ static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { } else { // Transfer complete channel_dealloc(channel, TUSB_DIR_OUT); - edpt->pid = (ch_reg & USB_CHEP_DTOG_TX) ? 1 : 0; + edpt->pid = (ch_reg & U_EP_DTOG_TX) ? 1 : 0; hcd_event_xfer_complete(daddr, ep_num, edpt->queued_len, XFER_RESULT_SUCCESS, true); } } else { @@ -341,7 +341,7 @@ static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { if ((rx_count < edpt->max_packet_size) || (edpt->queued_len >= edpt->buflen)) { // Transfer complete (short packet or all bytes received) channel_dealloc(channel, TUSB_DIR_IN); - edpt->pid = (ch_reg & USB_CHEP_DTOG_RX) ? 1 : 0; + edpt->pid = (ch_reg & U_EP_DTOG_RX) ? 1 : 0; hcd_event_xfer_complete(daddr, ep_num | TUSB_DIR_IN_MASK, edpt->queued_len, XFER_RESULT_SUCCESS, true); } else { // More data expected @@ -355,8 +355,8 @@ static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { // Handle NAK response static void ch_handle_nak(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { - uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD; - uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos; + uint8_t const ep_num = ch_reg & U_EPADDR_FIELD; + uint8_t const daddr = (ch_reg & U_EP_DEVADDR) >> U_EP_DEVADDR_Pos; uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0)); if (ep_id == TUSB_INDEX_INVALID_8) return; @@ -378,8 +378,8 @@ static void ch_handle_nak(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { // Handle STALL response static void ch_handle_stall(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { - uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD; - uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos; + uint8_t const ep_num = ch_reg & U_EPADDR_FIELD; + uint8_t const daddr = (ch_reg & U_EP_DEVADDR) >> U_EP_DEVADDR_Pos; uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0)); if (ep_id == TUSB_INDEX_INVALID_8) return; @@ -396,8 +396,8 @@ static void ch_handle_stall(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { // Handle error response static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { - uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD; - uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos; + uint8_t const ep_num = ch_reg & U_EPADDR_FIELD; + uint8_t const daddr = (ch_reg & U_EP_DEVADDR) >> U_EP_DEVADDR_Pos; uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0)); if (ep_id == TUSB_INDEX_INVALID_8) return; @@ -405,8 +405,8 @@ static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; hcd_channel_t* channel = &_hcd_data.channel[ch_id]; - ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir); - ch_reg &= ~(dir == TUSB_DIR_OUT ? USB_CH_ERRTX : USB_CH_ERRRX); + ch_reg &= U_EPREG_MASK | CH_STAT_MASK(dir); + ch_reg &= ~(dir == TUSB_DIR_OUT ? U_EP_ERRTX : U_EP_ERRRX); hcd_channel_dir_t* channel_dir = (dir == TUSB_DIR_OUT) ? &(_hcd_data.channel[ch_id].out) : &(_hcd_data.channel[ch_id].in); @@ -426,17 +426,17 @@ static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { // Handle CTR interrupt for the TX/OUT direction static inline void handle_ctr_tx(uint32_t ch_id) { - uint32_t ch_reg = ch_read(ch_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; + uint32_t ch_reg = ch_read(ch_id) | U_EP_CTR_TX | U_EP_CTR_RX; hcd_channel_t* channel = &_hcd_data.channel[ch_id]; TU_VERIFY(channel->out.allocated == 1,); - if ((ch_reg & USB_CH_ERRTX) == 0U) { + if ((ch_reg & U_EP_ERRTX) == 0U) { // No error - if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_ACK_SBUF) { + if ((ch_reg & U_CH_TX_STTX) == U_CH_TX_ACK_SBUF) { ch_handle_ack(ch_id, ch_reg, TUSB_DIR_OUT); - } else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_NAK) { + } else if ((ch_reg & U_CH_TX_STTX) == U_CH_TX_NAK) { ch_handle_nak(ch_id, ch_reg, TUSB_DIR_OUT); - } else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_STALL) { + } else if ((ch_reg & U_CH_TX_STTX) == U_CH_TX_STALL) { ch_handle_stall(ch_id, ch_reg, TUSB_DIR_OUT); } } else { @@ -446,17 +446,17 @@ static inline void handle_ctr_tx(uint32_t ch_id) { // Handle CTR interrupt for the RX/IN direction static inline void handle_ctr_rx(uint32_t ch_id) { - uint32_t ch_reg = ch_read(ch_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; + uint32_t ch_reg = ch_read(ch_id) | U_EP_CTR_TX | U_EP_CTR_RX; hcd_channel_t* channel = &_hcd_data.channel[ch_id]; TU_VERIFY(channel->in.allocated == 1,); - if ((ch_reg & USB_CH_ERRRX) == 0U) { + if ((ch_reg & U_EP_ERRRX) == 0U) { // No error - if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_ACK_SBUF) { + if ((ch_reg & U_CH_RX_STRX) == U_CH_RX_ACK_SBUF) { ch_handle_ack(ch_id, ch_reg, TUSB_DIR_IN); - } else if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_NAK) { + } else if ((ch_reg & U_CH_RX_STRX) == U_CH_RX_NAK) { ch_handle_nak(ch_id, ch_reg, TUSB_DIR_IN); - } else if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_STALL){ + } else if ((ch_reg & U_CH_RX_STRX) == U_CH_RX_STALL){ ch_handle_stall(ch_id, ch_reg, TUSB_DIR_IN); } } else { @@ -469,41 +469,41 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { uint32_t int_status = FSDEV_REG->ISTR; // Start of Frame - if (int_status & USB_ISTR_SOF) { - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; + if (int_status & U_ISTR_SOF) { + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_SOF; sof_handler(); } // Port Change Detected (Connection/Disconnection) - if (int_status & USB_ISTR_DCON) { - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_DCON; + if (int_status & U_ISTR_DCON) { + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_DCON; port_status_handler(rhport, in_isr); } // Handle transfer complete (CTR) - while (FSDEV_REG->ISTR & USB_ISTR_CTR) { - uint32_t const ch_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID; + while (FSDEV_REG->ISTR & U_ISTR_CTR) { + uint32_t const ch_id = FSDEV_REG->ISTR & U_ISTR_EP_ID; uint32_t const ch_reg = ch_read(ch_id); - if (ch_reg & USB_EP_CTR_RX) { + if (ch_reg & U_EP_CTR_RX) { ch_write_clear_ctr(ch_id, TUSB_DIR_IN); handle_ctr_rx(ch_id); } - if (ch_reg & USB_EP_CTR_TX) { + if (ch_reg & U_EP_CTR_TX) { ch_write_clear_ctr(ch_id, TUSB_DIR_OUT); handle_ctr_tx(ch_id); } } - if (int_status & USB_ISTR_ERR) { - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ERR; + if (int_status & U_ISTR_ERR) { + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_ERR; // TODO: Handle error } - if (int_status & USB_ISTR_PMAOVR) { + if (int_status & U_ISTR_PMAOVR) { TU_BREAKPOINT(); - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR; + FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_PMAOVR; } } @@ -520,7 +520,7 @@ void hcd_int_disable(uint8_t rhport) { // Get frame number (1ms) uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; - return FSDEV_REG->FNR & USB_FNR_FN; + return FSDEV_REG->FNR & U_FNR_FN; } //--------------------------------------------------------------------+ @@ -536,19 +536,19 @@ bool hcd_port_connect_status(uint8_t rhport) { // Reset USB bus on the port void hcd_port_reset(uint8_t rhport) { (void) rhport; - FSDEV_REG->CNTR |= USB_CNTR_FRES; + FSDEV_REG->CNTR |= U_CNTR_FRES; } // Complete bus reset sequence void hcd_port_reset_end(uint8_t rhport) { (void) rhport; - FSDEV_REG->CNTR &= ~USB_CNTR_FRES; + FSDEV_REG->CNTR &= ~U_CNTR_FRES; } // Get port link speed tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; - if ((FSDEV_REG->ISTR & USB_ISTR_LS_DCONN) != 0U) { + if ((FSDEV_REG->ISTR & U_ISTR_LS_DCONN) != 0U) { return TUSB_SPEED_LOW; } else { return TUSB_SPEED_FULL; @@ -647,7 +647,7 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { channel->dev_addr == dev_addr && channel->ep_num == tu_edpt_number(ep_addr)) { channel_dealloc(channel, dir); - uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX; + uint32_t ch_reg = ch_read(i) | U_EP_CTR_TX | U_EP_CTR_RX; channel_write_status(i, ch_reg, dir, EP_STAT_DISABLED, true); } } @@ -724,7 +724,7 @@ static void edpoint_close(uint8_t ep_id) { // disable active channel belong to this endpoint for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) { hcd_channel_t* channel = &_hcd_data.channel[i]; - uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX; + uint32_t ch_reg = ch_read(i) | U_EP_CTR_TX | U_EP_CTR_RX; if (channel->out.allocated == 1 && channel->out.edpt == edpt) { channel_dealloc(channel, TUSB_DIR_OUT); channel_write_status(i, ch_reg, TUSB_DIR_OUT, EP_STAT_DISABLED, true); @@ -818,21 +818,21 @@ static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir) { hcd_channel_t* channel = &_hcd_data.channel[ch_id]; hcd_endpoint_t* edpt = (dir == TUSB_DIR_OUT) ? channel->out.edpt : channel->in.edpt; - uint32_t ch_reg = ch_read(ch_id) & ~USB_EPREG_MASK; - ch_reg |= tu_edpt_number(edpt->ep_addr) | edpt->dev_addr << USB_CHEP_DEVADDR_Pos | - USB_EP_CTR_TX | USB_EP_CTR_RX; + uint32_t ch_reg = ch_read(ch_id) & ~U_EPREG_MASK; + ch_reg |= tu_edpt_number(edpt->ep_addr) | edpt->dev_addr << U_EP_DEVADDR_Pos | + U_EP_CTR_TX | U_EP_CTR_RX; // Set type switch (edpt->ep_type) { case TUSB_XFER_BULK: - ch_reg |= USB_EP_BULK; + ch_reg |= U_EP_BULK; break; case TUSB_XFER_INTERRUPT: - ch_reg |= USB_EP_INTERRUPT; + ch_reg |= U_EP_INTERRUPT; break; case TUSB_XFER_CONTROL: - ch_reg |= USB_EP_CONTROL; + ch_reg |= U_EP_CONTROL; break; default: @@ -855,9 +855,9 @@ static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir) { } if (edpt->ls_pre == 1) { - ch_reg |= USB_CHEP_LSEP; + ch_reg |= U_EP_LSEP; } else { - ch_reg &= ~USB_CHEP_LSEP; + ch_reg &= ~U_EP_LSEP; } // Setup DATA/STATUS phase start with DATA1 @@ -867,13 +867,13 @@ static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir) { if (edpt->next_setup) { edpt->next_setup = false; - ch_reg |= USB_EP_SETUP; + ch_reg |= U_EP_SETUP; edpt->pid = 0; } ch_change_status(&ch_reg, dir, EP_STAT_VALID); ch_change_dtog(&ch_reg, dir, edpt->pid); - ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir) | CH_DTOG_MASK(dir); + ch_reg &= U_EPREG_MASK | CH_STAT_MASK(dir) | CH_DTOG_MASK(dir); ch_write(ch_id, ch_reg, true); return true; diff --git a/src/tusb_option.h b/src/tusb_option.h index 3814a4d71..9eb8ee533 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -340,12 +340,16 @@ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #if CFG_TUSB_FSDEV_PMA_SIZE == 2048 || TU_CHECK_MCU(OPT_MCU_STM32U0) + // 32-bit access scheme #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase + #define CFG_TUSB_FSDEV_32BIT #elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 + // 2 x 16-bit access scheme #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 2 // 16-bit address increase #elif CFG_TUSB_FSDEV_PMA_SIZE == 512 + // 1 x 16-bit access scheme #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase #endif diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 8de8c7f32..e8449ba74 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -182,7 +182,8 @@ "name": "jlink", "uid": "779541626", "args": "-device stm32f072rb" - } + }, + "comment": "2x16 access scheme with 1KB USB SRAM" }, { "name": "stm32f723disco", @@ -226,7 +227,8 @@ "name": "openocd", "uid": "066FFF495087534867063844", "args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - } + }, + "comment": "32-bit scheme, 2KB USB SRAM" } ], "boards-skip": [