You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I'm a beginner. My hardware board is based on STM32F405RGT6 + USB3300. The STM32F405RGT6 uses an 8 MHz crystal, and the USB3300 uses a 24 MHz crystal. Only the ULPI-related pins are connected between the USB3300 and STM32F405RGT6, with the USB_HS interface exposed via the USB3300. I have flashed other firmware and confirmed that USB High-Speed is recognized, proving the hardware is functional. I am now trying to create a bootloader for my board that supports firmware updates via the USB_HS interface. After researching, the main modifications are required in the boards.c ,I am modifying the configuration based on feather_stm32f405_express, changing the crystal oscillator to 8 MHz to match my hardware and #define BOARD_TUD_RHPORT 1. I have commented out configurations for LED, NeoPixel, and UART to avoid pin conflicts。I erased the entire STM32F405RGT6 chip and flashed the compiled bootloader (BL). After waiting a few seconds, I reconnected the USB cable. About 1-2 seconds later, the computer prompted an "Unknown USB Device," and upon checking with UsbTreeView, I found error code 43,Am I missing some critical code?
// TODO enable only used GPIO clock
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
#ifdef __HAL_RCC_GPIOD_CLK_ENABLE
__HAL_RCC_GPIOD_CLK_ENABLE();
#endif
//--------------------------------------------------------------------+
// LED pattern
//--------------------------------------------------------------------+
#ifdef LED_PIN
void board_led_write(uint32_t state)
{
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
}
#endif
#ifdef NEOPIXEL_NUMBER
#define MAGIC_800_INT 900000 // ~1.11 us -> 1.2 field
#define MAGIC_800_T0H 2800000 // ~0.36 us -> 0.44 field
#define MAGIC_800_T1H 1350000 // ~0.74 us -> 0.84 field
#ifndef BUILD_NO_TINYUSB
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
// Despite being call USB2_OTG
// OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port
void OTG_FS_IRQHandler(void)
{
tud_int_handler(0);
}
// Despite being call USB2_OTG
// OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port
void OTG_HS_IRQHandler(void)
{
tud_int_handler(1);
}
#endif
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void)
{
This discussion was converted from issue #429 on February 06, 2025 06:02.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Operating System
Windows 10
INFO_UF2.TXT
Not yet uploaded
What happened ?
Hi, I'm a beginner. My hardware board is based on STM32F405RGT6 + USB3300. The STM32F405RGT6 uses an 8 MHz crystal, and the USB3300 uses a 24 MHz crystal. Only the ULPI-related pins are connected between the USB3300 and STM32F405RGT6, with the USB_HS interface exposed via the USB3300. I have flashed other firmware and confirmed that USB High-Speed is recognized, proving the hardware is functional. I am now trying to create a bootloader for my board that supports firmware updates via the USB_HS interface. After researching, the main modifications are required in the boards.c ,I am modifying the configuration based on feather_stm32f405_express, changing the crystal oscillator to 8 MHz to match my hardware and #define BOARD_TUD_RHPORT 1. I have commented out configurations for LED, NeoPixel, and UART to avoid pin conflicts。I erased the entire STM32F405RGT6 chip and flashed the compiled bootloader (BL). After waiting a few seconds, I reconnected the USB cable. About 1-2 seconds later, the computer prompted an "Unknown USB Device," and upon checking with UsbTreeView, I found error code 43,Am I missing some critical code?
boards.c file here:`#include "board_api.h"
#ifndef BUILD_NO_TINYUSB
#include "tusb.h"
#endif
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
#define STM32_UUID ((volatile uint32_t *) UID_BASE)
UART_HandleTypeDef UartHandle;
void board_init(void)
{
clock_init();
SystemCoreClockUpdate();
// disable systick
board_timer_stop();
// TODO enable only used GPIO clock
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
#ifdef __HAL_RCC_GPIOD_CLK_ENABLE
__HAL_RCC_GPIOD_CLK_ENABLE();
#endif
GPIO_InitTypeDef GPIO_InitStruct;
#ifdef BUTTON_PIN
GPIO_InitStruct.Pin = BUTTON_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
#endif
#ifdef LED_PIN
GPIO_InitStruct.Pin = LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
board_led_write(0);
#endif
#ifdef NEOPIXEL_NUMBER
GPIO_InitStruct.Pin = NEOPIXEL_PIN;
GPIO_InitStruct.Mode = NEOPIXEL_PIN_MODE;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(NEOPIXEL_PORT, &GPIO_InitStruct);
#endif
#if defined(UART_DEV) && CFG_TUSB_DEBUG
UART_CLOCK_ENABLE();
GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = UART_GPIO_AF;
HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct);
UartHandle.Instance = UART_DEV;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&UartHandle);
#endif
}
void board_dfu_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* ULPI D0 | CLK */
GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* ULPI D1 D2 D3 D4 D5 D6 D7 */
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
// GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* ULPI STP | DIR | NXT*/
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) ||
defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||
defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
#ifdef USB_NO_VBUS_PIN
/* Deactivate VBUS Sensing B */
USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
#else
// Enable VBUS sense (B device) via pin PA9
USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBDEN;
#endif
#else
#ifdef USB_NO_VBUS_PIN
// Disable VBUS sense
USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
#else
// Enable VBUS sense (B device) via pin PA9
USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS;
USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
#endif
#endif
}
void board_reset(void)
{
NVIC_SystemReset();
}
void board_dfu_complete(void)
{
NVIC_SystemReset();
}
bool board_app_valid(void)
{
volatile uint32_t const * app_vector = (volatile uint32_t const*) BOARD_FLASH_APP_START;
uint32_t sp = app_vector[0];
uint32_t app_entry = app_vector[1];
TUF2_LOG1_HEX(sp);
TUF2_LOG1_HEX(app_entry);
// 1st word is stack pointer (must be in SRAM region)
if ((sp & 0xff000003) != 0x20000000) return false;
// 2nd word is App entry point (reset)
if (app_entry < BOARD_FLASH_APP_START || app_entry > BOARD_FLASH_APP_START + BOARD_FLASH_SIZE) {
return false;
}
return true;
}
void board_app_jump(void)
{
volatile uint32_t const * app_vector = (volatile uint32_t const*) BOARD_FLASH_APP_START;
uint32_t sp = app_vector[0];
uint32_t app_entry = app_vector[1];
#ifdef BUTTON_PIN
HAL_GPIO_DeInit(BUTTON_PORT, BUTTON_PIN);
#endif
#ifdef LED_PIN
HAL_GPIO_DeInit(LED_PORT, LED_PIN);
#endif
#ifdef NEOPIXEL_NUMBER
HAL_GPIO_DeInit(NEOPIXEL_PORT, NEOPIXEL_PIN);
#endif
#if defined(UART_DEV) && CFG_TUSB_DEBUG
HAL_UART_DeInit(&UartHandle);
HAL_GPIO_DeInit(UART_GPIO_PORT, UART_TX_PIN | UART_RX_PIN);
UART_CLOCK_DISABLE();
#endif
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
#ifdef __HAL_RCC_GPIOD_CLK_DISABLE
__HAL_RCC_GPIOD_CLK_DISABLE();
#endif
HAL_RCC_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
// Disable all Interrupts
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
NVIC->ICER[2] = 0xFFFFFFFF;
NVIC->ICER[3] = 0xFFFFFFFF;
/* switch exception handlers to the application */
SCB->VTOR = (uint32_t) BOARD_FLASH_APP_START;
// Set stack pointer
__set_MSP(sp);
__set_PSP(sp);
// Jump to Application Entry
asm("bx %0" ::"r"(app_entry));
}
uint8_t board_usb_get_serial(uint8_t serial_id[16])
{
uint8_t const len = 12;
uint32_t* serial_id32 = (uint32_t*) (uintptr_t) serial_id;
serial_id32[0] = STM32_UUID[0];
serial_id32[1] = STM32_UUID[1];
serial_id32[2] = STM32_UUID[2];
return len;
}
//--------------------------------------------------------------------+
// LED pattern
//--------------------------------------------------------------------+
#ifdef LED_PIN
void board_led_write(uint32_t state)
{
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
}
#endif
#ifdef NEOPIXEL_NUMBER
#define MAGIC_800_INT 900000 // ~1.11 us -> 1.2 field
#define MAGIC_800_T0H 2800000 // ~0.36 us -> 0.44 field
#define MAGIC_800_T1H 1350000 // ~0.74 us -> 0.84 field
static inline uint8_t apply_percentage(uint8_t brightness)
{
return (uint8_t) ((brightness*NEOPIXEL_BRIGHTNESS) >> 8);
}
void board_rgb_write(uint8_t const rgb[]) {
// assumes 800_000Hz frequency
// Theoretical values here are 800_000 -> 1.25us, 2500000->0.4us,
// 1250000->0.8us
uint32_t const sys_freq = HAL_RCC_GetSysClockFreq();
uint32_t const interval = sys_freq / MAGIC_800_INT;
uint32_t const t0 = sys_freq / MAGIC_800_T0H;
uint32_t const t1 = sys_freq / MAGIC_800_T1H;
// neopixel color order is GRB
uint8_t const colors[3] = {apply_percentage(rgb[1]), apply_percentage(rgb[0]),
apply_percentage(rgb[2])};
__disable_irq();
uint32_t start;
uint32_t cyc;
// Enable DWT in debug core. Usable when interrupts disabled, as opposed to
// Systick->VAL
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
DWT->CYCCNT = 0;
for (uint32_t i = 0; i < NEOPIXEL_NUMBER; i++) {
uint8_t const *color_pointer = colors;
uint8_t const *const color_pointer_end = color_pointer + 3;
uint8_t color = *color_pointer++;
uint8_t color_mask = 0x80;
}
__enable_irq();
}
#else
void board_rgb_write(uint8_t const rgb[])
{
(void) rgb;
}
#endif
//--------------------------------------------------------------------+
// Timer
//--------------------------------------------------------------------+
void board_timer_start(uint32_t ms)
{
SysTick_Config( (SystemCoreClock/1000) * ms );
}
void board_timer_stop(void)
{
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Handler(void)
{
board_timer_handler();
}
int board_uart_write(void const * buf, int len)
{
#if defined(UART_DEV) && CFG_TUSB_DEBUG
HAL_UART_Transmit(&UartHandle, (uint8_t*) buf, len, 0xffff);
return len;
#else
(void) buf; (void) len;
(void) UartHandle;
return 0;
#endif
}
#ifndef BUILD_NO_TINYUSB
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
// Despite being call USB2_OTG
// OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port
void OTG_FS_IRQHandler(void)
{
tud_int_handler(0);
}
// Despite being call USB2_OTG
// OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port
void OTG_HS_IRQHandler(void)
{
tud_int_handler(1);
}
#endif
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void)
{
}`
How to reproduce ?
Not yet uploaded
Debug Log
Not yet uploaded
Screenshots
Beta Was this translation helpful? Give feedback.
All reactions