2019-08-28 02:30 PM
I have a self powered STM32F446 with 24 MHz oscillator, not crystal. When trying to activate the bootloader mode, I get variable results. Sometimes it shows up properly, sometimes it shows up but in a corrupted type of state, and sometimes it doesn't come up at all. The corrupted states seems to get most of the usb descriptors correctly, but the string descriptors don't come up as well.
I use USB in the main application mode of my program as well, and that works without issue.
A previous design with the F446 that was usb powered, 24 MHz crystal had no issues. Some of the pinout has changed between designs. Any ideas where I should be looking? Improper clock detection? Other bootloader mode activated, but still somewhat communicating over USB?
Example top of descriptor, corrupted,
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0483 STMicroelectronics
idProduct 0xdf11 STM Device in DFU Mode
bcdDevice 22.00
iManufacturer 1 (error)
iProduct 2 (error)
iSerial 3 Љ
bNumConfigurations 1
Configuration Descriptor:
bLength 9
2019-08-28 02:34 PM
AN2606 would indicate the pins which the ROM is looking for activity on.
2019-08-28 02:37 PM
Then my question there is if it possible that it could potentially partially communicate over usb if it entered a different mode. If so then I'd look more into the pin states and forcing them low, etc.
2019-08-29 01:58 PM
I can connect the debugger when the bootloader is running and see that in fact it's detecting the oscillator as 23 MHz when usb doesn't work. It addition the bootloader does not set HSEBYP. So is it just that the bootloader is not compatible with oscillators, only crystals?
2019-08-30 08:10 AM
So it seems that the issue is just poor HSI accuracy such that autodetect doesn't work. My measured HSI is 16.4 MHz. This is described here: https://community.st.com/s/article/FAQ-DFU-mode-with-system-bootloader-is-not-working-while-USB-does
My workaround is to trim hsi. This won't help for a brand new board, but it does for reboot to bootloader from application code. Here is some code:
// Find the best value of hsi_trim
uint8_t calibrate_hsi(uint8_t hse_freq) {
// hsi frequency is supposed to be 16 MHz
// Switch to hsi for sysclk, connect hse_rtc to tim11 for counting
RCC->APB2ENR |= RCC_APB2ENR_TIM11EN;
RCC->CFGR &= ~(RCC_CFGR_SW | RCC_CFGR_PPRE2); // HSI at 16MHz for sysclk, APB2 at 16MHz for TIM11
RCC->CFGR |= (uint32_t) hse_freq << RCC_CFGR_RTCPRE_Pos; // HSE_RTC at 1 MHz
TIM11->OR = 2;
TIM11->CR1 |= TIM_CR1_CEN;
TIM11->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_IC1PSC; // input capture IC1, max prescaler, 8
TIM11->CCER |= TIM_CCER_CC1E; // enable input capture
int16_t min_error = INT16_MAX;
uint8_t min_hsi_trim = 0x10;
for (uint32_t i=0; i<=0x1F; i++) {
uint32_t hsi_trim = i << RCC_CR_HSITRIM_Pos;
RCC->CR &= ~RCC_CR_HSITRIM;
RCC->CR |= hsi_trim;
uint16_t start_count = TIM11->CCR1;
uint16_t tmp[10];
for (int j=0; j<10; j++) {
while(!(TIM11->SR & TIM_SR_CC1IF)); // wait for capture
tmp[j] = TIM11->CCR1;
}
// The ideal total count is 10*8*16
uint16_t total_count = TIM11->CCR1 - start_count;
int16_t error = 10*8*16 - (int16_t) total_count;
if (abs(error) < abs(min_error)) {
min_hsi_trim = i;
min_error = error;
}
}
return min_hsi_trim;
}
// Call bootloader, trigger is go_to_bootloader==1 on reboot + software reset
uint8_t go_to_bootloader = false;
uint32_t hsi_trim = 0x10l << RCC_CR_HSITRIM_Pos;
void reboot_to_bootloader() {
__disable_irq();
go_to_bootloader = true;
hsi_trim = (uint32_t) calibrate_hsi(get_pin_config()->crystal_frequency_MHz) << RCC_CR_HSITRIM_Pos;
NVIC_SystemReset();
}
.section .text
Reboot_Loader:
ldr r0, =0x40023844 /* RCC_APB2ENR */
ldr r1, =0x00004000 /* ENABLE SYSCFG CLOCK */
str R1, [R0, #0]
ldr r0, =0x40023800 /* RCC_CR */
ldr r1, =hsi_trim
ldr r1, [r1]
str r1, [r0]
ldr R0, =0x40013800 /* SYSCFG_MEMRMP */
ldr R1, =0x00000001 /* MAP ROM AT ZERO */
str R1, [R0, #0]
ldr R0, =0x1FFF0000 /* ROM BASE */
ldr SP,[R0, #0] /* SP @ +0 */
ldr R0,[R0, #4] /* PC @ +4 */
bx R0
2019-08-30 08:54 AM
Thanks for details
2022-08-30 03:18 PM
try calibrating the HSI generator