2024-05-27 04:13 PM
Hello,
I read through the fairly thorough How To Jump To System Bootloader From Application Code on STM32 regarding entering the bootloader from firmware but I am having an issue getting USART1 to work after the software jump.
Code is below. I am able to successfully:
However, I can NOT do a software jump to the bootloader and then have it work through USART1. Note that I disconnected USB for this test because that can prevent the bootloader from using USART1.
Code:
void bootloaderJump (void)
{
uint32_t i=0;
void (*SysMemBootJump)(void);
/* Set a vector addressed with STM32 Microcontrollers names */
/* Each vector position contains an address to the boot loader entry point */
volatile uint32_t BootAddr[33];
BootAddr[C0] = 0x1FFF0000;
BootAddr[F030x8] = 0x1FFFEC00;
BootAddr[F030xC] = 0x1FFFD800;
BootAddr[F03xx] = 0x1FFFEC00;
BootAddr[F05] = 0x1FFFEC00;
BootAddr[F07] = 0x1FFFC800;
BootAddr[F09] = 0x1FFFD800;
BootAddr[F10xx] = 0x1FFFF000;
BootAddr[F105] = 0x1FFFB000;
BootAddr[F107] = 0x1FFFB000;
BootAddr[F10XL] = 0x1FFFE000;
BootAddr[F2] = 0x1FFF0000;
BootAddr[F3] = 0x1FFFD800;
BootAddr[F4] = 0x1FFF0000;
BootAddr[F7] = 0x1FF00000;
BootAddr[G0] = 0x1FFF0000;
BootAddr[G4] = 0x1FFF0000;
BootAddr[H503] = 0x0BF87000;
BootAddr[H563] = 0x0BF97000;
BootAddr[H573] = 0x0BF97000;
BootAddr[H7x] = 0x1FF09800;
BootAddr[H7A] = 0x1FF0A800;
BootAddr[H7B] = 0x1FF0A000;
BootAddr[L0] = 0x1FF00000;
BootAddr[L1] = 0x1FF00000;
BootAddr[L4] = 0x1FFF0000;
BootAddr[L5] = 0x0BF90000;
BootAddr[WBA] = 0x0BF88000;
BootAddr[WBX] = 0x1FFF0000;
BootAddr[WL] = 0x1FFF0000;
BootAddr[U5] = 0x0BF90000;
/* Disable all interrupts */
__disable_irq();
/* Disable Systick timer */
SysTick->CTRL = 0;
/* DEREK: DISABLE UART etc - THIS IS NEW */
disablePeripherals();
/* Set the clock to the default state */
HAL_RCC_DeInit();
//
// NOTE: others have found that you should disable SYSTICK here instead of above.
//
/* Clear Interrupt Enable Register & Interrupt Pending Register */
//for (i=0;i<5;i++)
//for (uint8_t i = 0; i < (MCU_IRQS + 31u) / 32; i++)
for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
/* Re-enable all interrupts */
__enable_irq();
/* Set up the jump to boot loader address + 4 */
SysMemBootJump = (void (*)(void)) (*((uint32_t *) ((BootAddr[MCU] + 4))));
/* Set the main stack pointer to the boot loader stack */
__set_MSP(*(uint32_t *)BootAddr[MCU]);
/* Call the function to jump to boot loader location */
SysMemBootJump();
/* Jump is done successfully */
while (1)
{
/* Code should never reach this loop */
}
}
Additionally, the code to disable the peripherals:
void disablePeripherals(void)
{
HAL_DMA_DeInit(&hdma_adc1);
HAL_DMA_DeInit(&hdma_adc3);
HAL_DMA_DeInit(&hdma_i2c2_tx);
HAL_DMA_DeInit(&hdma_i2c2_rx);
HAL_TIM_PWM_DeInit(&htim8);
HAL_TIM_PWM_DeInit(&htim1);
HAL_SPI_DeInit(&hspi3);
HAL_I2C_DeInit(&hi2c2);
HAL_SPI_DeInit(&hspi2);
// NOTE there is no deinit for HAL_IWDG_Init(&hiwdg);
// IWDG can only be de-initialized by reset
HAL_TIM_PWM_DeInit(&htim4);
HAL_ADC_DeInit(&hadc1);
HAL_TIM_PWM_DeInit(&htim3);
HAL_UART_DeInit(&huart3);
HAL_UART_DeInit(&huart1);
HAL_ADC_DeInit(&hadc2);
HAL_ADC_DeInit(&hadc3);
}
Thank you