-
Notifications
You must be signed in to change notification settings - Fork 238
Description
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;
/* B-peripheral session valid override enable */
USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
USB_OTG_HS->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
#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;
while (true) {
cyc = (color & color_mask) ? t1 : t0;
start = DWT->CYCCNT;
HAL_GPIO_WritePin(NEOPIXEL_PORT, NEOPIXEL_PIN, 1);
while ((DWT->CYCCNT - start) < cyc)
;
HAL_GPIO_WritePin(NEOPIXEL_PORT, NEOPIXEL_PIN, 0);
while ((DWT->CYCCNT - start) < interval)
;
if (!(color_mask >>= 1)) {
if (color_pointer >= color_pointer_end) {
break;
}
color = *color_pointer++;
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


