Skip to content

Conversation

@tswan22
Copy link

@tswan22 tswan22 commented Nov 1, 2025

Describe the PR
Added the USB device for the STM32U3 using stm32_fsdev.

Additional context

  • Essentially the same as the STM32U0 and STM32U5 (stm32_fsdev) and others.
  • I am not sure if this addition also handles USB host, but it is possible on this MCU. I left the column empty in the README.
  • This was tested on a custom PCB so I did not add any hw/bsp
  • I have only tested it with CDC device.
  • In #2824 it was mentioned there is quite a bit of duplication for the fsdev code. I have followed suit but I can adjust if needed.
  • I have set FSDEV_HAS_SBUF_ISO 1 in fsdev_stm32.h though this has not been tested.
    • I see it is 0 in STM32U0 but 1 in STM32U5. This ultimately translates to FSDEV_USE_SBUF_ISO 1 which is used in dcd_stm32_fsdev.c, but I don't quite know what it does. Since STM32U3 is between the others in terms of capability I figured it would be capable of it.

Family Code
I am not using the tinyusb hw/bsp setup in my project but I do have a minimum setup code which I will add here, I am not sure if I should add this somewhere else but it may be useful for anyone adding a board in the future. Sorry the GPIO config does not use HAL since it is generated from another tool, but it can likely be replaced with HAL_GPIO_Init(...).

#include "tusb.h"
#include "stm32u3xx_hal_pwr.h"
#include "stm32u3xx_hal_rcc.h"

void USB_FS_IRQHandler(void)
{
    tud_int_handler(0);
}

size_t board_get_unique_id(uint8_t id[], size_t max_len) // from STM32U5
{
    (void) max_len;
    volatile uint32_t *stm32_uuid = (volatile uint32_t *) UID_BASE;
    uint32_t *id32 = (uint32_t *) (uintptr_t) id;
    uint8_t const len = 12;

    id32[0] = stm32_uuid[0];
    id32[1] = stm32_uuid[1];
    id32[2] = stm32_uuid[2];

    return len;
}

void usb_setup()
{
    HAL_PWREx_EnableVddUSB();
    __HAL_RCC_USB1_CLK_ENABLE();

    LL_RCC_HSI48_Enable();
    while(LL_RCC_HSI48_IsReady() != 1);

    LL_RCC_SetICLKClockSource(LL_RCC_ICLK_CLKSOURCE_HSI48);
    while (LL_RCC_GetICLKClockSource(LL_RCC_ICLK_CLKSOURCE) != LL_RCC_ICLK_CLKSOURCE_HSI48);
    LL_RCC_SetUSBClockSource(LL_RCC_USB1_CLKSOURCE_ICLK);

    __HAL_RCC_CRS_CLK_ENABLE();
    RCC_CRSInitTypeDef RCC_CRSInitStruct = {0};
    RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
    RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB;
    RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING;
    RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000,1000);
    RCC_CRSInitStruct.ErrorLimitValue = 34;
    RCC_CRSInitStruct.HSI48CalibrationValue = 32;
    HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct);

    // Don't think this is actually necessary since USB DM/DP are not AF
    // GPIOB 11: USB_DM
    GPIOA->MODER = (GPIOA->MODER & ~GPIO_MODER_MODE11_Msk) | (0x2 << GPIO_MODER_MODE11_Pos); // AF
    GPIOA->OTYPER = (GPIOA->OTYPER & ~GPIO_OTYPER_OT11_Msk) | (0x0 << GPIO_OTYPER_OT11_Pos); // PUSH_PULL
    GPIOA->OSPEEDR = (GPIOA->OSPEEDR & ~GPIO_OSPEEDR_OSPEED11_Msk) | (0x3 << GPIO_OSPEEDR_OSPEED11_Pos); // VERY-HIGH
    GPIOA->PUPDR = (GPIOA->PUPDR & ~GPIO_PUPDR_PUPD11_Msk) | (0x0 << GPIO_PUPDR_PUPD11_Pos); // NONE
    GPIOA->AFR[1] = (GPIOA->AFR[1] & ~GPIO_AFRH_AFSEL11_Msk) | (0xA << GPIO_AFRH_AFSEL11_Pos); // AF10
    // GPIOA 12: USB_DP
    GPIOA->MODER = (GPIOA->MODER & ~GPIO_MODER_MODE12_Msk) | (0x2 << GPIO_MODER_MODE12_Pos); // AF
    GPIOA->OTYPER = (GPIOA->OTYPER & ~GPIO_OTYPER_OT12_Msk) | (0x0 << GPIO_OTYPER_OT12_Pos); // PUSH_PULL
    GPIOA->OSPEEDR = (GPIOA->OSPEEDR & ~GPIO_OSPEEDR_OSPEED12_Msk) | (0x3 << GPIO_OSPEEDR_OSPEED12_Pos); // VERY-HIGH
    GPIOA->PUPDR = (GPIOA->PUPDR & ~GPIO_PUPDR_PUPD12_Msk) | (0x0 << GPIO_PUPDR_PUPD12_Pos); // NONE
    GPIOA->AFR[1] = (GPIOA->AFR[1] & ~GPIO_AFRH_AFSEL12_Msk) | (0xA << GPIO_AFRH_AFSEL12_Pos); // AF10
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant