cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f0: effect of bootloader on usart

a2
Associate II
Posted on June 25, 2013 at 10:58

Hi there,

I'm using ST's bootloader in rom to program my device and USART1 for communications. Now I observed the following problem: when my code runs directly after startup, it works fine. However, when my code receives control via the bootloader, the USART speed seems a little but off and every few characters are corrupted on the rx side. I found a different value for the BRR which works for the post-bootloader-path, but now this value corrupts characters for the direct startup -- exactly the other way around.

I'm currently using a work around: I determine the presence of the bootloader by testing some registers at startup, and choose BRR accordingly, but this doesn't feel safe.

Any comments? Tia. This is my init code:

void init_usart(void)

{

    USART_InitTypeDef USART_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_DeInit(USART1);

    ///?

    USART_ClockInitTypeDef  USART_ClockInitStructure;

    USART_ClockStructInit(&USART_ClockInitStructure);

    USART_ClockInit(USART1, &USART_ClockInitStructure);

    ///?

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

    /* Configure USART1 pins:  Rx and Tx ----------------------------*/

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = 115200;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    USART_InitStructure.USART_StopBits = USART_StopBits_1;

    USART_InitStructure.USART_Parity = USART_Parity_No;

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);

    USART_Cmd(USART1,ENABLE);

}

#stm32f0-usart-bootloader
4 REPLIES 4
Posted on June 25, 2013 at 13:59

So is this code in FLASH?

If the timing is wrong you should perhaps review the clock and PLL settings that the Boot Loader enters with. Inspect the start up code in system_stm32f0xx.c, SystemInit()

You might also want to output internal clocks via the MCO pins, or TIM, or output a constant character and measure the baud timing. Time also your host device.

The System Loader sets the baud rate based on timing the 0x7F pattern with 8E1 (Even Parity)
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
a2
Associate II
Posted on July 01, 2013 at 08:22

Thanks for your comment. This code is in flash, indeed. I was not able to spot any oddities in system_stm32f0xx.c, SystemInit(), I use the one from STM. At the moment, I don't have the tools to measure the clocks from outside, but I'll try to do so.

Regards,

Roel

a2
Associate II
Posted on July 10, 2013 at 08:50

I don't need the bootloader anymore, I wrote my own. However, for future reference, I believe that I found the problem. I dumped all IOs and compared them for post and non-bootloader states. I believe that the problems were caused by the RCC_CR settings. For reasons I cannot understand, the bootloader sets HSITRIM from 16 to 0, without resetting it afterwards. Hence, the HSI is about 640kHz off. Beware, I didn't verify my hypothesis, this is just what I observed.

a2
Associate II
Posted on March 27, 2014 at 11:42

I'm convinced that I was right, and it keeps me bothering. Especially that ST remains silent about this problem. For any people suffering from the same problem:

RCC_AdjustHSICalibrationValue(0x10);

or

RCC->CR = (RCC->CR&0xffffff07) | 0x80

Will solve your problems. I believe I understand the bootloader programmer's mistake too: the calibration value is set to 0 (what you want) by writing 16, writing 0 is setting it to its maximum actually.