cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 PGPERR PGSERR

joe
Associate III
Posted on August 11, 2014 at 12:00

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();

5 REPLIES 5
joe
Associate III
Posted on August 11, 2014 at 13:16 Update: I've just been playing around with Flash register to try to get a workaround. Writing the DisableIRQ like this prevent the error flags from being set:

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.
alessandro morniroli
Associate III
Posted on May 09, 2018 at 10:22

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 Morniroli
Posted on May 09, 2018 at 10:42

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 Morniroli
Posted on May 09, 2018 at 10:50

System Handlers have stuff in the SCB as I recall.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 09, 2018 at 23:20

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;

}