2020-11-16 03:03 AM
I'm trying to activate the UART bootloader after receiving input (from either a button press or from parsing a command from UART interrupt). I see from the G030x programming manual that to do so, I must set bits of the FLASH_OPTR register as nBOOT1 = 1, nBOOT_SEL = 1, and nBOOT0 = 0. The value of the boot0 pin shouldn't matter. I do this by using the following code (and HAL libraries):
SET_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT1_Msk);
SET_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT_SEL_Msk);
CLEAR_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT0_Msk);
HAL_NVIC_SystemReset();
After reset, my board resets GPIO outputs and seems to reset, but I'm not able to connect to it and program it through the UART bootloader. I am attempting to use the stm32flash tool since I am using Mac and can't run the official STM32Flasher utility.
Is this way of setting the bits correct, is the reset the correct way to enter the boot mode, or is there something else I am missing? Several sources mentioned the boot_lock bits, but from my research those bits only apply to the G0x1 MCUs...
Thanks
2020-11-16 05:20 AM
Option bytes can't be modified like RAM memory. You need to unlock the flash prior to it. Per the RM:
Example of setting option bytes here (different family, same idea):
2020-11-16 09:32 AM
Thanks for pointing this out! I definitely just needed to read a few more lines and I would have seen that. I've got this implemented now using the following code:
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
SET_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT1);
SET_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT_SEL);
CLEAR_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT0);
while (READ_BIT(FLASH->SR, FLASH_SR_BSY1))
{
// wait for flash operation to finish
}
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
while (READ_BIT(FLASH->SR, FLASH_SR_BSY1))
{
// wait for flash operation to finish
}
SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
HAL_NVIC_SystemReset();
break;
Using the open source stlink utility I can see that the option bytes changed from before and after I ran this code, giving me what I think is the right output:
(Before)
➜ st-flash --area=option read
st-flash 1.6.1
2020-11-16T12:22:41 INFO common.c: G030/G031/G041: 8 KiB SRAM, 32 KiB flash in at least 2 KiB pages.
dfffe1aa
(After)
➜ st-flash --area=option read
st-flash 1.6.1
2020-11-16T12:24:12 INFO common.c: G030/G031/G041: 8 KiB SRAM, 32 KiB flash in at least 2 KiB pages.
dbffe1aa
The only thing is that I now I can't seem to actually connect to the bootloader? Again, I'm using the stm32flash tool from sourceforge, and my computer is connected through USB and an FTDI230XS USB to UART bridge chip (I don' think this is the problem, I am able to read and write to the UART normally when it isn't in bootloader mode). I've tried several baud rates, but no luck. I might have to try and find a windows computer to run the stm32flashloader utility...
Any suggestions? It does seem to be in bootloader mode, because it doesn't load my application even after reset, and to get it back to normal I have to reset the flash option bytes with
st-flash --reset --area=option write 0xDFFFE1AA
Thanks!
2022-06-24 02:30 AM
Hi GWork
to use system bootloader,try this code. This code can make mcu in system bootmode, and STM32CubeProgrammer can connect it. but porgram not work?
static void JumpToBootloader( void )
{
uint32_t i = 0;
void ( *SysMemBootJump )( void ); /*declare a function pointer 声明一个函数指针 */
__IO uint32_t BootAddr = 0x1FFF0000; /* system BootLoader address*/
/*Turn off global interrupts 关闭全局中断 */
__disable_irq();
/* Turn off the tick timer, reset to default 关闭滴答定时器,�?�?到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* Set all clocks to default state, use HSI clock 设置所有时钟到默认状�?,使用HSI时钟 */
HAL_RCC_DeInit();
/* Disable all interrupts, clear all interrupt pending flags 关闭所有中断,清除所有中断挂起标志 */
for ( i = 0; i < 1; i++ )
{
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
/* Enable global interrupt 使能全局中断 */
__enable_irq();
/* Jump to the system BootLoader 跳转到系统BootLoader,首地�?�是MSP,地�?�+4是�?�?中断�?务程�?地�?� */
SysMemBootJump = ( void ( * )( void ) ) ( *( ( uint32_t * ) ( BootAddr + 4 ) ) );
/* set the main stack pointer 设置主堆栈指针 */
__set_MSP( *( uint32_t * )BootAddr );
/* Jump to the system BootLoader 跳转到系统BootLoader */
SysMemBootJump();
/* */
while ( 1 )
{
}
}