cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with UART Interrupts (ICSR->ISRPENDING always 1) after jumping to booloader from main application

VPapa
Associate

I have built an main application (using HAL) and a bootloader project (using LL).

When debugging seperately, the UART reception using interrupts works well in both projects.

But after I jump to bootloader from main application, immediately after re-initialization of UART the ICSR ISRPENDING Flag is always set to 1, and the code does not jump to USART3_IRQHandler. At the same time though, the Systick Timer keeps working normally ( Proof that ISR Vector offset is correctly set).

Any ideas what forces ISRPENDING to 1, and how to clear it?

The first run of bootloader sets NVIC_ISPR1 and ICPR1 to 0x80.

But after jumping from main application, immediately after  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); the UART1 interrupt is enabled on NVIC, even if it has been disabled by the main app.

Check screenshot below.

The code from jumping from main application is the following.

You will notice that I have disabled all interrupts ( all nvic registers are 0 before jumping).

Then why USART1 interrupt is activated when UART clock is set active.

Is there any workaround for this?

void JumpToBootloader(void)

{

  void (*SysBootJump)(void);

  volatile uint32_t addr = 0x08000000;

  NVIC_DisableIRQ(DMA1_Channel2_IRQn);

  NVIC_DisableIRQ(DMA1_Channel3_IRQn);

  NVIC_DisableIRQ(DMA1_Channel4_IRQn);

  NVIC_DisableIRQ(DMA1_Channel5_IRQn);

  HAL_SPI_MspDeInit(&hspi2);

  HAL_SPI_MspDeInit(&hspi1);

  HAL_UART_MspDeInit(&huart1);

  HAL_UART_MspDeInit(&huart2);

  HAL_UART_MspDeInit(&huart3);

  NVIC_DisableIRQ(PVD_PVM_IRQn);

  NVIC_ClearPendingIRQ(PVD_PVM_IRQn);

  __disable_irq();

  SysBootJump = (void (*)(void)) (*((uint32_t*) (addr + 4)));

  __set_MSP(*(uint32_t*) addr);

  SysBootJump();

}

Thank you in advance,

Vasilis Papakos

2 REPLIES 2
VPapa
Associate

Sollution found after a while...

Turns out HAL_UART_MspDeInit(&huart1); only turns off the clock to register, but does not reset register.. Main app enabled various uart interrupts (idle, parity error etc.). So when the bootloader activated the clock, these IE bits were active (probably idle detection causes the ISRPENDING  flag to 1).

The solution was simple, call LL_USART_DeInit for each usart, before activating, the clock to USART.

TDK
Guru

You can also use the reset bits for the peripheral to return it to its default state. It is somewhat more straightforward IMO.

__HAL_RCC_USART1_FORCE_RESET();
__HAL_RCC_USART1_RELEASE_RESET();

If you feel a post has answered your question, please click "Accept as Solution".