2014-08-11 03:00 AM
Hi,
I'm having a peculiar issue when jumping from my application code back to my bootloader. Before jumping back to the bootloader I disable all peripheral as shown in the code below. But when the HAL_NVIC_DisableIRQ(SysTick_IRQn); line executes the PGPERR & PGSERR ( ie SR = 0x000000C0 ) bits are set in the Flash SR register. They are not clearing when the bootloader executes and subsequent flash writes fail in the bootloader. Anyone got any explaination why this would occur? There are no flash writes taking place in the application code and the NVIC_DisableIRQ only writes to the NVIC->ICER register.__disable_irq();
FATFS_UnLinkDriver(SD_Path);
HAL_ADC_MspDeInit(&hadc3);
HAL_CAN_DeInit(&hcan1);
HAL_I2C_MspDeInit(&hi2c2);
HAL_SD_MspDeInit(&hsd);
HAL_SPI_MspDeInit(&hspi1);
HAL_SPI_MspDeInit(&hspi2);
HAL_UART_MspDeInit(&huart2);
HAL_UART_MspDeInit(&huart3);
HAL_UART_MspDeInit(&huart6);
HAL_NVIC_DisableIRQ(SysTick_IRQn);
pEntryFromProgFnc = (void(*)(void))(APPLICATION_RESET_VECTOR + 1);
pEntryFromProgFnc();
2014-08-11 04:16 AM
HAL_FLASH_Unlock();
FLASH->CR |= (FLASH_PSIZE_WORD | FLASH_CR_PG);
HAL_NVIC_DisableIRQ(SysTick_IRQn);
HAL_FLASH_Lock();
The FLASH_PSIZE_WORD bit prevents the PGPERR error flag from being set and the FLASH_CR_PG bit prevents the PGSERR error flag from being set. All is working ok now but I'm not sure why a write to the NVIC is being treated as a FLASH write though. Maybe someone could shed some light and offer a better solution to this workaround.
2018-05-09 01:22 AM
Hi,
I have the same problem w/ STM32F429NIH6: whenever HAL_NVIC_EnableIRQ(SysTick_IRQn) is executed,
the PGPERR & PGSERR (SR = 0x000000C0 bits are set in the flash status register.
The consequence is that the first flash write operation (HAL_FLASH_Program) fails because of the function FLASH_WaitForLastOperation returning error.As workaround I'm explicitly clearing these bits prior to execute HAL_FLASH_Program, but I'd like to understand why these bits are set. Is this a HW bug of the MCU? Is there any explanation to this? I've chekched the errata pdf for my MCU (en.DM00068628.pdf) but there is nothing about it.Best regards,Alessandro Morniroli2018-05-09 03:42 AM
Hi,
I've just found the problem.
NVIC_EnableIRQ (and NVIC_DisableIRQ) cannot be used with negative numbers.
/**
\brief Enable External Interrupt \details Enables a device-specific interrupt in the NVIC interrupt controller. \param [in] IRQn External interrupt number. Value cannot be negative. */__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn){ NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));}/** \brief Disable External Interrupt \details Disables a device-specific interrupt in the NVIC interrupt controller. \param [in] IRQn External interrupt number. Value cannot be negative. */__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn){ NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));}SysTick_IRQn is '-1', so this is causing flash error. HW is (almost) always right : )
Best regards,Alessandro Morniroli2018-05-09 03:50 AM
System Handlers have stuff in the SCB as I recall.
2018-05-09 04:20 PM
It appears these are the functions need for Enabling and Disabling of SysTick Interrupt in HAL implementation.
from stm32f4xx_hal.c
__weak void HAL_SuspendTick(void)
{
/* Disable SysTick Interrupt */
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}
__weak void HAL_ResumeTick(void)
{
/* Enable SysTick Interrupt */
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
}